mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge remote-tracking branch 'sm8350/lineage-20' into lineage-23.0
* sm8350/lineage-20: (841 commits)
UPSTREAM: fs: prevent out-of-bounds array speculation when closing a file descriptor
UPSTREAM: file: let pick_file() tell caller it's done
BACKPORT: rcu-tasks: Add a grace-period start time for throttling and debug
BACKPORT: maccess: rename probe_user_{read,write} to copy_{from,to}_user_nofault
BACKPORT: powerpc: use probe_user_read() and probe_user_write()
BACKPORT: maccess: rename probe_kernel_address to get_kernel_nofault
BACKPORT: tracing/kprobes: handle mixed kernel/userspace probes better
BACKPORT: maccess: rename probe_kernel_{read,write} to copy_{from,to}_kernel_nofault
UPSTREAM: maccess: unexport probe_kernel_write()
UPSTREAM: maccess: return -ERANGE when probe_kernel_read() fails
UPSTREAM: maccess: allow architectures to provide kernel probing directly
BACKPORT: maccess: remove strncpy_from_unsafe
UPSTREAM: bpf:bpf_seq_printf(): handle potentially unsafe format string better
UPSTREAM: bpf: Use strncpy_from_unsafe_strict() in bpf_seq_printf() helper
UPSTREAM: bpf: handle the compat string in bpf_trace_copy_string better
UPSTREAM: bpf: factor out a bpf_trace_copy_string helper
BACKPORT: maccess: always use strict semantics for probe_kernel_read
UPSTREAM: maccess: unify the probe kernel arch hooks
UPSTREAM: maccess: remove probe_read_common and probe_write_common
UPSTREAM: maccess: remove duplicate kerneldoc comments
...
Change-Id: I22cf7d6fb34826727904effb4f012b0ef459149d
This commit is contained in:
commit
2eb0f824a1
529 changed files with 40893 additions and 9494 deletions
167
kernel/umh.c
167
kernel/umh.c
|
|
@ -27,8 +27,6 @@
|
|||
#include <linux/ptrace.h>
|
||||
#include <linux/async.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/pipe_fs_i.h>
|
||||
|
||||
#include <trace/events/module.h>
|
||||
|
||||
|
|
@ -39,8 +37,6 @@ static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
|
|||
static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
|
||||
static DEFINE_SPINLOCK(umh_sysctl_lock);
|
||||
static DECLARE_RWSEM(umhelper_sem);
|
||||
static LIST_HEAD(umh_list);
|
||||
static DEFINE_MUTEX(umh_list_lock);
|
||||
|
||||
static void call_usermodehelper_freeinfo(struct subprocess_info *info)
|
||||
{
|
||||
|
|
@ -111,13 +107,10 @@ static int call_usermodehelper_exec_async(void *data)
|
|||
|
||||
commit_creds(new);
|
||||
|
||||
sub_info->pid = task_pid_nr(current);
|
||||
if (sub_info->file) {
|
||||
if (sub_info->file)
|
||||
retval = do_execve_file(sub_info->file,
|
||||
sub_info->argv, sub_info->envp);
|
||||
if (!retval)
|
||||
current->flags |= PF_UMH;
|
||||
} else
|
||||
else
|
||||
retval = do_execve(getname_kernel(sub_info->path),
|
||||
(const char __user *const __user *)sub_info->argv,
|
||||
(const char __user *const __user *)sub_info->envp);
|
||||
|
|
@ -418,140 +411,6 @@ struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv,
|
|||
}
|
||||
EXPORT_SYMBOL(call_usermodehelper_setup);
|
||||
|
||||
struct subprocess_info *call_usermodehelper_setup_file(struct file *file,
|
||||
int (*init)(struct subprocess_info *info, struct cred *new),
|
||||
void (*cleanup)(struct subprocess_info *info), void *data)
|
||||
{
|
||||
struct subprocess_info *sub_info;
|
||||
struct umh_info *info = data;
|
||||
const char *cmdline = (info->cmdline) ? info->cmdline : "usermodehelper";
|
||||
|
||||
sub_info = kzalloc(sizeof(struct subprocess_info), GFP_KERNEL);
|
||||
if (!sub_info)
|
||||
return NULL;
|
||||
|
||||
sub_info->argv = argv_split(GFP_KERNEL, cmdline, NULL);
|
||||
if (!sub_info->argv) {
|
||||
kfree(sub_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_WORK(&sub_info->work, call_usermodehelper_exec_work);
|
||||
sub_info->path = "none";
|
||||
sub_info->file = file;
|
||||
sub_info->init = init;
|
||||
sub_info->cleanup = cleanup;
|
||||
sub_info->data = data;
|
||||
return sub_info;
|
||||
}
|
||||
|
||||
static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
|
||||
{
|
||||
struct umh_info *umh_info = info->data;
|
||||
struct file *from_umh[2];
|
||||
struct file *to_umh[2];
|
||||
int err;
|
||||
|
||||
/* create pipe to send data to umh */
|
||||
err = create_pipe_files(to_umh, 0);
|
||||
if (err)
|
||||
return err;
|
||||
err = replace_fd(0, to_umh[0], 0);
|
||||
fput(to_umh[0]);
|
||||
if (err < 0) {
|
||||
fput(to_umh[1]);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* create pipe to receive data from umh */
|
||||
err = create_pipe_files(from_umh, 0);
|
||||
if (err) {
|
||||
fput(to_umh[1]);
|
||||
replace_fd(0, NULL, 0);
|
||||
return err;
|
||||
}
|
||||
err = replace_fd(1, from_umh[1], 0);
|
||||
fput(from_umh[1]);
|
||||
if (err < 0) {
|
||||
fput(to_umh[1]);
|
||||
replace_fd(0, NULL, 0);
|
||||
fput(from_umh[0]);
|
||||
return err;
|
||||
}
|
||||
|
||||
umh_info->pipe_to_umh = to_umh[1];
|
||||
umh_info->pipe_from_umh = from_umh[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void umh_clean_and_save_pid(struct subprocess_info *info)
|
||||
{
|
||||
struct umh_info *umh_info = info->data;
|
||||
|
||||
/* cleanup if umh_pipe_setup() was successful but exec failed */
|
||||
if (info->pid && info->retval) {
|
||||
fput(umh_info->pipe_to_umh);
|
||||
fput(umh_info->pipe_from_umh);
|
||||
}
|
||||
|
||||
argv_free(info->argv);
|
||||
umh_info->pid = info->pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* fork_usermode_blob - fork a blob of bytes as a usermode process
|
||||
* @data: a blob of bytes that can be do_execv-ed as a file
|
||||
* @len: length of the blob
|
||||
* @info: information about usermode process (shouldn't be NULL)
|
||||
*
|
||||
* If info->cmdline is set it will be used as command line for the
|
||||
* user process, else "usermodehelper" is used.
|
||||
*
|
||||
* Returns either negative error or zero which indicates success
|
||||
* in executing a blob of bytes as a usermode process. In such
|
||||
* case 'struct umh_info *info' is populated with two pipes
|
||||
* and a pid 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.
|
||||
*/
|
||||
int fork_usermode_blob(void *data, size_t len, struct umh_info *info)
|
||||
{
|
||||
struct subprocess_info *sub_info;
|
||||
struct file *file;
|
||||
ssize_t written;
|
||||
loff_t pos = 0;
|
||||
int err;
|
||||
|
||||
file = shmem_kernel_file_setup("", len, 0);
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
written = kernel_write(file, data, len, &pos);
|
||||
if (written != len) {
|
||||
err = written;
|
||||
if (err >= 0)
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = -ENOMEM;
|
||||
sub_info = call_usermodehelper_setup_file(file, umh_pipe_setup,
|
||||
umh_clean_and_save_pid, info);
|
||||
if (!sub_info)
|
||||
goto out;
|
||||
|
||||
err = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC);
|
||||
if (!err) {
|
||||
mutex_lock(&umh_list_lock);
|
||||
list_add(&info->list, &umh_list);
|
||||
mutex_unlock(&umh_list_lock);
|
||||
}
|
||||
out:
|
||||
fput(file);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fork_usermode_blob);
|
||||
|
||||
/**
|
||||
* call_usermodehelper_exec - start a usermode application
|
||||
* @sub_info: information about the subprocessa
|
||||
|
|
@ -654,7 +513,7 @@ int call_usermodehelper(const char *path, char **argv, char **envp, int wait)
|
|||
EXPORT_SYMBOL(call_usermodehelper);
|
||||
|
||||
static int proc_cap_handler(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct ctl_table t;
|
||||
unsigned long cap_array[_KERNEL_CAPABILITY_U32S];
|
||||
|
|
@ -713,26 +572,6 @@ static int proc_cap_handler(struct ctl_table *table, int write,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void __exit_umh(struct task_struct *tsk)
|
||||
{
|
||||
struct umh_info *info;
|
||||
pid_t pid = tsk->pid;
|
||||
|
||||
mutex_lock(&umh_list_lock);
|
||||
list_for_each_entry(info, &umh_list, list) {
|
||||
if (info->pid == pid) {
|
||||
list_del(&info->list);
|
||||
mutex_unlock(&umh_list_lock);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&umh_list_lock);
|
||||
return;
|
||||
out:
|
||||
if (info->cleanup)
|
||||
info->cleanup(info);
|
||||
}
|
||||
|
||||
struct ctl_table usermodehelper_table[] = {
|
||||
{
|
||||
.procname = "bset",
|
||||
|
|
|
|||
Loading…
Reference in a new issue