lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 28 May 2019 20:21:53 -0500
From: (Eric W. Biederman)
To:     Andrew Morton <>
        Oleg Nesterov <>,
        syzbot <>,
        Andrei Vagin <>
Subject: [PATCH] signal/ptrace: Don't leak unitialized kernel memory with PTRACE_PEEK_SIGINFO

Recently syzbot in conjunction with KMSAN reported that
ptrace_peek_siginfo can copy an uninitialized siginfo to userspace.
Inspecting ptrace_peek_siginfo confirms this.

The problem is that off when initialized from can be
initialized to a negaive value.  At which point the "if (off >= 0)"
test to see if off became negative fails because off started off

Prevent the core problem by adding a variable found that is only true
if a siginfo is found and copied to a temporary in preparation for
being copied to userspace.

Prevent from being truncated when being assigned to off by
testing that off is <= the maximum possible value of off.  Convert off
to an unsigned long so that we should not have to truncate,
we have well defined overflow behavior so if we add another check we
won't risk fighting undefined compiler behavior, and so that we have a
type whose maximum value is easy to test for.

Cc: Andrei Vagin <>
Fixes: 84c751bd4aeb ("ptrace: add ability to retrieve signals without removing from a queue (v4)")
Signed-off-by: "Eric W. Biederman" <>


Otherwise I will queue this up and send it to Linus.

 kernel/ptrace.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 6f357f4fc859..4c2b24a885d3 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -704,6 +704,10 @@ static int ptrace_peek_siginfo(struct task_struct *child,
 	if ( < 0)
 		return -EINVAL;
+	/* Ensure fits in an unsigned */
+	if ( > ULONG_MAX)
+		return 0;
 		pending = &child->signal->shared_pending;
@@ -711,18 +715,20 @@ static int ptrace_peek_siginfo(struct task_struct *child,
 	for (i = 0; i <; ) {
 		kernel_siginfo_t info;
-		s32 off = + i;
+		unsigned long off = + i;
+		bool found = false;
 		list_for_each_entry(q, &pending->list, list) {
 			if (!off--) {
+				found = true;
 				copy_siginfo(&info, &q->info);
-		if (off >= 0) /* beyond the end of the list */
+		if (!found) /* beyond the end of the list */

Powered by blists - more mailing lists