diff options
| -rw-r--r-- | fs/signalfd.c | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/fs/signalfd.c b/fs/signalfd.c index d2187a813376..46e9de097507 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
| @@ -256,10 +256,8 @@ static const struct file_operations signalfd_fops = { | |||
| 256 | .llseek = noop_llseek, | 256 | .llseek = noop_llseek, |
| 257 | }; | 257 | }; |
| 258 | 258 | ||
| 259 | static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, | 259 | static int do_signalfd4(int ufd, sigset_t *mask, int flags) |
| 260 | int flags) | ||
| 261 | { | 260 | { |
| 262 | sigset_t sigmask; | ||
| 263 | struct signalfd_ctx *ctx; | 261 | struct signalfd_ctx *ctx; |
| 264 | 262 | ||
| 265 | /* Check the SFD_* constants for consistency. */ | 263 | /* Check the SFD_* constants for consistency. */ |
| @@ -269,18 +267,15 @@ static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, | |||
| 269 | if (flags & ~(SFD_CLOEXEC | SFD_NONBLOCK)) | 267 | if (flags & ~(SFD_CLOEXEC | SFD_NONBLOCK)) |
| 270 | return -EINVAL; | 268 | return -EINVAL; |
| 271 | 269 | ||
| 272 | if (sizemask != sizeof(sigset_t) || | 270 | sigdelsetmask(mask, sigmask(SIGKILL) | sigmask(SIGSTOP)); |
| 273 | copy_from_user(&sigmask, user_mask, sizeof(sigmask))) | 271 | signotset(mask); |
| 274 | return -EINVAL; | ||
| 275 | sigdelsetmask(&sigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); | ||
| 276 | signotset(&sigmask); | ||
| 277 | 272 | ||
| 278 | if (ufd == -1) { | 273 | if (ufd == -1) { |
| 279 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | 274 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
| 280 | if (!ctx) | 275 | if (!ctx) |
| 281 | return -ENOMEM; | 276 | return -ENOMEM; |
| 282 | 277 | ||
| 283 | ctx->sigmask = sigmask; | 278 | ctx->sigmask = *mask; |
| 284 | 279 | ||
| 285 | /* | 280 | /* |
| 286 | * When we call this, the initialization must be complete, since | 281 | * When we call this, the initialization must be complete, since |
| @@ -300,7 +295,7 @@ static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, | |||
| 300 | return -EINVAL; | 295 | return -EINVAL; |
| 301 | } | 296 | } |
| 302 | spin_lock_irq(¤t->sighand->siglock); | 297 | spin_lock_irq(¤t->sighand->siglock); |
| 303 | ctx->sigmask = sigmask; | 298 | ctx->sigmask = *mask; |
| 304 | spin_unlock_irq(¤t->sighand->siglock); | 299 | spin_unlock_irq(¤t->sighand->siglock); |
| 305 | 300 | ||
| 306 | wake_up(¤t->sighand->signalfd_wqh); | 301 | wake_up(¤t->sighand->signalfd_wqh); |
| @@ -313,46 +308,51 @@ static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, | |||
| 313 | SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, | 308 | SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, |
| 314 | size_t, sizemask, int, flags) | 309 | size_t, sizemask, int, flags) |
| 315 | { | 310 | { |
| 316 | return do_signalfd4(ufd, user_mask, sizemask, flags); | 311 | sigset_t mask; |
| 312 | |||
| 313 | if (sizemask != sizeof(sigset_t) || | ||
| 314 | copy_from_user(&mask, user_mask, sizeof(mask))) | ||
| 315 | return -EINVAL; | ||
| 316 | return do_signalfd4(ufd, &mask, flags); | ||
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask, | 319 | SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask, |
| 320 | size_t, sizemask) | 320 | size_t, sizemask) |
| 321 | { | 321 | { |
| 322 | return do_signalfd4(ufd, user_mask, sizemask, 0); | 322 | sigset_t mask; |
| 323 | |||
| 324 | if (sizemask != sizeof(sigset_t) || | ||
| 325 | copy_from_user(&mask, user_mask, sizeof(mask))) | ||
| 326 | return -EINVAL; | ||
| 327 | return do_signalfd4(ufd, &mask, 0); | ||
| 323 | } | 328 | } |
| 324 | 329 | ||
| 325 | #ifdef CONFIG_COMPAT | 330 | #ifdef CONFIG_COMPAT |
| 326 | static long do_compat_signalfd4(int ufd, | 331 | static long do_compat_signalfd4(int ufd, |
| 327 | const compat_sigset_t __user *sigmask, | 332 | const compat_sigset_t __user *user_mask, |
| 328 | compat_size_t sigsetsize, int flags) | 333 | compat_size_t sigsetsize, int flags) |
| 329 | { | 334 | { |
| 330 | sigset_t tmp; | 335 | sigset_t mask; |
| 331 | sigset_t __user *ksigmask; | ||
| 332 | 336 | ||
| 333 | if (sigsetsize != sizeof(compat_sigset_t)) | 337 | if (sigsetsize != sizeof(compat_sigset_t)) |
| 334 | return -EINVAL; | 338 | return -EINVAL; |
| 335 | if (get_compat_sigset(&tmp, sigmask)) | 339 | if (get_compat_sigset(&mask, user_mask)) |
| 336 | return -EFAULT; | ||
| 337 | ksigmask = compat_alloc_user_space(sizeof(sigset_t)); | ||
| 338 | if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t))) | ||
| 339 | return -EFAULT; | 340 | return -EFAULT; |
| 340 | 341 | return do_signalfd4(ufd, &mask, flags); | |
| 341 | return do_signalfd4(ufd, ksigmask, sizeof(sigset_t), flags); | ||
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd, | 344 | COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd, |
| 345 | const compat_sigset_t __user *, sigmask, | 345 | const compat_sigset_t __user *, user_mask, |
| 346 | compat_size_t, sigsetsize, | 346 | compat_size_t, sigsetsize, |
| 347 | int, flags) | 347 | int, flags) |
| 348 | { | 348 | { |
| 349 | return do_compat_signalfd4(ufd, sigmask, sigsetsize, flags); | 349 | return do_compat_signalfd4(ufd, user_mask, sigsetsize, flags); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd, | 352 | COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd, |
| 353 | const compat_sigset_t __user *,sigmask, | 353 | const compat_sigset_t __user *, user_mask, |
| 354 | compat_size_t, sigsetsize) | 354 | compat_size_t, sigsetsize) |
| 355 | { | 355 | { |
| 356 | return do_compat_signalfd4(ufd, sigmask, sigsetsize, 0); | 356 | return do_compat_signalfd4(ufd, user_mask, sigsetsize, 0); |
| 357 | } | 357 | } |
| 358 | #endif | 358 | #endif |
