diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-05-31 15:31:56 -0300 | 
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-05-31 15:31:56 -0300 | 
| commit | d17ed982e4497070e4575ecd8c5afcfcb7210b8b (patch) | |
| tree | 1524dbccee3c535ab3a8d027a170fe86a7c2935c /kernel/module/main.c | |
| parent | 422db30713ac84080a8c4b3efa9dd560b654ed57 (diff) | |
| parent | c041d33bf7ec731bb71f47e4d45a7aec9e40b1b9 (diff) | |
Merge tag 'perf-tools-fixes-for-v6.4-2-2023-05-30' into perf-tools-next
perf tools fixes for v6.4: 2nd batch
- Fix BPF CO-RE naming convention for checking the availability of fields on
  'union perf_mem_data_src' on the running kernel.
- Remove the use of llvm-strip on BPF skel object files, not needed, fixes a
  build breakage when the llvm package, that contains it in most distros, isn't
  installed.
- Fix tools that use both evsel->{bpf_counter_list,bpf_filters}, removing them from a
  union.
- Remove extra "--" from the 'perf ftrace latency' --use-nsec option,
  previously it was working only when using the '-n' alternative.
- Don't stop building when both binutils-devel and a C++ compiler isn't
  available to compile the alternative C++ demangle support code, disable that
  feature instead.
- Sync the linux/in.h and coresight-pmu.h header copies with the kernel sources.
- Fix relative include path to cs-etm.h.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'kernel/module/main.c')
| -rw-r--r-- | kernel/module/main.c | 58 | 
1 files changed, 43 insertions, 15 deletions
diff --git a/kernel/module/main.c b/kernel/module/main.c index 044aa2c9e3cb..b4c7e925fdb0 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -3057,25 +3057,13 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,  	return load_module(&info, uargs, 0);  } -SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) +static int file_init_module(struct file *file, const char __user * uargs, int flags)  {  	struct load_info info = { };  	void *buf = NULL;  	int len; -	int err; - -	err = may_init_module(); -	if (err) -		return err; - -	pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags); -	if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS -		      |MODULE_INIT_IGNORE_VERMAGIC -		      |MODULE_INIT_COMPRESSED_FILE)) -		return -EINVAL; - -	len = kernel_read_file_from_fd(fd, 0, &buf, INT_MAX, NULL, +	len = kernel_read_file(file, 0, &buf, INT_MAX, NULL,  				       READING_MODULE);  	if (len < 0) {  		mod_stat_inc(&failed_kreads); @@ -3084,7 +3072,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)  	}  	if (flags & MODULE_INIT_COMPRESSED_FILE) { -		err = module_decompress(&info, buf, len); +		int err = module_decompress(&info, buf, len);  		vfree(buf); /* compressed data is no longer needed */  		if (err) {  			mod_stat_inc(&failed_decompress); @@ -3099,6 +3087,46 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)  	return load_module(&info, uargs, flags);  } +/* + * kernel_read_file() will already deny write access, but module + * loading wants _exclusive_ access to the file, so we do that + * here, along with basic sanity checks. + */ +static int prepare_file_for_module_load(struct file *file) +{ +	if (!file || !(file->f_mode & FMODE_READ)) +		return -EBADF; +	if (!S_ISREG(file_inode(file)->i_mode)) +		return -EINVAL; +	return exclusive_deny_write_access(file); +} + +SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) +{ +	struct fd f; +	int err; + +	err = may_init_module(); +	if (err) +		return err; + +	pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags); + +	if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS +		      |MODULE_INIT_IGNORE_VERMAGIC +		      |MODULE_INIT_COMPRESSED_FILE)) +		return -EINVAL; + +	f = fdget(fd); +	err = prepare_file_for_module_load(f.file); +	if (!err) { +		err = file_init_module(f.file, uargs, flags); +		allow_write_access(f.file); +	} +	fdput(f); +	return err; +} +  /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */  char *module_flags(struct module *mod, char *buf, bool show_state)  {  | 
