Skip to content

Commit 5ed0127

Browse files
author
Al Viro
committed
signalfd: lift sigmask copyin and size checks to callers of do_signalfd4()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 87a3002 commit 5ed0127

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

fs/signalfd.c

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,8 @@ static const struct file_operations signalfd_fops = {
256256
.llseek = noop_llseek,
257257
};
258258

259-
static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask,
260-
int flags)
259+
static int do_signalfd4(int ufd, sigset_t *mask, int flags)
261260
{
262-
sigset_t sigmask;
263261
struct signalfd_ctx *ctx;
264262

265263
/* Check the SFD_* constants for consistency. */
@@ -269,18 +267,15 @@ static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask,
269267
if (flags & ~(SFD_CLOEXEC | SFD_NONBLOCK))
270268
return -EINVAL;
271269

272-
if (sizemask != sizeof(sigset_t) ||
273-
copy_from_user(&sigmask, user_mask, sizeof(sigmask)))
274-
return -EINVAL;
275-
sigdelsetmask(&sigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
276-
signotset(&sigmask);
270+
sigdelsetmask(mask, sigmask(SIGKILL) | sigmask(SIGSTOP));
271+
signotset(mask);
277272

278273
if (ufd == -1) {
279274
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
280275
if (!ctx)
281276
return -ENOMEM;
282277

283-
ctx->sigmask = sigmask;
278+
ctx->sigmask = *mask;
284279

285280
/*
286281
* 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,
300295
return -EINVAL;
301296
}
302297
spin_lock_irq(&current->sighand->siglock);
303-
ctx->sigmask = sigmask;
298+
ctx->sigmask = *mask;
304299
spin_unlock_irq(&current->sighand->siglock);
305300

306301
wake_up(&current->sighand->signalfd_wqh);
@@ -313,46 +308,51 @@ static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask,
313308
SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
314309
size_t, sizemask, int, flags)
315310
{
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);
317317
}
318318

319319
SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask,
320320
size_t, sizemask)
321321
{
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);
323328
}
324329

325330
#ifdef CONFIG_COMPAT
326331
static long do_compat_signalfd4(int ufd,
327-
const compat_sigset_t __user *sigmask,
332+
const compat_sigset_t __user *user_mask,
328333
compat_size_t sigsetsize, int flags)
329334
{
330-
sigset_t tmp;
331-
sigset_t __user *ksigmask;
335+
sigset_t mask;
332336

333337
if (sigsetsize != sizeof(compat_sigset_t))
334338
return -EINVAL;
335-
if (get_compat_sigset(&tmp, sigmask))
336-
return -EFAULT;
337-
ksigmask = compat_alloc_user_space(sizeof(sigset_t));
338-
if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t)))
339+
if (get_compat_sigset(&mask, user_mask))
339340
return -EFAULT;
340-
341-
return do_signalfd4(ufd, ksigmask, sizeof(sigset_t), flags);
341+
return do_signalfd4(ufd, &mask, flags);
342342
}
343343

344344
COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd,
345-
const compat_sigset_t __user *, sigmask,
345+
const compat_sigset_t __user *, user_mask,
346346
compat_size_t, sigsetsize,
347347
int, flags)
348348
{
349-
return do_compat_signalfd4(ufd, sigmask, sigsetsize, flags);
349+
return do_compat_signalfd4(ufd, user_mask, sigsetsize, flags);
350350
}
351351

352352
COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd,
353-
const compat_sigset_t __user *,sigmask,
353+
const compat_sigset_t __user *, user_mask,
354354
compat_size_t, sigsetsize)
355355
{
356-
return do_compat_signalfd4(ufd, sigmask, sigsetsize, 0);
356+
return do_compat_signalfd4(ufd, user_mask, sigsetsize, 0);
357357
}
358358
#endif

0 commit comments

Comments
 (0)