From cba263ff122321ee2af13956720a7fa824bb7549 Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Sun, 7 Mar 2021 17:31:47 +0900 Subject: [PATCH] mcexec_open_exec: guard fput and add to mckernel_exec_files with spin_lock_irqsave Change-Id: Id5dae8cb7f947d4e9939bf9c6762c2d1dcdd3776 --- executer/kernel/mcctrl/control.c | 49 ++++++++++++++------------------ 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 849b9afb..a84a2a53 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -1799,8 +1799,7 @@ out: } LIST_HEAD(mckernel_exec_files); -DEFINE_SEMAPHORE(mckernel_exec_file_lock); - +static DEFINE_SPINLOCK(mckernel_exec_file_lock); struct mckernel_exec_file { ihk_os_t os; @@ -1977,6 +1976,7 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename) char *fullpath = NULL; char *kfilename = NULL; int len; + unsigned long flags; if (os_ind < 0) { return -EINVAL; @@ -1991,38 +1991,39 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename) kfilename = kmalloc(PATH_MAX, GFP_KERNEL); if (!kfilename) { retval = -ENOMEM; - kfree(pathbuf); goto out; } len = strncpy_from_user(kfilename, filename, PATH_MAX); if (unlikely(len < 0)) { retval = -EINVAL; - goto out_free; + goto out; } - /* fget and list_add should be atomic */ - down(&mckernel_exec_file_lock); + /* fget and list_add should not be interrupted by hardware interrupt */ + spin_lock_irqsave(&mckernel_exec_file_lock, flags); file = open_exec(kfilename); retval = PTR_ERR(file); if (IS_ERR(file)) { - up(&mckernel_exec_file_lock); - goto out_free; + spin_unlock_irqrestore(&mckernel_exec_file_lock, flags); + goto out; } fullpath = d_path(&file->f_path, pathbuf, PATH_MAX); if (IS_ERR(fullpath)) { - up(&mckernel_exec_file_lock); + fput(file); + spin_unlock_irqrestore(&mckernel_exec_file_lock, flags); retval = PTR_ERR(fullpath); - goto out_put_file; + goto out; } mcef = kmalloc(sizeof(*mcef), GFP_KERNEL); if (!mcef) { - up(&mckernel_exec_file_lock); + fput(file); + spin_unlock_irqrestore(&mckernel_exec_file_lock, flags); retval = -ENOMEM; - goto out_put_file; + goto out; } memset(mcef, 0, sizeof(struct mckernel_exec_file)); /* debug */ @@ -2046,22 +2047,15 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename) /* Create /proc/self/exe entry */ add_pid_entry(os_ind, task_tgid_vnr(current)); proc_exe_link(os_ind, task_tgid_vnr(current), fullpath); - up(&mckernel_exec_file_lock); + spin_unlock_irqrestore(&mckernel_exec_file_lock, flags); dprintk("%d open_exec and holding file: %s\n", (int)task_tgid_vnr(current), kfilename); - kfree(kfilename); - kfree(pathbuf); - - return 0; - -out_put_file: - fput(file); -out_free: - kfree(pathbuf); - kfree(kfilename); + retval = 0; out: + kfree(pathbuf); + kfree(kfilename); return retval; } @@ -2069,13 +2063,14 @@ int mcexec_close_exec(ihk_os_t os, int pid) { struct mckernel_exec_file *mcef = NULL; int found = 0; - int os_ind = ihk_host_os_get_index(os); + int os_ind = ihk_host_os_get_index(os); + unsigned long flags; if (os_ind < 0) { return EINVAL; } - - down(&mckernel_exec_file_lock); + + spin_lock_irqsave(&mckernel_exec_file_lock, flags); list_for_each_entry(mcef, &mckernel_exec_files, list) { if (mcef->os == os && mcef->pid == pid) { allow_write_access(mcef->fp); @@ -2088,7 +2083,7 @@ int mcexec_close_exec(ihk_os_t os, int pid) } } - up(&mckernel_exec_file_lock); + spin_unlock_irqrestore(&mckernel_exec_file_lock, flags); return (found ? 0 : EINVAL); }