From: "Amanieu d'Antras" <amanieu@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: Oleg Nesterov <oleg@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
x86@kernel.org, Brian Gerst <brgerst@gmail.com>,
"Amanieu d'Antras" <amanieu@gmail.com>
Subject: [PATCH 19/20] signalfd: Fix handling of ssi_ptr and ssi_int in signalfd_copyinfo
Date: Wed, 14 Oct 2015 21:59:29 +0100 [thread overview]
Message-ID: <1444856371-26319-20-git-send-email-amanieu@gmail.com> (raw)
In-Reply-To: <1444856371-26319-1-git-send-email-amanieu@gmail.com>
There are several issues here:
1) The value of ssi_ptr was incorrect for 32-bit processes. It was
previously copied directly from si_ptr, which contains garbage
on 32-bit processes, especially on big-endian architectures.
2) A SIGSYS would cause various fields to be filled with incorrect
values. SIGSYS fields are not in signalfd_siginfo, and it should
avoid filling in unrelated fields.
3) ssi_ptr and ssi_int should not be filled in for any unrecognized
si_code, but only for those generated by sigqueue. The si_ptr
and si_int fields in siginfo_t may not be initialized otherwise.
Signed-off-by: Amanieu d'Antras <amanieu@gmail.com>
---
fs/signalfd.c | 42 +++++++++++++++++++++++++++++++-----------
1 file changed, 31 insertions(+), 11 deletions(-)
diff --git a/fs/signalfd.c b/fs/signalfd.c
index 270221f..4d59de9 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -80,22 +80,43 @@ static unsigned int signalfd_poll(struct file *file, poll_table *wait)
static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
siginfo_t const *kinfo)
{
- long err;
+ long err, ssi_ptr;
BUILD_BUG_ON(sizeof(struct signalfd_siginfo) != 128);
/*
+ * ssi_ptr for a compat task should be sourced from si_int instead
+ * of si_ptr since that is what copy_siginfo_from_user32 and
+ * get_compat_sigevent use. 32-bit pointer values are sign-extended
+ * to 64 bits when written to ssi_ptr, which matches the behavior of
+ * 32-bit kernels.
+ */
+ ssi_ptr = is_compat_task() ? kinfo->si_int : (long) kinfo->si_ptr;
+
+ /*
* Unused members should be zero ...
*/
err = __clear_user(uinfo, sizeof(*uinfo));
/*
- * If you change siginfo_t structure, please be sure
- * this code is fixed accordingly.
+ * If you change siginfo_t structure, please be sure that
+ * all these functions are fixed accordingly:
+ * copy_siginfo_to_user
+ * copy_siginfo_to_user32
+ * copy_siginfo_from_user32
+ * signalfd_copyinfo
+ * They should never copy any pad contained in the structure
+ * to avoid security leaks, but must copy the generic
+ * 3 ints plus the relevant union member.
*/
err |= __put_user(kinfo->si_signo, &uinfo->ssi_signo);
err |= __put_user(kinfo->si_errno, &uinfo->ssi_errno);
err |= __put_user((short) kinfo->si_code, &uinfo->ssi_code);
+ if (kinfo->si_code < 0) {
+ /* Write ssi_int and ssi_ptr for sigqueue()-generated signals */
+ err |= __put_user(ssi_ptr, &uinfo->ssi_ptr);
+ err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
+ }
switch (kinfo->si_code & __SI_MASK) {
case __SI_KILL:
err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
@@ -104,7 +125,7 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
case __SI_TIMER:
err |= __put_user(kinfo->si_tid, &uinfo->ssi_tid);
err |= __put_user(kinfo->si_overrun, &uinfo->ssi_overrun);
- err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
+ err |= __put_user(ssi_ptr, &uinfo->ssi_ptr);
err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
break;
case __SI_POLL:
@@ -139,21 +160,20 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
case __SI_MESGQ: /* But this is */
err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
- err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
+ err |= __put_user(ssi_ptr, &uinfo->ssi_ptr);
err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
break;
+#ifdef __ARCH_SIGSYS
+ case __SI_SYS: /* SIGSYS fields are not in signalfd_siginfo */
+ break;
+#endif
default:
- /*
- * This case catches also the signals queued by sigqueue().
- */
err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
- err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
- err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
break;
}
- return err ? -EFAULT: sizeof(*uinfo);
+ return err ? -EFAULT : sizeof(*uinfo);
}
static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, siginfo_t *info,
--
2.6.1
next prev parent reply other threads:[~2015-10-14 21:02 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-14 20:59 [PATCH 00/20] Fix handling of compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 01/20] compat: Add generic compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 02/20] compat: Add generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 03/20] x86: Update compat_siginfo_t to be closer to the generic version Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 04/20] x86: Rewrite copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 22:47 ` kbuild test robot
2015-10-15 18:41 ` Oleg Nesterov
2015-10-15 18:58 ` Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 05/20] mips: Clean up compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 06/20] mips: Use generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 07/20] arm64: Use generic compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 08/20] arm64: Use generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 09/20] parisc: Use generic compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 10/20] parsic: Use generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 11/20] s390: Use generic compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 12/20] s390: Use generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 13/20] powerpc: Use generic compat_siginfo_t Amanieu d'Antras
2015-10-16 23:00 ` kbuild test robot
2015-10-14 20:59 ` [PATCH 14/20] powerpc: Use generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 15/20] tile: Use generic compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 16/20] tile: Use generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 17/20] sparc: Use generic compat_siginfo_t Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 18/20] sparc: Use generic copy_siginfo_{to,from}_user32 Amanieu d'Antras
2015-10-14 20:59 ` Amanieu d'Antras [this message]
2015-10-14 21:23 ` [PATCH 19/20] signalfd: Fix handling of ssi_ptr and ssi_int in signalfd_copyinfo Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 19/20] signalfd: Fix some issues " Amanieu d'Antras
2015-10-14 20:59 ` [PATCH 20/20] signal: Remove unnecessary zero-initialization of siginfo_t Amanieu d'Antras
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1444856371-26319-20-git-send-email-amanieu@gmail.com \
--to=amanieu@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=brgerst@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.