From: Jingxian He hejingxian@huawei.com
hulk inclusion category: feature bugzilla: 48159 CVE: N/A
------------------------------
Pid recover method add new member to task_truct, which generates kabi change problem. We use KABI_RESERVE of task_truct, instead of adding new member to task_truct.
Signed-off-by: Jingxian He hejingxian@huawei.com Reviewed-by: Jing Xiangfeng jingxiangfeng@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/char/pin_memory.c | 2 +- include/linux/sched.h | 18 +++++++++++++++--- init/init_task.c | 4 +++- kernel/pid.c | 8 ++++---- 4 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/drivers/char/pin_memory.c b/drivers/char/pin_memory.c index 05fa7cfde03b2..12ae7627bdf0c 100644 --- a/drivers/char/pin_memory.c +++ b/drivers/char/pin_memory.c @@ -164,7 +164,7 @@ static int set_fork_pid(unsigned long arg) goto fault; if (copy_from_user(&pid, buf, sizeof(int))) goto fault; - current->fork_pid = pid; + current->fork_pid_union.fork_pid = pid; return 0; fault: return -EFAULT; diff --git a/include/linux/sched.h b/include/linux/sched.h index e532338aab8e7..b4c6dfe5e1d9d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -596,6 +596,13 @@ struct wake_q_node { struct wake_q_node *next; };
+#ifdef CONFIG_PID_RESERVE +typedef union { + pid_t fork_pid; + unsigned long pid_reserve; +} fork_pid_t; +#endif + struct task_struct { #ifdef CONFIG_THREAD_INFO_IN_TASK /* @@ -1206,9 +1213,6 @@ struct task_struct { /* Used by LSM modules for access restriction: */ void *security; #endif -#ifdef CONFIG_PID_RESERVE - int fork_pid; -#endif
/* * New fields for task_struct should be added above here, so that @@ -1227,7 +1231,15 @@ struct task_struct { KABI_RESERVE(3) KABI_RESERVE(4) #endif +#ifdef CONFIG_PID_RESERVE +#ifndef __GENKSYMS__ + fork_pid_t fork_pid_union; +#else + KABI_RESERVE(5) +#endif +#else KABI_RESERVE(5) +#endif KABI_RESERVE(6) KABI_RESERVE(7) KABI_RESERVE(8) diff --git a/init/init_task.c b/init/init_task.c index dd02e591490ae..57ff82ab98110 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -181,7 +181,9 @@ struct task_struct init_task .security = NULL, #endif #ifdef CONFIG_PID_RESERVE - .fork_pid = 0, + .fork_pid_union = { + .fork_pid = 0, + }, #endif }; EXPORT_SYMBOL(init_task); diff --git a/kernel/pid.c b/kernel/pid.c index d6a8009f96739..5666ce075487d 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -189,7 +189,7 @@ struct pid *alloc_pid(struct pid_namespace *ns) pid_min = RESERVED_PIDS;
#ifdef CONFIG_PID_RESERVE - if (!current->fork_pid) { + if (!current->fork_pid_union.fork_pid) { /* * Store a null pointer so find_pid_ns does not find * a partially initialized PID (see below). @@ -199,9 +199,9 @@ struct pid *alloc_pid(struct pid_namespace *ns) GFP_ATOMIC); } else { /* Try to free the reserved fork_pid, and then use it to alloc pid. */ - free_reserved_pid(&tmp->idr, current->fork_pid); - pid_min = current->fork_pid; - current->fork_pid = 0; + free_reserved_pid(&tmp->idr, current->fork_pid_union.fork_pid); + pid_min = current->fork_pid_union.fork_pid; + current->fork_pid_union.fork_pid = 0; nr = idr_alloc(&tmp->idr, NULL, pid_min, pid_min + 1, GFP_ATOMIC);