set_fs_pwd(current->fs, &umd_info->wd);
umd_info->pipe_to_umh = to_umh[1];
umd_info->pipe_from_umh = from_umh[0];
- umd_info->pid = task_pid_nr(current);
+ umd_info->tgid = get_pid(task_tgid(current));
current->flags |= PF_UMH;
return 0;
}
if (info->retval) {
fput(umd_info->pipe_to_umh);
fput(umd_info->pipe_from_umh);
+ put_pid(umd_info->tgid);
+ umd_info->tgid = NULL;
}
}
*
* Returns either negative error or zero which indicates success in
* executing a usermode driver. In such case 'struct umd_info *info'
- * is populated with two pipes and a pid of the process. The caller is
+ * is populated with two pipes and a tgid of the process. The caller is
* responsible for health check of the user process, killing it via
- * pid, and closing the pipes when user process is no longer needed.
+ * tgid, and closing the pipes when user process is no longer needed.
*/
int fork_usermode_driver(struct umd_info *info)
{
char **argv = NULL;
int err;
+ if (WARN_ON_ONCE(info->tgid))
+ return -EBUSY;
+
err = -ENOMEM;
argv = argv_split(GFP_KERNEL, info->driver_name, NULL);
if (!argv)
void __exit_umh(struct task_struct *tsk)
{
struct umd_info *info;
- pid_t pid = tsk->pid;
+ struct pid *tgid = task_tgid(tsk);
mutex_lock(&umh_list_lock);
list_for_each_entry(info, &umh_list, list) {
- if (info->pid == pid) {
+ if (info->tgid == tgid) {
list_del(&info->list);
mutex_unlock(&umh_list_lock);
goto out;
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)
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);
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) {