actual sys_indirect code
PATCH v5 1/5 actual sys_indirect code
This is the actual architecture-independent part of the system call implementation.
include/linux/indirect.h | 17 +++++++++++++++++ include/linux/sched.h | 4 ++++ include/linux/syscalls.h | 4 ++++ kernel/Makefile | 3 +++ kernel/indirect.c | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+)
include/linux/indirect.h +17 -0
@@ -0,0 +1,17 @@ +#ifndef _LINUX_INDIRECT_H +#define _LINUX_INDIRECT_H + +#include <asm/indirect.h> + + +/* IMPORTANT: +All the elements of this union must be neutral to the word size +and must not require reworking when used in compat syscalls. Used +fixed-size types or types which are known to not vary in size across +architectures. */ +union indirect_params { +}; + +#define INDIRECT_PARAM (set, name) current->indirect_params.set.name + +#endif
kernel/Makefile +3 -0
@@ -57,6 +57,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o obj-$(CONFIG_MARKERS) += marker.o +obj-$(CONFIG_ARCH_HAS_INDIRECT_SYSCALLS) += indirect.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
@@ -67,6 +68,8 @@ CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer endif +CFLAGS_indirect.o = -Wno-undef + $(obj)/configs.o: $(obj)/config_data.h # config_data.h contains the same information as ikconfig.h but gzipped.
kernel/indirect.c +40 -0
@@ -0,0 +1,40 @@ +#include <linux/sched.h> +#include <linux/uaccess.h> +#include <linux/unistd.h> +#include <asm/asm-offsets.h> + + +asmlinkage long sys_indirect (struct indirect_registers __user *userregs, +void __user *userparams,size_t paramslen, +int flags) +{ +struct indirect_registers regs; +long result; + +if (unlikely (flags !=0 )) +return -EINVAL ; + +if (copy_from_user (®s, userregs,sizeof (regs))) +return -EFAULT ; + +switch (INDIRECT_SYSCALL (®s)) + { +#define INDSYSCALL (name) __NR_##name +#include <linux/indirect.h> +break ; + +default : +return -EINVAL ; + } + +if (paramslen >sizeof (union indirect_params )) +return -EINVAL ; + + result = -EFAULT ; +if (!copy_from_user (¤t->indirect_params, userparams, paramslen)) + result =call_indirect (®s); + +memset (¤t->indirect_params,'\0' , paramslen); + +return result; +}
include/linux/syscalls.h +4 -0
@@ -54,6 +54,7 @@struct compat_timeval ;struct robust_list_head ;struct getcpu_cache ; +struct indirect_registers ;#include <linux/types.h> #include <linux/aio_abi.h>
@@ -611,6 +612,9 @@ const struct itimerspec __user *utmr);asmlinkage long sys_eventfd (unsigned int count);asmlinkage long sys_fallocate (int fd,int mode,loff_t offset,loff_t len); +asmlinkage long sys_indirect (struct indirect_registers __user *userregs, +void __user *userparams,size_t paramslen, +int flags);int kernel_execve (const char *filename,char *const argv[],char *const envp[]);
include/linux/sched.h +4 -0
@@ -80,6 +80,7 @@ struct sched_param {#include <linux/rcupdate.h> #include <linux/futex.h> #include <linux/rtmutex.h> +#include <linux/indirect.h> #include <linux/time.h> #include <linux/param.h>
@@ -1174,6 +1175,9 @@ struct task_struct {int make_it_fail;#endif struct prop_local_single dirties; + +/* Additional system call parameters. */ +union indirect_params indirect_params; };/*