On Tue, Aug 29, 2023 at 08:54:06PM +0000, zdi-disclosures@xxxxxxxxxxxxxx wrote: > The attachment could not be scanned for viruses because it is a password protected file. > ZDI-CAN-22042: Linux Kernel USB Core Out-Of-Bounds Read Local Privilege Escalation Vulnerability > > -- CVSS ----------------------------------------- > > 7.1: AV:P/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H > > -- ABSTRACT ------------------------------------- > > Trend Micro's Zero Day Initiative has identified a vulnerability affecting the following products: > Linux - Kernel > > -- VULNERABILITY DETAILS ------------------------ > * Version tested:6.5-rc7 > * Installer file:- > * Platform tested:debian bullseye > > --- > > ### Analysis > > ``` usb_destroy_configuration() didn't consider/validate the updated > USB descriptor it leads to out-of-bounds access in > usb_destroy_configuration() it would call kfree() on a pointer that is > read from out-of-bounds it would be triggered physically the build > config is from syzbot's ci-qemu-upstream ``` > > ~~~C++ > int usb_get_configuration(struct usb_device *dev) { > struct device *ddev = &dev->dev; > int ncfg = dev->descriptor.bNumConfigurations; > unsigned int cfgno, length; > unsigned char *bigbuffer; > struct usb_config_descriptor *desc; > int result; > > if (ncfg > USB_MAXCONFIG) { > dev_notice(ddev, "too many configurations: %d, " > "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); > dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; > } > > if (ncfg < 1) { > dev_err(ddev, "no configurations\n"); > return -EINVAL; > } > > length = ncfg * sizeof(struct usb_host_config); > dev->config = kzalloc(length, GFP_KERNEL); > if (!dev->config) > return -ENOMEM; > > length = ncfg * sizeof(char *); > dev->rawdescriptors = kzalloc(length, GFP_KERNEL); // (1) at the beginning, length is 8, ncfg is 1 > ... > } > > static int sd_config(struct gspca_dev *gspca_dev, > const struct usb_device_id *id) > { > struct sd *sd = (struct sd *)gspca_dev; > struct cam *cam = &gspca_dev->cam; > u8 *cd = gspca_dev->usb_buf; > int i, j, n; > int widths[MAX_MODES], heights[MAX_MODES]; > > /* Read the camera descriptor */ > se401_read_req(gspca_dev, SE401_REQ_GET_CAMERA_DESCRIPTOR, 1); > if (gspca_dev->usb_err) { > /* Sometimes after being idle for a while the se401 won't > respond and needs a good kicking */ > usb_reset_device(gspca_dev->dev); // (2) if usb_reset_device() is called, the dev->descriptor will be updated from USB This should be fixed by the following commits in linux-next: 85d07c556216, de28e469da75, ff33299ec8bb, 59cf44575456 (particularly the third one). Presumably these will be added into 6.6-rc1 during the current merge window and then back-ported to the stable kernels. Alan Stern