mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 00:21:17 +00:00
Merge branch 'next' into for-linus
This commit is contained in:
commit
434d42cfd0
25 changed files with 205 additions and 64 deletions
100
kernel/kmod.c
100
kernel/kmod.c
|
@ -25,6 +25,7 @@
|
|||
#include <linux/kmod.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fdtable.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
@ -43,6 +44,13 @@ extern int max_threads;
|
|||
|
||||
static struct workqueue_struct *khelper_wq;
|
||||
|
||||
#define CAP_BSET (void *)1
|
||||
#define CAP_PI (void *)2
|
||||
|
||||
static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
|
||||
static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
|
||||
static DEFINE_SPINLOCK(umh_sysctl_lock);
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
|
||||
/*
|
||||
|
@ -132,6 +140,7 @@ EXPORT_SYMBOL(__request_module);
|
|||
static int ____call_usermodehelper(void *data)
|
||||
{
|
||||
struct subprocess_info *sub_info = data;
|
||||
struct cred *new;
|
||||
int retval;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
|
@ -153,6 +162,19 @@ static int ____call_usermodehelper(void *data)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
retval = -ENOMEM;
|
||||
new = prepare_kernel_cred(current);
|
||||
if (!new)
|
||||
goto fail;
|
||||
|
||||
spin_lock(&umh_sysctl_lock);
|
||||
new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset);
|
||||
new->cap_inheritable = cap_intersect(usermodehelper_inheritable,
|
||||
new->cap_inheritable);
|
||||
spin_unlock(&umh_sysctl_lock);
|
||||
|
||||
commit_creds(new);
|
||||
|
||||
retval = kernel_execve(sub_info->path,
|
||||
(const char *const *)sub_info->argv,
|
||||
(const char *const *)sub_info->envp);
|
||||
|
@ -420,6 +442,84 @@ unlock:
|
|||
}
|
||||
EXPORT_SYMBOL(call_usermodehelper_exec);
|
||||
|
||||
static int proc_cap_handler(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct ctl_table t;
|
||||
unsigned long cap_array[_KERNEL_CAPABILITY_U32S];
|
||||
kernel_cap_t new_cap;
|
||||
int err, i;
|
||||
|
||||
if (write && (!capable(CAP_SETPCAP) ||
|
||||
!capable(CAP_SYS_MODULE)))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* convert from the global kernel_cap_t to the ulong array to print to
|
||||
* userspace if this is a read.
|
||||
*/
|
||||
spin_lock(&umh_sysctl_lock);
|
||||
for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) {
|
||||
if (table->data == CAP_BSET)
|
||||
cap_array[i] = usermodehelper_bset.cap[i];
|
||||
else if (table->data == CAP_PI)
|
||||
cap_array[i] = usermodehelper_inheritable.cap[i];
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
spin_unlock(&umh_sysctl_lock);
|
||||
|
||||
t = *table;
|
||||
t.data = &cap_array;
|
||||
|
||||
/*
|
||||
* actually read or write and array of ulongs from userspace. Remember
|
||||
* these are least significant 32 bits first
|
||||
*/
|
||||
err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* convert from the sysctl array of ulongs to the kernel_cap_t
|
||||
* internal representation
|
||||
*/
|
||||
for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++)
|
||||
new_cap.cap[i] = cap_array[i];
|
||||
|
||||
/*
|
||||
* Drop everything not in the new_cap (but don't add things)
|
||||
*/
|
||||
spin_lock(&umh_sysctl_lock);
|
||||
if (write) {
|
||||
if (table->data == CAP_BSET)
|
||||
usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap);
|
||||
if (table->data == CAP_PI)
|
||||
usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap);
|
||||
}
|
||||
spin_unlock(&umh_sysctl_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ctl_table usermodehelper_table[] = {
|
||||
{
|
||||
.procname = "bset",
|
||||
.data = CAP_BSET,
|
||||
.maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long),
|
||||
.mode = 0600,
|
||||
.proc_handler = proc_cap_handler,
|
||||
},
|
||||
{
|
||||
.procname = "inheritable",
|
||||
.data = CAP_PI,
|
||||
.maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long),
|
||||
.mode = 0600,
|
||||
.proc_handler = proc_cap_handler,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
void __init usermodehelper_init(void)
|
||||
{
|
||||
khelper_wq = create_singlethread_workqueue("khelper");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue