[RHEL8,COMMIT] ve: Replace 0 ppid with 1 (workaround for bad utils)

Submitted by Konstantin Khorenko on Oct. 20, 2020, 9:42 a.m.

Details

Message ID 202010200942.09K9g0Kg2632306@finist-co8.sw.ru
State New
Series "ve: Replace 0 ppid with 1 (workaround for bad utils)"
Headers show

Commit Message

Konstantin Khorenko Oct. 20, 2020, 9:42 a.m.
The commit is pushed to "branch-rh8-4.18.0-193.6.3.vz8.4.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-193.6.3.vz8.4.14
------>
commit da0ca84b27c10b14c98322124a73c24088302f73
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Tue Nov 28 13:46:43 2017 +0300

    ve: Replace 0 ppid with 1 (workaround for bad utils)
    
    Extracted from "Initial patch".
    
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    
    (cherry picked from vz7 commit 762f3e6a33f389a9bf8cfbd05278ce587520ca94)
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
    
    vz8 rebase notes:
    * use proper pidns in sys_getppid() - not children's one as in
      original vz7 patch
---
 fs/proc/array.c     |  5 ++---
 include/linux/pid.h |  1 +
 kernel/pid.c        | 12 ++++++++++++
 kernel/sys.c        |  2 +-
 4 files changed, 16 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/proc/array.c b/fs/proc/array.c
index e9b6e403858a..5e7152d21a9d 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -173,8 +173,7 @@  static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	unsigned int max_fds = 0;
 
 	rcu_read_lock();
-	ppid = pid_alive(p) ?
-		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
+	ppid = pid_alive(p) ? ve_task_ppid_nr_ns(p, ns) : 0;
 
 	tracer = ptrace_parent(p);
 	if (tracer)
@@ -522,7 +521,7 @@  static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 		}
 
 		sid = task_session_nr_ns(task, ns);
-		ppid = task_tgid_nr_ns(task->real_parent, ns);
+		ppid = ve_task_ppid_nr_ns(task, ns);
 		pgid = task_pgrp_nr_ns(task, ns);
 
 		unlock_task_sighand(task, &flags);
diff --git a/include/linux/pid.h b/include/linux/pid.h
index d2050f8fbe59..23b71c7882a8 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -176,6 +176,7 @@  static inline pid_t pid_nr(struct pid *pid)
 
 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
 pid_t pid_vnr(struct pid *pid);
+pid_t ve_task_ppid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
 
 #define do_each_pid_task(pid, type, task)				\
 	do {								\
diff --git a/kernel/pid.c b/kernel/pid.c
index fedb993a0820..3e4ff08f9536 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -440,6 +440,18 @@  pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
 }
 EXPORT_SYMBOL(__task_pid_nr_ns);
 
+pid_t ve_task_ppid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+	pid_t ppid;
+	rcu_read_lock();
+	ppid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
+	rcu_read_unlock();
+	/* It's dirty hack. Some old utils don't work if ppid is zero*/
+	if (ppid == 0 && ns->child_reaper != tsk)
+		ppid = 1;
+	return ppid;
+}
+
 struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
 {
 	return ns_of_pid(task_pid(tsk));
diff --git a/kernel/sys.c b/kernel/sys.c
index 0b8f9b050114..e7e07ea8d7ef 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -913,7 +913,7 @@  SYSCALL_DEFINE0(getppid)
 	int pid;
 
 	rcu_read_lock();
-	pid = task_tgid_vnr(rcu_dereference(current->real_parent));
+	pid = ve_task_ppid_nr_ns(current, task_active_pid_ns(current));
 	rcu_read_unlock();
 
 	return pid;