From: Matthew Finlay <redacted>
Allow the netlink_queue_module to get the PID associated with an outgoing
connection. Finding the PID based on the tuple in userspace is expensive.
This additional attribute makes it convenient and efficient to get the PID
associated with the outgoing connection in userspace, without the need to
parse procfs.
Signed-off-by: Matthew Finlay <redacted>
Signed-off-by: Saeed Mahameed <redacted>
CC: Pablo Neira Ayuso <pablo@netfilter.org>
CC: Patrick McHardy <redacted>
CC: Jozsef Kadlecsik <redacted>
---
include/linux/fs.h | 1 +
include/uapi/linux/netfilter/nfnetlink_queue.h | 4 +++-
net/netfilter/nfnetlink_queue.c | 25 +++++++++++++++++++++++++
net/socket.c | 1 +
4 files changed, 30 insertions(+), 1 deletion(-)
@@ -871,6 +871,7 @@ extern struct block_device *I_BDEV(struct inode *inode);structfown_struct{rwlock_tlock;/* protects pid, uid, euid fields */structpid*pid;/* pid or -pgrp where SIGIO should be sent */+structpid*sock_pid;/* pid of the process that created the socket */enumpid_typepid_type;/* Kind of process group SIGIO should be sent to */kuid_tuid,euid;/* uid/euid of process setting the owner */intsignum;/* posix.1b rt signal to be delivered on IO */
This looks like this leaks sock_pid reference...?
(find_get_pid -> get_pid -> atomic_inc() , I don't see a put_pid in the
patch)
Can't comment further than this since I'm not familiar with vfs; e.g.
I can't say if fown_struct is right place or not, or if this approach
even works when creating process has exited after fork, etc.
This looks like this leaks sock_pid reference...?
(find_get_pid -> get_pid -> atomic_inc() , I don't see a put_pid in the
patch)
Can't comment further than this since I'm not familiar with vfs; e.g.
I can't say if fown_struct is right place or not, or if this approach
even works when creating process has exited after fork, etc.
Or ... if you xmit the fd via unix domain socket to a different process
and initial owner terminates, which should give you invalid information
then; afaik, this would just increase struct file's refcnt and hand out
an unused fdnum ( get_unused_fd_flags() + fd_install(), etc).
For extending 'struct fown_struct', you probably also need to Cc fs folks.
This looks like this leaks sock_pid reference...?
(find_get_pid -> get_pid -> atomic_inc() , I don't see a put_pid in the
patch)
Can't comment further than this since I'm not familiar with vfs; e.g.
I can't say if fown_struct is right place or not, or if this approach
even works when creating process has exited after fork, etc.
Or ... if you xmit the fd via unix domain socket to a different process
and initial owner terminates, which should give you invalid information
then; afaik, this would just increase struct file's refcnt and hand out
an unused fdnum ( get_unused_fd_flags() + fd_install(), etc).
For extending 'struct fown_struct', you probably also need to Cc fs folks.
[ Cc'ing John, Daniel, et al ]
Btw, while I just looked at scm_detach_fds(), I think commits ...
* 48a87cc26c13 ("net: netprio: fd passed in SCM_RIGHTS datagram not set correctly")
* d84295067fc7 ("net: net_cls: fd passed in SCM_RIGHTS datagram not set correctly")
... might not be correct, maybe I'm missing something ...? Lets say process A
has a socket fd that it sends via SCM_RIGHTS to process B. Process A was the
one that called sk_alloc() originally. Now in scm_detach_fds() we install a new
fd for process B pointing to the same sock (file's private_data) and above commits
update the cached socket cgroup data for net_cls/net_prio to the new process B.
So, if process A for example still sends data over that socket, skbs will then
wrongly match on B's cgroup membership instead of A's, no?
Thanks,
Daniel
From: Daniel Wagner <hidden> Date: 2016-06-10 06:40:34
Hi Daniel,
[ Cc'ing John, Daniel, et al ]
Btw, while I just looked at scm_detach_fds(), I think commits ...
* 48a87cc26c13 ("net: netprio: fd passed in SCM_RIGHTS datagram not set
correctly")
* d84295067fc7 ("net: net_cls: fd passed in SCM_RIGHTS datagram not set
correctly")
... might not be correct, maybe I'm missing something ...? Lets say
process A
has a socket fd that it sends via SCM_RIGHTS to process B. Process A was
the
one that called sk_alloc() originally. Now in scm_detach_fds() we
install a new
fd for process B pointing to the same sock (file's private_data) and
above commits
update the cached socket cgroup data for net_cls/net_prio to the new
process B.
So, if process A for example still sends data over that socket, skbs
will then
wrongly match on B's cgroup membership instead of A's, no?
I can't remember the details right now (need to read up again but I wont
have time till Wednesday).
From your analysis I would say that is not the desired effect. A should
match against its own cgroup and not the one of B.
cheers,
daniel
Wow, that is a serious memory leak weapon (of struct pid)
Why don't you store the pid value, instead of a pointer ?
Since the numeric 'pid' values can be reused (with no grace time) you'd
need to hold a reference to the pid structure (added in about 2.6.27) instead.
Which is just a smaller memory leak!
(and annoyingly a non-gpl driver can't drop a reference to it).
David
Wow, that is a serious memory leak weapon (of struct pid)
Why don't you store the pid value, instead of a pointer ?
Since the numeric 'pid' values can be reused (with no grace time) you'd
need to hold a reference to the pid structure (added in about 2.6.27) instead.
Which is just a smaller memory leak!
Smaller than what ?
I fail to see how keeping a reference on the pid structure of the
process who created a socket can be useful, other than some optional
LSM.
A socket can be given via af_unix to another process.
Original process might have died.
Keeping a ref on the pid wont prevent this.
So the 'pid' here looks as a pure hint/info. Better store it directly
and avoid all the ref counting and indirection games that are going to
slow down nfnetlink quite a lot with all these extra cache line misses
and locks.
Hello,
On Fri, Jun 10, 2016 at 08:40:34AM +0200, Daniel Wagner wrote:
quoted
[ Cc'ing John, Daniel, et al ]
Btw, while I just looked at scm_detach_fds(), I think commits ...
* 48a87cc26c13 ("net: netprio: fd passed in SCM_RIGHTS datagram not set
correctly")
* d84295067fc7 ("net: net_cls: fd passed in SCM_RIGHTS datagram not set
correctly")
... might not be correct, maybe I'm missing something ...? Lets say
process A
has a socket fd that it sends via SCM_RIGHTS to process B. Process A was
the
one that called sk_alloc() originally. Now in scm_detach_fds() we
install a new
fd for process B pointing to the same sock (file's private_data) and
above commits
update the cached socket cgroup data for net_cls/net_prio to the new
process B.
So, if process A for example still sends data over that socket, skbs
will then
wrongly match on B's cgroup membership instead of A's, no?
I can't remember the details right now (need to read up again but I wont
have time till Wednesday).
From your analysis I would say that is not the desired effect. A should
match against its own cgroup and not the one of B.
We don't have a good answer for resources which are shared across
different cgroups. It is often too expensive to track such sharing
accurately and crude approximation (creator-owned, last-used or
whatever) is used widely even outside cgroup. Different cgroup
controllers tried different approaches but most are settling down for
creator ownership with exceptions for high impact cases.
I don't think there's a solution which satifies all cases here. Given
that, doing the minimum amount of work (not worrying about SCM_RIGHTS
transfers) is the right thing to do, but we've had this re-labeling
since 2012, so leaving as-is is likely the best option at this point.
Thanks.
--
tejun