summaryrefslogtreecommitdiffstats
path: root/net/bpfilter
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2020-06-25 16:48:26 -0500
committerEric W. Biederman <ebiederm@xmission.com>2020-07-04 09:35:56 -0500
commit1c340ead18ee4b4a84357abdef6d4f39ee08328b (patch)
tree412b58dd03cf04a9fd8cc26caae482628a0fbd71 /net/bpfilter
parent0fe3c63148ef5df1b3cb067e4b4d45d45d0c0fdc (diff)
downloadlinux-1c340ead18ee4b4a84357abdef6d4f39ee08328b.tar.bz2
umd: Track user space drivers with struct pid
Use struct pid instead of user space pid values that are prone to wrap araound. In addition track the entire thread group instead of just the first thread that is started by exec. There are no multi-threaded user mode drivers today but there is nothing preclucing user drivers from being multi-threaded, so it is just a good idea to track the entire process. Take a reference count on the tgid's in question to make it possible to remove exit_umh in a future change. As a struct pid is available directly use kill_pid_info. The prior process signalling code was iffy in using a userspace pid known to be in the initial pid namespace and then looking up it's task in whatever the current pid namespace is. It worked only because kernel threads always run in the initial pid namespace. As the tgid is now refcounted verify the tgid is NULL at the start of fork_usermode_driver to avoid the possibility of silent pid leaks. v1: https://lkml.kernel.org/r/87mu4qdlv2.fsf_-_@x220.int.ebiederm.org v2: https://lkml.kernel.org/r/a70l4oy8.fsf_-_@x220.int.ebiederm.org Link: https://lkml.kernel.org/r/20200702164140.4468-12-ebiederm@xmission.com Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Alexei Starovoitov <ast@kernel.org> Tested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'net/bpfilter')
-rw-r--r--net/bpfilter/bpfilter_kern.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/net/bpfilter/bpfilter_kern.c b/net/bpfilter/bpfilter_kern.c
index 28883b00609d..08ea77c2b137 100644
--- a/net/bpfilter/bpfilter_kern.c
+++ b/net/bpfilter/bpfilter_kern.c
@@ -15,16 +15,13 @@ extern char bpfilter_umh_end;
static void shutdown_umh(void)
{
- struct task_struct *tsk;
+ struct umd_info *info = &bpfilter_ops.info;
+ struct pid *tgid = info->tgid;
if (bpfilter_ops.stop)
return;
- tsk = get_pid_task(find_vpid(bpfilter_ops.info.pid), PIDTYPE_PID);
- if (tsk) {
- send_sig(SIGKILL, tsk, 1);
- put_task_struct(tsk);
- }
+ kill_pid(tgid, SIGKILL, 1);
}
static void __stop_umh(void)
@@ -48,7 +45,7 @@ static int __bpfilter_process_sockopt(struct sock *sk, int optname,
req.cmd = optname;
req.addr = (long __force __user)optval;
req.len = optlen;
- if (!bpfilter_ops.info.pid)
+ if (!bpfilter_ops.info.tgid)
goto out;
n = __kernel_write(bpfilter_ops.info.pipe_to_umh, &req, sizeof(req),
&pos);
@@ -81,7 +78,7 @@ static int start_umh(void)
if (err)
return err;
bpfilter_ops.stop = false;
- pr_info("Loaded bpfilter_umh pid %d\n", bpfilter_ops.info.pid);
+ pr_info("Loaded bpfilter_umh pid %d\n", pid_nr(bpfilter_ops.info.tgid));
/* health check that usermode process started correctly */
if (__bpfilter_process_sockopt(NULL, 0, NULL, 0, 0) != 0) {