Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fbdev: smscufx: Fix use-after-free in ufx_ops_open()

A race condition may occur if the user physically removes the
USB device while calling open() for this device node.

This is a race condition between the ufx_ops_open() function and
the ufx_usb_disconnect() function, which may eventually result in UAF.

So, add a mutex to the ufx_ops_open() and ufx_usb_disconnect() functions
to avoid race contidion of krefs.

Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Helge Deller <deller@gmx.de>

authored by

Hyunwoo Kim and committed by
Helge Deller
5610bcfe e69dade8

+13 -1
+13 -1
drivers/video/fbdev/smscufx.c
··· 137 137 static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size); 138 138 static void ufx_free_urb_list(struct ufx_data *dev); 139 139 140 + static DEFINE_MUTEX(disconnect_mutex); 141 + 140 142 /* reads a control register */ 141 143 static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data) 142 144 { ··· 1073 1071 if (user == 0 && !console) 1074 1072 return -EBUSY; 1075 1073 1074 + mutex_lock(&disconnect_mutex); 1075 + 1076 1076 /* If the USB device is gone, we don't accept new opens */ 1077 - if (dev->virtualized) 1077 + if (dev->virtualized) { 1078 + mutex_unlock(&disconnect_mutex); 1078 1079 return -ENODEV; 1080 + } 1079 1081 1080 1082 dev->fb_count++; 1081 1083 ··· 1102 1096 1103 1097 pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d", 1104 1098 info->node, user, info, dev->fb_count); 1099 + 1100 + mutex_unlock(&disconnect_mutex); 1105 1101 1106 1102 return 0; 1107 1103 } ··· 1749 1741 { 1750 1742 struct ufx_data *dev; 1751 1743 1744 + mutex_lock(&disconnect_mutex); 1745 + 1752 1746 dev = usb_get_intfdata(interface); 1753 1747 1754 1748 pr_debug("USB disconnect starting\n"); ··· 1771 1761 kref_put(&dev->kref, ufx_free); 1772 1762 1773 1763 /* consider ufx_data freed */ 1764 + 1765 + mutex_unlock(&disconnect_mutex); 1774 1766 } 1775 1767 1776 1768 static struct usb_driver ufx_driver = {