mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Harald Welte <laforge@gnumonks.org>
To: Linus Torvalds <torvalds@osdl.org>
Cc: Chris Wright <chrisw@osdl.org>, Sergey Vlasov <vsu@altlinux.ru>,
	linux-usb-devel@lists.sourceforge.net,
	linux-kernel@vger.kernel.org, security@linux.kernel.org,
	vendor-sec@lst.de
Subject: Re: [linux-usb-devel] Re: [Security] [vendor-sec] [BUG/PATCH/RFC] Oops while completing async USB via usbdevio
Date: Sat, 1 Oct 2005 00:08:09 +0200	[thread overview]
Message-ID: <20050930220808.GE4168@sunbeam.de.gnumonks.org> (raw)
In-Reply-To: <Pine.LNX.4.64.0509301225190.3378@g5.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 6317 bytes --]

On Fri, Sep 30, 2005 at 12:27:04PM -0700, Linus Torvalds wrote:
> 
> 
> On Fri, 30 Sep 2005, Chris Wright wrote:
> > 
> > Sorry, I missed the thread up to this, but this looks fundamentally
> > broken.  The kill_proc_info_as_uid() idea is not sufficient because more
> > than uid/euid are needed for permission check.  There's capabilities and
> > security labels.
> 
> Not for this particular USB use, there isn't. Since you can only send a 
> signal to yourself anyway, the uid/euid check is just testing that you're 
> still who you were.

please find the patch below.  It compiles, but I didn't yet have the
time to verify it makes the bug disappear and the async urb delivery is
still working.

I'll try to report whether it's working tomorrow.

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -30,6 +30,8 @@
  *  Revision history
  *    22.12.1999   0.1   Initial release (split from proc_usb.c)
  *    04.01.2000   0.2   Turned into its own filesystem
+ *    30.09.2005   0.3   Fix user-triggerable oops in async URB delivery
+ *    			 (CAN-2005-3055)
  */
 
 /*****************************************************************************/
@@ -58,7 +60,8 @@ static struct class *usb_device_class;
 struct async {
 	struct list_head asynclist;
 	struct dev_state *ps;
-	struct task_struct *task;
+	pid_t pid;
+	pid_t uid, euid;
 	unsigned int signr;
 	unsigned int ifnum;
 	void __user *userbuffer;
@@ -290,7 +293,8 @@ static void async_completed(struct urb *
 		sinfo.si_errno = as->urb->status;
 		sinfo.si_code = SI_ASYNCIO;
 		sinfo.si_addr = as->userurb;
-		send_sig_info(as->signr, &sinfo, as->task);
+		kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, 
+				      as->euid);
 	}
         wake_up(&ps->wait);
 }
