summaryrefslogtreecommitdiffstats
path: root/kernel/umh.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/umh.c')
-rw-r--r--kernel/umh.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/kernel/umh.c b/kernel/umh.c
index 0baa672e023c..d937cbad903a 100644
--- a/kernel/umh.c
+++ b/kernel/umh.c
@@ -37,6 +37,8 @@ static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
37static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; 37static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
38static DEFINE_SPINLOCK(umh_sysctl_lock); 38static DEFINE_SPINLOCK(umh_sysctl_lock);
39static DECLARE_RWSEM(umhelper_sem); 39static DECLARE_RWSEM(umhelper_sem);
40static LIST_HEAD(umh_list);
41static DEFINE_MUTEX(umh_list_lock);
40 42
41static void call_usermodehelper_freeinfo(struct subprocess_info *info) 43static void call_usermodehelper_freeinfo(struct subprocess_info *info)
42{ 44{
@@ -100,10 +102,12 @@ static int call_usermodehelper_exec_async(void *data)
100 commit_creds(new); 102 commit_creds(new);
101 103
102 sub_info->pid = task_pid_nr(current); 104 sub_info->pid = task_pid_nr(current);
103 if (sub_info->file) 105 if (sub_info->file) {
104 retval = do_execve_file(sub_info->file, 106 retval = do_execve_file(sub_info->file,
105 sub_info->argv, sub_info->envp); 107 sub_info->argv, sub_info->envp);
106 else 108 if (!retval)
109 current->flags |= PF_UMH;
110 } else
107 retval = do_execve(getname_kernel(sub_info->path), 111 retval = do_execve(getname_kernel(sub_info->path),
108 (const char __user *const __user *)sub_info->argv, 112 (const char __user *const __user *)sub_info->argv,
109 (const char __user *const __user *)sub_info->envp); 113 (const char __user *const __user *)sub_info->envp);
@@ -517,6 +521,11 @@ int fork_usermode_blob(void *data, size_t len, struct umh_info *info)
517 goto out; 521 goto out;
518 522
519 err = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC); 523 err = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC);
524 if (!err) {
525 mutex_lock(&umh_list_lock);
526 list_add(&info->list, &umh_list);
527 mutex_unlock(&umh_list_lock);
528 }
520out: 529out:
521 fput(file); 530 fput(file);
522 return err; 531 return err;
@@ -679,6 +688,26 @@ static int proc_cap_handler(struct ctl_table *table, int write,
679 return 0; 688 return 0;
680} 689}
681 690
691void __exit_umh(struct task_struct *tsk)
692{
693 struct umh_info *info;
694 pid_t pid = tsk->pid;
695
696 mutex_lock(&umh_list_lock);
697 list_for_each_entry(info, &umh_list, list) {
698 if (info->pid == pid) {
699 list_del(&info->list);
700 mutex_unlock(&umh_list_lock);
701 goto out;
702 }
703 }
704 mutex_unlock(&umh_list_lock);
705 return;
706out:
707 if (info->cleanup)
708 info->cleanup(info);
709}
710
682struct ctl_table usermodehelper_table[] = { 711struct ctl_table usermodehelper_table[] = {
683 { 712 {
684 .procname = "bset", 713 .procname = "bset",