On Tue, Mar 15, 2022 at 05:22:15AM +0200, Mika Penttilä wrote: > Hi Jason and thanks for your comments.. > > On 14.3.2022 20.24, Jason Gunthorpe wrote: > > On Fri, Mar 11, 2022 at 05:30:50AM +0200, mpenttil@xxxxxxxxxx wrote: > > > From: Mika Penttilä <mpenttil@xxxxxxxxxx> > > > > > > HMM selftests use an in-kernel pseudo device to emulate device private > > > memory. The pseudo device registers a major device range for two pseudo > > > device instances. User space has a script that reads /proc/devices in > > > order to find the assigned major number, and sends that to mknod(1), > > > once for each node. > > > > > > This duplicates a fair amount of boilerplate that misc device can do > > > instead. > > > > > > Change this to use misc device, which makes the device node names appear > > > for us. This also enables udev-like processing if desired. > > > > This is borderline the wrong way to use misc devices, they should > > never be embedded into other structs like this. It works out here > > because they are eventually only placed in a static array, but still > > it is a generally bad pattern to see. > > Could you elaborate on this one? We have many in-tree usages of the same > pattern, like: The kernel is full of bugs > drivers/video/fbdev/pxa3xx-gcu.c ie this is broken because it allocates like this: priv = devm_kzalloc(dev, sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL); if (!priv) return -ENOMEM; And free's via devm: static int pxa3xx_gcu_remove(struct platform_device *pdev) { struct pxa3xx_gcu_priv *priv = platform_get_drvdata(pdev); misc_deregister(&priv->misc_dev); return 0; } But this will UAF if it races fops open with misc_desregister. Proper use of cdevs with proper struct devices prevent this bug. > You mention "placed in a static array", are you seeing a potential lifetime > issue or what? Many of the examples above embed miscdevice in a dynamically > allocated object also. > > The file object's private_data holds a pointer to the miscdevice, and > fops_get() pins the module. So freeing the objects miscdevice is embedded in > at module_exit time should be fine. But, as you said, in this case the > miscdevices are statically allocated, so that shouldn't be an issue > either. Correct, it is OK here because the module refcounts prevent the miscdevice memory from being freed, the above cases with dynamic allocations do not have that protection and are wrong. This is why I don't care for the pattern of putting misc devices inside other structs, it suggests this is perhaps generally safe but it is not. > I think using cdev_add ends up in the same results in device_* api > sense. Nope, everything works right once you use cdev_device_add on a properly registered struct device. > miscdevice acting like a mux at a higher abstraction level simplifies the > code. It does avoid the extra struct device, but at the cost of broken memory lifetime Jason