Merge tag 'driver-core-5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core fixes from Greg KH:
"Here are two small fixes for some driver core issues that have been
reported. There is also a kernfs "fix" here, which was then reverted
because it was found to cause problems in linux-next.

The driver core fixes both resolve reported issues, one with gpioint
stuff that showed up in 5.3-rc1, and the other finally (and hopefully)
resolves a very long standing race when removing glue directories.
It's nice to get that issue finally resolved and the developers
involved should be applauded for the persistence it took to get this
patch finally accepted.

All of these have been in linux-next for a while with no reported
issues. Well, the one reported issue, hence the revert :)"

* tag 'driver-core-5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
Revert "kernfs: fix memleak in kernel_ops_readdir()"
kernfs: fix memleak in kernel_ops_readdir()
driver core: Fix use-after-free and double free on glue directory
driver core: platform: return -ENXIO for missing GpioInt

+59 -3
+52 -1
drivers/base/core.c
··· 1823 1823 */ 1824 1824 static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 1825 1825 { 1826 + unsigned int ref; 1827 + 1826 1828 /* see if we live in a "glue" directory */ 1827 1829 if (!live_in_glue_dir(glue_dir, dev)) 1828 1830 return; 1829 1831 1830 1832 mutex_lock(&gdp_mutex); 1831 - if (!kobject_has_children(glue_dir)) 1833 + /** 1834 + * There is a race condition between removing glue directory 1835 + * and adding a new device under the glue directory. 1836 + * 1837 + * CPU1: CPU2: 1838 + * 1839 + * device_add() 1840 + * get_device_parent() 1841 + * class_dir_create_and_add() 1842 + * kobject_add_internal() 1843 + * create_dir() // create glue_dir 1844 + * 1845 + * device_add() 1846 + * get_device_parent() 1847 + * kobject_get() // get glue_dir 1848 + * 1849 + * device_del() 1850 + * cleanup_glue_dir() 1851 + * kobject_del(glue_dir) 1852 + * 1853 + * kobject_add() 1854 + * kobject_add_internal() 1855 + * create_dir() // in glue_dir 1856 + * sysfs_create_dir_ns() 1857 + * kernfs_create_dir_ns(sd) 1858 + * 1859 + * sysfs_remove_dir() // glue_dir->sd=NULL 1860 + * sysfs_put() // free glue_dir->sd 1861 + * 1862 + * // sd is freed 1863 + * kernfs_new_node(sd) 1864 + * kernfs_get(glue_dir) 1865 + * kernfs_add_one() 1866 + * kernfs_put() 1867 + * 1868 + * Before CPU1 remove last child device under glue dir, if CPU2 add 1869 + * a new device under glue dir, the glue_dir kobject reference count 1870 + * will be increase to 2 in kobject_get(k). And CPU2 has been called 1871 + * kernfs_create_dir_ns(). Meanwhile, CPU1 call sysfs_remove_dir() 1872 + * and sysfs_put(). This result in glue_dir->sd is freed. 1873 + * 1874 + * Then the CPU2 will see a stale "empty" but still potentially used 1875 + * glue dir around in kernfs_new_node(). 1876 + * 1877 + * In order to avoid this happening, we also should make sure that 1878 + * kernfs_node for glue_dir is released in CPU1 only when refcount 1879 + * for glue_dir kobj is 1. 1880 + */ 1881 + ref = kref_read(&glue_dir->kref); 1882 + if (!kobject_has_children(glue_dir) && !--ref) 1832 1883 kobject_del(glue_dir); 1833 1884 kobject_put(glue_dir); 1834 1885 mutex_unlock(&gdp_mutex);
+7 -2
drivers/base/platform.c
··· 157 157 * the device will only expose one IRQ, and this fallback 158 158 * allows a common code path across either kind of resource. 159 159 */ 160 - if (num == 0 && has_acpi_companion(&dev->dev)) 161 - return acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); 160 + if (num == 0 && has_acpi_companion(&dev->dev)) { 161 + int ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); 162 + 163 + /* Our callers expect -ENXIO for missing IRQs. */ 164 + if (ret >= 0 || ret == -EPROBE_DEFER) 165 + return ret; 166 + } 162 167 163 168 return -ENXIO; 164 169 #endif