aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-09 00:48:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-09 00:48:15 -0400
commit5ad18b2e60b75c7297a998dea702451d33a052ed (patch)
treec47fb503b4cfc8d3e99ad425aadede9832e96dc4 /drivers/usb/core/devio.c
parent92c1d6522135050cb377a18cc6e30d08dfb87efb (diff)
parent318759b4737c3b3789e2fd64d539f437d52386f5 (diff)
Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull force_sig() argument change from Eric Biederman: "A source of error over the years has been that force_sig has taken a task parameter when it is only safe to use force_sig with the current task. The force_sig function is built for delivering synchronous signals such as SIGSEGV where the userspace application caused a synchronous fault (such as a page fault) and the kernel responded with a signal. Because the name force_sig does not make this clear, and because the force_sig takes a task parameter the function force_sig has been abused for sending other kinds of signals over the years. Slowly those have been fixed when the oopses have been tracked down. This set of changes fixes the remaining abusers of force_sig and carefully rips out the task parameter from force_sig and friends making this kind of error almost impossible in the future" * 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (27 commits) signal/x86: Move tsk inside of CONFIG_MEMORY_FAILURE in do_sigbus signal: Remove the signal number and task parameters from force_sig_info signal: Factor force_sig_info_to_task out of force_sig_info signal: Generate the siginfo in force_sig signal: Move the computation of force into send_signal and correct it. signal: Properly set TRACE_SIGNAL_LOSE_INFO in __send_signal signal: Remove the task parameter from force_sig_fault signal: Use force_sig_fault_to_task for the two calls that don't deliver to current signal: Explicitly call force_sig_fault on current signal/unicore32: Remove tsk parameter from __do_user_fault signal/arm: Remove tsk parameter from __do_user_fault signal/arm: Remove tsk parameter from ptrace_break signal/nds32: Remove tsk parameter from send_sigtrap signal/riscv: Remove tsk parameter from do_trap signal/sh: Remove tsk parameter from force_sig_info_fault signal/um: Remove task parameter from send_sigtrap signal/x86: Remove task parameter from send_sigtrap signal: Remove task parameter from force_sig_mceerr signal: Remove task parameter from force_sig signal: Remove task parameter from force_sigsegv ...
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index fa783531ee88..a02448105527 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -63,7 +63,7 @@ struct usb_dev_state {
63 unsigned int discsignr; 63 unsigned int discsignr;
64 struct pid *disc_pid; 64 struct pid *disc_pid;
65 const struct cred *cred; 65 const struct cred *cred;
66 void __user *disccontext; 66 sigval_t disccontext;
67 unsigned long ifclaimed; 67 unsigned long ifclaimed;
68 u32 disabled_bulk_eps; 68 u32 disabled_bulk_eps;
69 bool privileges_dropped; 69 bool privileges_dropped;
@@ -90,6 +90,7 @@ struct async {
90 unsigned int ifnum; 90 unsigned int ifnum;
91 void __user *userbuffer; 91 void __user *userbuffer;
92 void __user *userurb; 92 void __user *userurb;
93 sigval_t userurb_sigval;
93 struct urb *urb; 94 struct urb *urb;
94 struct usb_memory *usbm; 95 struct usb_memory *usbm;
95 unsigned int mem_usage; 96 unsigned int mem_usage;
@@ -582,22 +583,19 @@ static void async_completed(struct urb *urb)
582{ 583{
583 struct async *as = urb->context; 584 struct async *as = urb->context;
584 struct usb_dev_state *ps = as->ps; 585 struct usb_dev_state *ps = as->ps;
585 struct kernel_siginfo sinfo;
586 struct pid *pid = NULL; 586 struct pid *pid = NULL;
587 const struct cred *cred = NULL; 587 const struct cred *cred = NULL;
588 unsigned long flags; 588 unsigned long flags;
589 int signr; 589 sigval_t addr;
590 int signr, errno;
590 591
591 spin_lock_irqsave(&ps->lock, flags); 592 spin_lock_irqsave(&ps->lock, flags);
592 list_move_tail(&as->asynclist, &ps->async_completed); 593 list_move_tail(&as->asynclist, &ps->async_completed);
593 as->status = urb->status; 594 as->status = urb->status;
594 signr = as->signr; 595 signr = as->signr;
595 if (signr) { 596 if (signr) {
596 clear_siginfo(&sinfo); 597 errno = as->status;
597 sinfo.si_signo = as->signr; 598 addr = as->userurb_sigval;
598 sinfo.si_errno = as->status;
599 sinfo.si_code = SI_ASYNCIO;
600 sinfo.si_addr = as->userurb;
601 pid = get_pid(as->pid); 599 pid = get_pid(as->pid);
602 cred = get_cred(as->cred); 600 cred = get_cred(as->cred);
603 } 601 }
@@ -615,7 +613,7 @@ static void async_completed(struct urb *urb)
615 spin_unlock_irqrestore(&ps->lock, flags); 613 spin_unlock_irqrestore(&ps->lock, flags);
616 614
617 if (signr) { 615 if (signr) {
618 kill_pid_info_as_cred(sinfo.si_signo, &sinfo, pid, cred); 616 kill_pid_usb_asyncio(signr, errno, addr, pid, cred);
619 put_pid(pid); 617 put_pid(pid);
620 put_cred(cred); 618 put_cred(cred);
621 } 619 }
@@ -1427,7 +1425,7 @@ find_memory_area(struct usb_dev_state *ps, const struct usbdevfs_urb *uurb)
1427 1425
1428static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb, 1426static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb,
1429 struct usbdevfs_iso_packet_desc __user *iso_frame_desc, 1427 struct usbdevfs_iso_packet_desc __user *iso_frame_desc,
1430 void __user *arg) 1428 void __user *arg, sigval_t userurb_sigval)
1431{ 1429{
1432 struct usbdevfs_iso_packet_desc *isopkt = NULL; 1430 struct usbdevfs_iso_packet_desc *isopkt = NULL;
1433 struct usb_host_endpoint *ep; 1431 struct usb_host_endpoint *ep;
@@ -1727,6 +1725,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
1727 isopkt = NULL; 1725 isopkt = NULL;
1728 as->ps = ps; 1726 as->ps = ps;
1729 as->userurb = arg; 1727 as->userurb = arg;
1728 as->userurb_sigval = userurb_sigval;
1730 if (as->usbm) { 1729 if (as->usbm) {
1731 unsigned long uurb_start = (unsigned long)uurb->buffer; 1730 unsigned long uurb_start = (unsigned long)uurb->buffer;
1732 1731
@@ -1801,13 +1800,17 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
1801static int proc_submiturb(struct usb_dev_state *ps, void __user *arg) 1800static int proc_submiturb(struct usb_dev_state *ps, void __user *arg)
1802{ 1801{
1803 struct usbdevfs_urb uurb; 1802 struct usbdevfs_urb uurb;
1803 sigval_t userurb_sigval;
1804 1804
1805 if (copy_from_user(&uurb, arg, sizeof(uurb))) 1805 if (copy_from_user(&uurb, arg, sizeof(uurb)))
1806 return -EFAULT; 1806 return -EFAULT;
1807 1807
1808 memset(&userurb_sigval, 0, sizeof(userurb_sigval));
1809 userurb_sigval.sival_ptr = arg;
1810
1808 return proc_do_submiturb(ps, &uurb, 1811 return proc_do_submiturb(ps, &uurb,
1809 (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), 1812 (((struct usbdevfs_urb __user *)arg)->iso_frame_desc),
1810 arg); 1813 arg, userurb_sigval);
1811} 1814}
1812 1815
1813static int proc_unlinkurb(struct usb_dev_state *ps, void __user *arg) 1816static int proc_unlinkurb(struct usb_dev_state *ps, void __user *arg)
@@ -1977,7 +1980,7 @@ static int proc_disconnectsignal_compat(struct usb_dev_state *ps, void __user *a
1977 if (copy_from_user(&ds, arg, sizeof(ds))) 1980 if (copy_from_user(&ds, arg, sizeof(ds)))
1978 return -EFAULT; 1981 return -EFAULT;
1979 ps->discsignr = ds.signr; 1982 ps->discsignr = ds.signr;
1980 ps->disccontext = compat_ptr(ds.context); 1983 ps->disccontext.sival_int = ds.context;
1981 return 0; 1984 return 0;
1982} 1985}
1983 1986
@@ -2005,13 +2008,17 @@ static int get_urb32(struct usbdevfs_urb *kurb,
2005static int proc_submiturb_compat(struct usb_dev_state *ps, void __user *arg) 2008static int proc_submiturb_compat(struct usb_dev_state *ps, void __user *arg)
2006{ 2009{
2007 struct usbdevfs_urb uurb; 2010 struct usbdevfs_urb uurb;
2011 sigval_t userurb_sigval;
2008 2012
2009 if (get_urb32(&uurb, (struct usbdevfs_urb32 __user *)arg)) 2013 if (get_urb32(&uurb, (struct usbdevfs_urb32 __user *)arg))
2010 return -EFAULT; 2014 return -EFAULT;
2011 2015
2016 memset(&userurb_sigval, 0, sizeof(userurb_sigval));
2017 userurb_sigval.sival_int = ptr_to_compat(arg);
2018
2012 return proc_do_submiturb(ps, &uurb, 2019 return proc_do_submiturb(ps, &uurb,
2013 ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, 2020 ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc,
2014 arg); 2021 arg, userurb_sigval);
2015} 2022}
2016 2023
2017static int processcompl_compat(struct async *as, void __user * __user *arg) 2024static int processcompl_compat(struct async *as, void __user * __user *arg)
@@ -2092,7 +2099,7 @@ static int proc_disconnectsignal(struct usb_dev_state *ps, void __user *arg)
2092 if (copy_from_user(&ds, arg, sizeof(ds))) 2099 if (copy_from_user(&ds, arg, sizeof(ds)))
2093 return -EFAULT; 2100 return -EFAULT;
2094 ps->discsignr = ds.signr; 2101 ps->discsignr = ds.signr;
2095 ps->disccontext = ds.context; 2102 ps->disccontext.sival_ptr = ds.context;
2096 return 0; 2103 return 0;
2097} 2104}
2098 2105
@@ -2614,22 +2621,15 @@ const struct file_operations usbdev_file_operations = {
2614static void usbdev_remove(struct usb_device *udev) 2621static void usbdev_remove(struct usb_device *udev)
2615{ 2622{
2616 struct usb_dev_state *ps; 2623 struct usb_dev_state *ps;
2617 struct kernel_siginfo sinfo;
2618 2624
2619 while (!list_empty(&udev->filelist)) { 2625 while (!list_empty(&udev->filelist)) {
2620 ps = list_entry(udev->filelist.next, struct usb_dev_state, list); 2626 ps = list_entry(udev->filelist.next, struct usb_dev_state, list);
2621 destroy_all_async(ps); 2627 destroy_all_async(ps);
2622 wake_up_all(&ps->wait); 2628 wake_up_all(&ps->wait);
2623 list_del_init(&ps->list); 2629 list_del_init(&ps->list);
2624 if (ps->discsignr) { 2630 if (ps->discsignr)
2625 clear_siginfo(&sinfo); 2631 kill_pid_usb_asyncio(ps->discsignr, EPIPE, ps->disccontext,
2626 sinfo.si_signo = ps->discsignr; 2632 ps->disc_pid, ps->cred);
2627 sinfo.si_errno = EPIPE;
2628 sinfo.si_code = SI_ASYNCIO;
2629 sinfo.si_addr = ps->disccontext;
2630 kill_pid_info_as_cred(ps->discsignr, &sinfo,
2631 ps->disc_pid, ps->cred);
2632 }
2633 } 2633 }
2634} 2634}
2635 2635