Re: [PATCH 2/2] dmabuf/tracing: Add dma-buf trace events
From: Kalesh Singh
Date: Tue Aug 04 2020 - 16:43:05 EST
On Tue, Aug 04, 2020 at 07:27:24PM +0100, Al Viro wrote:
> On Tue, Aug 04, 2020 at 03:44:51PM +0000, Kalesh Singh wrote:
> > Hi Al. Thank you for the comments. Ultimately what we need is to identify processes
> > that hold a file reference to the dma-buf. Unfortunately we can't use only
> > explicit dma_buf_get/dma_buf_put to track them because when an FD is being shared
> > between processes the file references are taken implicitly.
> > For example, on the sender side:
> > unix_dgram_sendmsg -> send_scm -> __send_scm -> scm_fp_copy -> fget_raw
> > and on the receiver side:
> > unix_dgram_recvmsg -> scm_recv -> scm_detach_fds -> __scm_install_fd -> get_file
> > I understand now that fd_install is not an appropriate abstraction level to track these.
> > Is there a more appropriate alternative where we could use to track these implicit file
> > references?
> There is no single lock that would stabilize the descriptor tables of all
> processes. And there's not going to be one, ever - it would be a contention
> point from hell, since that would've been a system-wide lock that would have
> to be taken by *ALL* syscalls modifying any descriptor table. Not going to
> happen, for obvious reasons. Moreover, you would have to have fork(2) take
> the same lock, since it does copy descriptor table. And clone(2) either does
> the same, or has the child share the descriptor table of parent.
> What's more, a reference to struct file can bloody well survive without
> a single descriptor refering to that file. In the example you've mentioned
> above, sender has ever right to close all descriptors it has sent. Files
> will stay opened as long as the references are held in the datagram; when
> that datagram is received, the references will be inserted into recepient's
> descriptor table. At that point you again have descriptors refering to
> that file, can do any IO on it, etc.
> So "the set of processes that hold a file reference to the dma-buf" is
> * inherently unstable, unless you are willing to freeze every
> process in the system except for the one trying to find that set.
> * can remain empty for any amount of time (hours, weeks, whatever),
> only to get non-empty later, with syscalls affecting the object in question
> done afterwards.
> So... what were you going to do with that set if you could calculate it?
> If it's really "how do we debug a leak?", it's one thing; in that case
> I would suggest keeping track of creation/destruction of objects (not
> gaining/dropping references - actual constructors and destructors) to
> see what gets stuck around for too long and use fuser(1) to try and locate
> the culprits if you see that something *was* living for too long. "Try"
> since the only reference might indeed have been stashed into an SCM_RIGHTS
> datagram sitting in a queue of some AF_UNIX socket. Note that "fuser
> needs elevated priveleges" is not a strong argument - the ability to
> do that sort of tracking does imply elevated priveleges anyway, and
> having a root process taking requests along the lines of "gimme the
> list of PIDs that have such-and-such dma_buf in their descriptor table"
> is not much of an attack surface.
> If you want to use it for something else, you'll need to describe that
> intended use; there might be sane ways to do that, but it's hard to
> come up with one without knowing what's being attempted...
Hi Al. Thanks for the guidance and detailed explanation. It appears what we
were trying to accomplish here is not feasible.