Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 9795
b: refs/heads/master
c: af74c3a
h: refs/heads/master
i:
  9793: 84ee978
  9791: c351826
v: v3
  • Loading branch information
Linus Torvalds committed Oct 10, 2005
1 parent c09ea93 commit 6902a04
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 9 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: 5d8e1b181c4ad63e6ca90d51287b31afd400d2eb
refs/heads/master: af74c3a61d24ab42c04052ddd2343de972a1cc07
2 changes: 0 additions & 2 deletions trunk/arch/x86_64/mm/pageattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,6 @@ void global_flush_tlb(void)
down_read(&init_mm.mmap_sem);
df = xchg(&df_list, NULL);
up_read(&init_mm.mmap_sem);
if (!df)
return;
flush_map((df && !df->next) ? df->address : 0);
for (; df; df = next_df) {
next_df = df->next;
Expand Down
16 changes: 12 additions & 4 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 @@ -526,7 +530,9 @@ static int usbdev_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&ps->async_completed);
init_waitqueue_head(&ps->wait);
ps->discsignr = 0;
ps->disctask = current;
ps->disc_pid = current->pid;
ps->disc_uid = current->uid;
ps->disc_euid = current->euid;
ps->disccontext = NULL;
ps->ifclaimed = 0;
wmb();
Expand Down Expand Up @@ -988,7 +994,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
2 changes: 1 addition & 1 deletion trunk/drivers/usb/core/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ void usbfs_remove_device(struct usb_device *dev)
sinfo.si_errno = EPIPE;
sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = ds->disccontext;
send_sig_info(ds->discsignr, &sinfo, ds->disctask);
kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid);
}
}
usbfs_update_special();
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/usb/core/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ struct dev_state {
struct list_head async_completed;
wait_queue_head_t wait; /* wake up if a request completed */
unsigned int discsignr;
struct task_struct *disctask;
pid_t disc_pid;
uid_t disc_uid, disc_euid;
void __user *disccontext;
unsigned long ifclaimed;
};
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 6902a04

Please sign in to comment.