Re: [linux-usb-devel] Re: [Security] [vendor-sec] [BUG/PATCH/RFC]Oops while completing async USB via usbdevio

From: Linus Torvalds
Date: Fri Sep 30 2005 - 10:05:17 EST




On Fri, 30 Sep 2005, Harald Welte wrote:
>
> I'm probably the person in this thread who understands the least about
> the USB stack and the scheduler, but if there is no implementation of
> Linus' suggested "PID approach" yet, I'd be willing to write a patch and
> test it. Please let me know.

Here's a totally untested patch. It's guaranteed not to do the "right
thing", simply because it doesn't _use_ the uid/euid information. But it's
in the right kind of direction.

If you change the "kill_proc_info()" into a "kill_proc_info_as_uid()"
call, and add that to kernel/signal.c (which is basically kill_proc_info()
except it uses the passed-in uid/euid for the "check_kill_permission()"
tests instead), it should be correct.

As-is, it won't work, because it will use a _random_ uid (whatever is the
currently running process) for the kill permission. So this really is just
a "use this as a template" kind of patch, DO NOT APPLY!

Linus

---
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
@@ -58,7 +58,8 @@ static struct class *usb_device_class;
struct async {
struct list_head asynclist;
struct dev_state *ps;
- struct task_struct *task;
+ pid_t pid;
+ uid_t uid, euid;
unsigned int signr;
unsigned int ifnum;
void __user *userbuffer;
@@ -290,7 +291,14 @@ 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);
+ /*
+ * We should have a
+ *
+ * kill_proc_info_as_uid(signr, info, pid, uid, euid);
+ *
+ * but we don't.
+ */
+ kill_proc_info(as->signr, &sinfo, as->pid);
}
wake_up(&ps->wait);
}
@@ -988,7 +996,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);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/