View | Details | Raw Unified | Return to bug 127916
Collapse All | Expand All

(-)a/drivers/usb/core/devio.c (-3 / +9 lines)
Lines 30-35 Link Here
30
 *  Revision history
30
 *  Revision history
31
 *    22.12.1999   0.1   Initial release (split from proc_usb.c)
31
 *    22.12.1999   0.1   Initial release (split from proc_usb.c)
32
 *    04.01.2000   0.2   Turned into its own filesystem
32
 *    04.01.2000   0.2   Turned into its own filesystem
33
 *    30.09.2005   0.3   Fix user-triggerable oops in async URB delivery
34
 *    			 (CAN-2005-3055)
33
 */
35
 */
34
36
35
/*****************************************************************************/
37
/*****************************************************************************/
Lines 58-64 static struct class *usb_device_class; Link Here
58
struct async {
60
struct async {
59
	struct list_head asynclist;
61
	struct list_head asynclist;
60
	struct dev_state *ps;
62
	struct dev_state *ps;
61
	struct task_struct *task;
63
	pid_t pid;
64
	uid_t uid, euid;
62
	unsigned int signr;
65
	unsigned int signr;
63
	unsigned int ifnum;
66
	unsigned int ifnum;
64
	void __user *userbuffer;
67
	void __user *userbuffer;
Lines 290-296 static void async_completed(struct urb * Link Here
290
		sinfo.si_errno = as->urb->status;
293
		sinfo.si_errno = as->urb->status;
291
		sinfo.si_code = SI_ASYNCIO;
294
		sinfo.si_code = SI_ASYNCIO;
292
		sinfo.si_addr = as->userurb;
295
		sinfo.si_addr = as->userurb;
293
		send_sig_info(as->signr, &sinfo, as->task);
296
		kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, 
297
				      as->euid);
294
	}
298
	}
295
        wake_up(&ps->wait);
299
        wake_up(&ps->wait);
296
}
300
}
Lines 988-994 static int proc_do_submiturb(struct dev_ Link Here
988
		as->userbuffer = NULL;
992
		as->userbuffer = NULL;
989
	as->signr = uurb->signr;
993
	as->signr = uurb->signr;
990
	as->ifnum = ifnum;
994
	as->ifnum = ifnum;
991
	as->task = current;
995
	as->pid = current->pid;
996
	as->uid = current->uid;
997
	as->euid = current->euid;
992
	if (!(uurb->endpoint & USB_DIR_IN)) {
998
	if (!(uurb->endpoint & USB_DIR_IN)) {
993
		if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) {
999
		if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) {
994
			free_async(as);
1000
			free_async(as);
(-)a/include/linux/sched.h (+1 lines)
Lines 1018-1023 extern int force_sig_info(int, struct si Link Here
1018
extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
1018
extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
1019
extern int kill_pg_info(int, struct siginfo *, pid_t);
1019
extern int kill_pg_info(int, struct siginfo *, pid_t);
1020
extern int kill_proc_info(int, struct siginfo *, pid_t);
1020
extern int kill_proc_info(int, struct siginfo *, pid_t);
1021
extern int kill_proc_info_as_uid(int, struct siginfo *, pid_t, uid_t, uid_t);
1021
extern void do_notify_parent(struct task_struct *, int);
1022
extern void do_notify_parent(struct task_struct *, int);
1022
extern void force_sig(int, struct task_struct *);
1023
extern void force_sig(int, struct task_struct *);
1023
extern void force_sig_specific(int, struct task_struct *);
1024
extern void force_sig_specific(int, struct task_struct *);
(-)a/kernel/signal.c (-1 / +34 lines)
Lines 1193-1198 kill_proc_info(int sig, struct siginfo * Link Here
1193
	return error;
1193
	return error;
1194
}
1194
}
1195
1195
1196
/* like kill_proc_info(), but doesn't use uid/euid of "current" */
1197
int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
1198
		      uid_t uid, uid_t euid)
1199
{
1200
	int ret = -EINVAL;
1201
	struct task_struct *p;
1202
1203
	if (!valid_signal(sig))
1204
		return ret;
1205
1206
	read_lock(&tasklist_lock);
1207
	p = find_task_by_pid(pid);
1208
	if (!p) {
1209
		ret = -ESRCH;
1210
		goto out_unlock;
1211
	}
1212
	if ((!info || ((unsigned long)info != 1 &&
1213
			(unsigned long)info != 2 && SI_FROMUSER(info)))
1214
	    && (euid != p->suid) && (euid != p->uid)
1215
	    && (uid != p->suid) && (uid != p->uid)) {
1216
		ret = -EPERM;
1217
		goto out_unlock;
1218
	}
1219
	if (sig && p->sighand) {
1220
		unsigned long flags;
1221
		spin_lock_irqsave(&p->sighand->siglock, flags);
1222
		ret = __group_send_sig_info(sig, info, p);
1223
		spin_unlock_irqrestore(&p->sighand->siglock, flags);
1224
	}
1225
out_unlock:
1226
	read_unlock(&tasklist_lock);
1227
	return ret;
1228
}
1229
EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);
1196
1230
1197
/*
1231
/*
1198
 * kill_something_info() interprets pid in interesting ways just like kill(2).
1232
 * kill_something_info() interprets pid in interesting ways just like kill(2).
1199

Return to bug 127916