Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 9792
b: refs/heads/master
c: 4611383
h: refs/heads/master
v: v3
  • Loading branch information
Harald Welte authored and Linus Torvalds committed Oct 10, 2005
1 parent c351826 commit 6003174
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 094804c5a132f04c12dd4902ee15c64362e5c1af
refs/heads/master: 46113830a18847cff8da73005e57bc49c2f95a56
12 changes: 9 additions & 3 deletions trunk/drivers/usb/core/devio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
*/

/*****************************************************************************/
Expand Down Expand Up @@ -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;
uid_t uid, euid;
unsigned int signr;
unsigned int ifnum;
void __user *userbuffer;
Expand Down Expand Up @@ -290,7 +293,8 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
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);
}
Expand Down Expand Up @@ -988,7 +992,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
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);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,7 @@ extern int force_sig_info(int, struct siginfo *, struct task_struct *);
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, uid_t, uid_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 *);
Expand Down
34 changes: 34 additions & 0 deletions trunk/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,40 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
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,
uid_t uid, uid_t euid)
{
int ret = -EINVAL;
struct task_struct *p;

if (!valid_signal(sig))
return ret;

read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
if (!p) {
ret = -ESRCH;
goto out_unlock;
}
if ((!info || ((unsigned long)info != 1 &&
(unsigned long)info != 2 && SI_FROMUSER(info)))
&& (euid != p->suid) && (euid != p->uid)
&& (uid != p->suid) && (uid != p->uid)) {
ret = -EPERM;
goto out_unlock;
}
if (sig && p->sighand) {
unsigned long flags;
spin_lock_irqsave(&p->sighand->siglock, flags);
ret = __group_send_sig_info(sig, info, p);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
}
out_unlock:
read_unlock(&tasklist_lock);
return ret;
}
EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);

/*
* kill_something_info() interprets pid in interesting ways just like kill(2).
Expand Down

0 comments on commit 6003174

Please sign in to comment.