@@ -988,7 +992,9 @@ static int proc_do_submiturb(struct dev_
 		as->userbuffer = NULL;
 	as->signr = uurb->signr;
 	as->ifnum = ifnum;
-	as->task = current;
+	as->pid = current->pid;
+	as->uid = current->uid;
+	as->euid = current->euid;
 	if (!(uurb->endpoint & USB_DIR_IN)) {
 		if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) {
 			free_async(as);
diff --git a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1018,6 +1018,7 @@ extern int force_sig_info(int, struct si
 extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
 extern int kill_pg_info(int, struct siginfo *, pid_t);
 extern int kill_proc_info(int, struct siginfo *, pid_t);
+extern int kill_proc_info_as_uid(int, struct siginfo *, pid_t, pid_t, pid_t);
 extern void do_notify_parent(struct task_struct *, int);
 extern void force_sig(int, struct task_struct *);
 extern void force_sig_specific(int, struct task_struct *);
diff --git a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -655,7 +655,8 @@ static int rm_from_queue(unsigned long m
  * Bad permissions for sending the signal
  */
 static int check_kill_permission(int sig, struct siginfo *info,
-				 struct task_struct *t)
+				 struct task_struct *t,
+				 pid_t uid, pid_t euid)
 {
 	int error = -EINVAL;
 	if (!valid_signal(sig))
@@ -665,8 +666,8 @@ static int check_kill_permission(int sig
 			(unsigned long)info != 2 && SI_FROMUSER(info)))
 	    && ((sig != SIGCONT) ||
 		(current->signal->session != t->signal->session))
-	    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
-	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
+	    && (euid ^ t->suid) && (euid ^ t->uid)
+	    && (uid ^ t->suid) && (uid ^ t->uid)
 	    && !capable(CAP_KILL))
 		return error;
 
@@ -1132,7 +1133,24 @@ int group_send_sig_info(int sig, struct 
 	unsigned long flags;
 	int ret;
 
-	ret = check_kill_permission(sig, info, p);
+	ret = check_kill_permission(sig, info, p, current->uid, current->euid);
+	if (!ret && sig && p->sighand) {
+		spin_lock_irqsave(&p->sighand->siglock, flags);
+		ret = __group_send_sig_info(sig, info, p);
+		spin_unlock_irqrestore(&p->sighand->siglock, flags);
+	}
+
+	return ret;
+}
+
+static int group_send_sig_info_as_uid(int sig, struct siginfo *info, 
+				      struct task_struct *p, 
+				      pid_t uid, pid_t euid)
+{
+	unsigned long flags;
+	int ret;
+
+	ret = check_kill_permission(sig, info, p, current->uid, current->euid);
 	if (!ret && sig && p->sighand) {
 		spin_lock_irqsave(&p->sighand->siglock, flags);
 		ret = __group_send_sig_info(sig, info, p);
@@ -1192,6 +1210,22 @@ kill_proc_info(int sig, struct siginfo *
 	return error;
 }
 
+/* like kill_proc_info(), but doesn't use uid/euid of "current" */
+int
+kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
+		      pid_t uid, pid_t euid)
+{
+	int error;
+	struct task_struct *p;
+
+	read_lock(&tasklist_lock);
+	p = find_task_by_pid(pid);
+	error = -ESRCH;
+	if (p)
+		error = group_send_sig_info_as_uid(sig, info, p, uid, euid);
+	read_unlock(&tasklist_lock);
+	return error;
+}
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -2290,7 +2324,8 @@ asmlinkage long sys_tgkill(int tgid, int
 	p = find_task_by_pid(pid);
 	error = -ESRCH;
 	if (p && (p->tgid == tgid)) {
-		error = check_kill_permission(sig, &info, p);
+		error = check_kill_permission(sig, &info, p, current->uid,
+					      current->euid);
 		/*
 		 * The null signal is a permissions and process existence
 		 * probe.  No signal is actually delivered.
@@ -2330,7 +2365,8 @@ sys_tkill(int pid, int sig)
 	p = find_task_by_pid(pid);
 	error = -ESRCH;
 	if (p) {
-		error = check_kill_permission(sig, &info, p);
+		error = check_kill_permission(sig, &info, p, current->uid,
+					      current->euid);
 		/*
 		 * The null signal is a permissions and process existence
 		 * probe.  No signal is actually delivered.
-- 
- Harald Welte <laforge@gnumonks.org>          	        http://gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

  parent reply	other threads:[~2005-09-30 22:08 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-25 15:13 Harald Welte
2005-09-27  8:04 ` [vendor-sec] " Greg KH
2005-09-27  9:13   ` Greg KH
     [not found]     ` <20050927110319.GD1980@piware.de>
2005-09-27 12:22       ` [vendor-sec] " Greg KH
2005-09-27 12:48   ` [vendor-sec] " Christoph Hellwig
2005-09-27 12:57     ` Greg KH
2005-09-27 12:59       ` Christoph Hellwig
2005-09-27 13:09         ` Greg KH
2005-09-27 15:27           ` David Brownell
2005-09-27 14:53 ` [Security] " Linus Torvalds
2005-09-27 16:00   ` [linux-usb-devel] " Sergey Vlasov
2005-09-27 16:09     ` Linus Torvalds
2005-09-27 16:52       ` Sergey Vlasov
2005-09-27 17:02         ` Linus Torvalds
2005-09-30 10:47           ` Harald Welte
2005-09-30 14:56             ` Linus Torvalds
2005-09-30 18:44               ` Chris Wright
2005-09-30 19:27                 ` Linus Torvalds
2005-09-30 20:38                   ` Chris Wright
2005-09-30 22:08                   ` Harald Welte [this message]
2005-09-30 22:16                     ` Linus Torvalds
2005-10-10 17:44                       ` Harald Welte
2005-10-10 18:07                         ` Chris Wright
2005-10-11  9:45                           ` Harald Welte
2005-10-11 23:10                             ` [vendor-sec] " Greg KH
2005-10-11 23:44                               ` Linus Torvalds
2005-10-12  7:24                                 ` Harald Welte
2005-10-13  5:51                             ` Horms
2005-10-11 13:57                           ` Bernd Petrovitsch
2005-10-10 18:19                         ` Linus Torvalds
2005-10-10 22:47                           ` Chris Wright
2005-10-10 20:03                         ` [linux-usb-devel] " Alan Stern
2005-10-11  8:28                           ` Harald Welte
2005-10-11 17:37                           ` Paul Jackson
2005-10-11 17:58                             ` linux-os (Dick Johnson)
2005-10-11 19:13                               ` Alan Stern
2005-10-11 20:02                                 ` [Security] " Alan Cox
2005-09-27 17:20         ` PID reuse safety for userspace apps (Re: [linux-usb-devel] Re: [Security] [vendor-sec] [BUG/PATCH/RFC] Oops while completing async USB via usbdevio) Solar Designer
2005-09-27 20:34           ` Alan Cox
2005-09-27 20:42             ` Linus Torvalds
2005-09-27 21:16               ` Solar Designer
2005-09-27 21:03             ` Solar Designer
2005-09-27 16:58       ` [linux-usb-devel] Re: [Security] [vendor-sec] [BUG/PATCH/RFC] Oops while completing async USB via usbdevio Alan Cox
2005-09-27 16:59         ` Linus Torvalds
2005-09-27 20:35           ` Alan Cox
2005-10-13 23:00         ` Pete Zaitcev
2005-10-13 23:16           ` Linus Torvalds
2005-10-13 23:56             ` Pete Zaitcev

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=20050930220808.GE4168@sunbeam.de.gnumonks.org \
    --to=laforge@gnumonks.org \
    --cc=chrisw@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb-devel@lists.sourceforge.net \
    --cc=security@linux.kernel.org \
    --cc=torvalds@osdl.org \
    --cc=vendor-sec@lst.de \
    --cc=vsu@altlinux.ru \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®