aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index d1b2b8d934bb..38509dc1f77b 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2018,7 +2018,11 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
2018 return error; 2018 return error;
2019 } 2019 }
2020 2020
2021 down_write(&mm->mmap_sem); 2021 /*
2022 * arg_lock protects concurent updates but we still need mmap_sem for
2023 * read to exclude races with sys_brk.
2024 */
2025 down_read(&mm->mmap_sem);
2022 2026
2023 /* 2027 /*
2024 * We don't validate if these members are pointing to 2028 * We don't validate if these members are pointing to
@@ -2032,6 +2036,7 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
2032 * to any problem in kernel itself 2036 * to any problem in kernel itself
2033 */ 2037 */
2034 2038
2039 spin_lock(&mm->arg_lock);
2035 mm->start_code = prctl_map.start_code; 2040 mm->start_code = prctl_map.start_code;
2036 mm->end_code = prctl_map.end_code; 2041 mm->end_code = prctl_map.end_code;
2037 mm->start_data = prctl_map.start_data; 2042 mm->start_data = prctl_map.start_data;
@@ -2043,6 +2048,7 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
2043 mm->arg_end = prctl_map.arg_end; 2048 mm->arg_end = prctl_map.arg_end;
2044 mm->env_start = prctl_map.env_start; 2049 mm->env_start = prctl_map.env_start;
2045 mm->env_end = prctl_map.env_end; 2050 mm->env_end = prctl_map.env_end;
2051 spin_unlock(&mm->arg_lock);
2046 2052
2047 /* 2053 /*
2048 * Note this update of @saved_auxv is lockless thus 2054 * Note this update of @saved_auxv is lockless thus
@@ -2055,7 +2061,7 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
2055 if (prctl_map.auxv_size) 2061 if (prctl_map.auxv_size)
2056 memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv)); 2062 memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
2057 2063
2058 up_write(&mm->mmap_sem); 2064 up_read(&mm->mmap_sem);
2059 return 0; 2065 return 0;
2060} 2066}
2061#endif /* CONFIG_CHECKPOINT_RESTORE */ 2067#endif /* CONFIG_CHECKPOINT_RESTORE */