Re: [PATCH] scsi: target: tcmu: Fix wrong uio handling causing big memory leak

From: Bodo Stroesser
Date: Wed Jan 13 2021 - 12:59:56 EST


On 12.01.21 19:36, Mike Christie wrote:
On 12/18/20 8:15 AM, Bodo Stroesser wrote:
tcmu calls uio_unregister_device from tcmu_destroy_device.
After that uio will never call tcmu_release for this device.
If userspace still had the uio device open and / or mmap'ed
during uio_unregister_device, tcmu_release will not be called and
udev->kref will never go down to 0.


I didn't get why the release function is not called if you call
uio_unregister_device while a device is open. Does the device_destroy call in
uio_unregister_device completely free the device or does it set some bits so
uio_release is not called later?

uio_unregister_device() resets the pointer (idev->info) to the struct uio_info which tcmu provided in uio_register_device().
The uio device itself AFAICS is kept while it is open / mmap'ed.
But no matter what userspace does, uio will not call tcmu's callbacks
since info pointer now is NULL.

When userspace finally closes the uio device, uio_release is called, but
tcmu_release can not be called.


Do other drivers hit this? Should uio have refcounting so uio_release is called
when the last ref (from userspace open/close/mmap calls and from the kernel by
drivers like target_core_user) is done?


To be honest I don't know exactly.
tcmu seems to be a special case in that is has it's own mmap callback.
That allows us to map pages allocated by tcmu.
As long as userspace still holds the mapping, we should not unmap those
pages, because userspace then could get killed by SIGSEGV.
So we have to wait for userspace closing uio before we may unmap and
free the pages.