OpenVZ Forum


Home » Mailing lists » Devel » [PATCH 19/20] Changes to show virtual ids to user
[PATCH 19/20] Changes to show virtual ids to user [message #15734] Fri, 10 August 2007 11:48 Go to next message
Pavel Emelianov is currently offline  Pavel Emelianov
Messages: 1149
Registered: September 2006
Senior Member
This is the largest patch in the set. Make all (I hope) the places where
the pid is shown to or get from user operate on the virtual pids.

The idea is:
 - all in-kernel data structures must store either struct pid itself
   or the pid's global nr, obtained with pid_nr() call;
 - when seeking the task from kernel code with the stored id one
   should use find_task_by_pid() call that works with global pids;
 - when showing pid's numerical value to the user the virtual one
   should be used, but however when one shows task's pid outside this
   task's namespace the global one is to be used;
 - when getting the pid from userspace one need to consider this as
   the virtual one and use appropriate task/pid-searching functions.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Cc: Oleg Nesterov <oleg@tv-sign.ru>

---

 arch/ia64/kernel/signal.c         |    4 +-
 arch/parisc/kernel/signal.c       |    2 -
 arch/sparc/kernel/sys_sunos.c     |    2 -
 arch/sparc64/kernel/sys_sunos32.c |    2 -
 drivers/char/tty_io.c             |    7 ++---
 fs/binfmt_elf.c                   |   16 +++++------
 fs/binfmt_elf_fdpic.c             |   16 +++++------
 fs/exec.c                         |    4 +-
 fs/fcntl.c                        |    5 ++-
 fs/ioprio.c                       |    5 ++-
 fs/proc/array.c                   |   27 +++++++++++++------
 fs/proc/base.c                    |   37 ++++++++++++++++-----------
 include/net/scm.h                 |    4 ++
 ipc/mqueue.c                      |    7 +++--
 ipc/msg.c                         |    6 ++--
 ipc/sem.c                         |    8 ++---
 ipc/shm.c                         |    6 ++--
 kernel/capability.c               |   14 +++++-----
 kernel/exit.c                     |   31 ++++++++++++++--------
 kernel/futex.c                    |   20 ++++++++------
 kernel/ptrace.c                   |    4 ++
 kernel/sched.c                    |    3 +-
 kernel/signal.c                   |   52 ++++++++++++++++++++++++++++----------
 kernel/sys.c                      |   42 ++++++++++++++++++------------
 kernel/sysctl.c                   |    2 -
 kernel/timer.c                    |    7 ++---
 net/core/scm.c                    |    4 ++
 net/unix/af_unix.c                |    6 ++--
 28 files changed, 212 insertions(+), 131 deletions(-)

--- ./arch/ia64/kernel/signal.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./arch/ia64/kernel/signal.c	2007-08-10 12:43:21.000000000 +0400
@@ -227,7 +227,7 @@ ia64_rt_sigreturn (struct sigscratch *sc
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = SI_KERNEL;
-	si.si_pid = current->pid;
+	si.si_pid = task_pid_vnr(current);
 	si.si_uid = current->uid;
 	si.si_addr = sc;
 	force_sig_info(SIGSEGV, &si, current);
@@ -332,7 +332,7 @@ force_sigsegv_info (int sig, void __user
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = SI_KERNEL;
-	si.si_pid = current->pid;
+	si.si_pid = task_pid_vnr(current);
 	si.si_uid = current->uid;
 	si.si_addr = addr;
 	force_sig_info(SIGSEGV, &si, current);
--- ./arch/parisc/kernel/signal.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./arch/parisc/kernel/signal.c	2007-08-10 12:43:21.000000000 +0400
@@ -181,7 +181,7 @@ give_sigsegv:
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = SI_KERNEL;
-	si.si_pid = current->pid;
+	si.si_pid = task_pid_vnr(current);
 	si.si_uid = current->uid;
 	si.si_addr = &frame->uc;
 	force_sig_info(SIGSEGV, &si, current);
--- ./arch/sparc/kernel/sys_sunos.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./arch/sparc/kernel/sys_sunos.c	2007-08-10 12:43:21.000000000 +0400
@@ -866,7 +866,7 @@ asmlinkage int sunos_killpg(int pgrp, in
 	rcu_read_lock();
 	ret = -EINVAL;
 	if (pgrp > 0)
-		ret = kill_pgrp(find_pid(pgrp), sig, 0);
+		ret = kill_pgrp(find_vpid(pgrp), sig, 0);
 	rcu_read_unlock();
 
 	return ret;
--- ./arch/sparc64/kernel/sys_sunos32.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./arch/sparc64/kernel/sys_sunos32.c	2007-08-10 12:43:21.000000000 +0400
@@ -831,7 +831,7 @@ asmlinkage int sunos_killpg(int pgrp, in
 	rcu_read_lock();
 	ret = -EINVAL;
 	if (pgrp > 0)
-		ret = kill_pgrp(find_pid(pgrp), sig, 0);
+		ret = kill_pgrp(find_vpid(pgrp), sig, 0);
 	rcu_read_unlock();
 
 	return ret;
--- ./drivers/char/tty_io.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./drivers/char/tty_io.c	2007-08-10 12:43:21.000000000 +0400
@@ -103,6 +103,7 @@
 #include <linux/selection.h>
 
 #include <linux/kmod.h>
+#include <linux/nsproxy.h>
 
 #undef TTY_DEBUG_HANGUP
 
@@ -3109,7 +3110,7 @@ static int tiocgpgrp(struct tty_struct *
 	 */
 	if (tty == real_tty && current->signal->tty != real_tty)
 		return -ENOTTY;
-	return put_user(pid_nr(real_tty->pgrp), p);
+	return put_user(pid_vnr(real_tty->pgrp), p);
 }
 
 /**
@@ -3143,7 +3144,7 @@ static int tiocspgrp(struct tty_struct *
 	if (pgrp_nr < 0)
 		return -EINVAL;
 	rcu_read_lock();
-	pgrp = find_pid(pgrp_nr);
+	pgrp = find_vpid(pgrp_nr);
 	retval = -ESRCH;
 	if (!pgrp)
 		goto out_unlock;
@@ -3180,7 +3181,7 @@ static int tiocgsid(struct tty_struct *t
 		return -ENOTTY;
 	if (!real_tty->session)
 		return -ENOTTY;
-	return put_user(pid_nr(real_tty->session), p);
+	return put_user(pid_vnr(real_tty->session), p);
 }
 
 /**
--- ./fs/binfmt_elf.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./fs/binfmt_elf.c	2007-08-10 12:43:21.000000000 +0400
@@ -1380,10 +1380,10 @@ static void fill_prstatus(struct elf_prs
 	prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
 	prstatus->pr_sigpend = p->pending.signal.sig[0];
 	prstatus->pr_sighold = p->blocked.sig[0];
-	prstatus->pr_pid = p->pid;
-	prstatus->pr_ppid = p->parent->pid;
-	prstatus->pr_pgrp = task_pgrp_nr(p);
-	prstatus->pr_sid = task_session_nr(p);
+	prstatus->pr_pid = task_pid_vnr(p);
+	prstatus->pr_ppid = task_pid_vnr(p->parent);
+	prstatus->pr_pgrp = task_pgrp_vnr(p);
+	prstatus->pr_sid = task_session_vnr(p);
 	if (thread_group_leader(p)) {
 		/*
 		 * This is the record for the group leader.  Add in the
@@ -1426,10 +1426,10 @@ static int fill_psinfo(struct elf_prpsin
 			psinfo->pr_psargs[i] = ' ';
 	psinfo->pr_psargs[len] = 0;
 
-	psinfo->pr_pid = p->pid;
-	psinfo->pr_ppid = p->parent->pid;
-	psinfo->pr_pgrp = task_pgrp_nr(p);
-	psinfo->pr_sid = task_session_nr(p);
+	psinfo->pr_pid = task_pid_vnr(p);
+	psinfo->pr_ppid = task_pid_vnr(p->parent);
+	psinfo->pr_pgrp = task_pgrp_vnr(p);
+	psinfo->pr_sid = task_session_vnr(p);
 
 	i = p->state ? ffz(~p->state) + 1 : 0;
 	psinfo->pr_state = i;
--- ./fs/binfmt_elf_fdpic.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./fs/binfmt_elf_fdpic.c	2007-08-10 12:43:21.000000000 +0400
@@ -1342,10 +1342,10 @@ static void fill_prstatus(struct elf_prs
 	prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
 	prstatus->pr_sigpend = p->pending.signal.sig[0];
 	prstatus->pr_sighold = p->blocked.sig[0];
-	prstatus->pr_pid = p->pid;
-	prstatus->pr_ppid = p->parent->pid;
-	prstatus->pr_pgrp = task_pgrp_nr(p);
-	prstatus->pr_sid = task_session_nr(p);
+	prstatus->pr_pid = task_pid_vnr(p);
+	prstatus->pr_ppid = task_pid_vnr(p->parent);
+	prstatus->pr_pgrp = task_pgrp_vnr(p);
+	prstatus->pr_sid = task_session_vnr(p);
 	if (thread_group_leader(p)) {
 		/*
 		 * This is the record for the group leader.  Add in the
@@ -1391,10 +1391,10 @@ static int fill_psinfo(struct elf_prpsin
 			psinfo->pr_psargs[i] = ' ';
 	psinfo->pr_psargs[len] = 0;
 
-	psinfo->pr_pid = p->pid;
-	psinfo->pr_ppid = p->parent->pid;
-	psinfo->pr_pgrp = task_pgrp_nr(p);
-	psinfo->pr_sid = task_session_nr(p);
+	psinfo->pr_pid = task_pid_vnr(p);
+	psinfo->pr_ppid = task_pid_vnr(p->parent);
+	psinfo->pr_pgrp = task_pgrp_vnr(p);
+	psinfo->pr_sid = task_session_vnr(p);
 
 	i = p->state ? ffz(~p->state) + 1 : 0;
 	psinfo->pr_state = i;
--- ./fs/exec.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./fs/exec.c	2007-08-10 12:43:21.000000000 +0400
@@ -1463,7 +1463,7 @@ static int format_corename(char *corenam
 			case 'p':
 				pid_in_pattern = 1;
 				rc = snprintf(out_ptr, out_end - out_ptr,
-					      "%d", current->tgid);
+					      "%d", task_tgid_vnr(current));
 				if (rc > out_end - out_ptr)
 					goto out;
 				out_ptr += rc;
@@ -1543,7 +1543,7 @@ static int format_corename(char *corenam
 	if (!ispipe && !pid_in_pattern
             && (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
 		rc = snprintf(out_ptr, out_end - out_ptr,
-			      ".%d", current->tgid);
+			      ".%d", task_tgid_vnr(current));
 		if (rc > out_end - out_ptr)
 			goto out;
 		out_ptr += rc;
--- ./fs/fcntl.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./fs/fcntl.c	2007-08-10 12:43:21.000000000 +0400
@@ -18,6 +18,7 @@
 #include <linux/ptrace.h>
 #include <linux/signal.h>
 #include <linux/rcupdate.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/poll.h>
 #include <asm/siginfo.h>
@@ -289,7 +290,7 @@ int f_setown(struct file *filp, unsigned
 		who = -who;
 	}
 	rcu_read_lock();
-	pid = find_pid(who);
+	pid = find_vpid(who);
 	result = __f_setown(filp, pid, type, force);
 	rcu_read_unlock();
 	return result;
@@ -305,7 +306,7 @@ pid_t f_getown(struct file *filp)
 {
 	pid_t pid;
 	read_lock(&filp->f_owner.lock);
-	pid = pid_nr(filp->f_owner.pid);
+	pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns);
 	if (filp->f_owner.pid_type == PIDTYPE_PGID)
 		pid = -pid;
 	read_unlock(&filp->f_owner.lock);
--- ./fs/ioprio.c.ve18	2007-08-10 12:40:59.000000000 +0400
+++ ./fs/ioprio.c	2007-08-10 12:43:21.000000000 +0400
@@ -25,6 +25,7 @@
 #include <linux/capability.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
+
...

Re: [PATCH 19/20] Changes to show virtual ids to user [message #15828 is a reply to message #15734] Tue, 14 August 2007 20:12 Go to previous messageGo to next message
Andrew Morton is currently offline  Andrew Morton
Messages: 127
Registered: December 2005
Senior Member
On Fri, 10 Aug 2007 15:48:28 +0400
xemul@openvz.org wrote:

> This is the largest patch in the set. Make all (I hope) the places where
> the pid is shown to or get from user operate on the virtual pids.
> 
> The idea is:
>  - all in-kernel data structures must store either struct pid itself
>    or the pid's global nr, obtained with pid_nr() call;
>  - when seeking the task from kernel code with the stored id one
>    should use find_task_by_pid() call that works with global pids;
>  - when showing pid's numerical value to the user the virtual one
>    should be used, but however when one shows task's pid outside this
>    task's namespace the global one is to be used;
>  - when getting the pid from userspace one need to consider this as
>    the virtual one and use appropriate task/pid-searching functions.
> 
> ...
>
> -	si.si_pid = current->pid;
> +	si.si_pid = task_pid_vnr(current);

This is going to be an ongoing maintenance problem: people will sneak
new references to current->pid into the tree and nobody will notice.

It'd be best to rename task_struct.pid to something else to catch such
problems and to force people to use the right accessors.  Is that feasible?

Generally this is a tactic which should be used whenever things like this
are virtualised.
Re: [PATCH 19/20] Changes to show virtual ids to user [message #19713 is a reply to message #15828] Thu, 16 August 2007 12:13 Go to previous message
serue is currently offline  serue
Messages: 750
Registered: February 2006
Senior Member
Quoting Andrew Morton (akpm@linux-foundation.org):
> On Fri, 10 Aug 2007 15:48:28 +0400
> xemul@openvz.org wrote:
> 
> > This is the largest patch in the set. Make all (I hope) the places where
> > the pid is shown to or get from user operate on the virtual pids.
> > 
> > The idea is:
> >  - all in-kernel data structures must store either struct pid itself
> >    or the pid's global nr, obtained with pid_nr() call;
> >  - when seeking the task from kernel code with the stored id one
> >    should use find_task_by_pid() call that works with global pids;
> >  - when showing pid's numerical value to the user the virtual one
> >    should be used, but however when one shows task's pid outside this
> >    task's namespace the global one is to be used;
> >  - when getting the pid from userspace one need to consider this as
> >    the virtual one and use appropriate task/pid-searching functions.
> > 
> > ...
> >
> > -	si.si_pid = current->pid;
> > +	si.si_pid = task_pid_vnr(current);
> 
> This is going to be an ongoing maintenance problem: people will sneak
> new references to current->pid into the tree and nobody will notice.
> 
> It'd be best to rename task_struct.pid to something else to catch such
> problems and to force people to use the right accessors.  Is that feasible?

It's certainly feasible, and something we'd previously done for instance
in http://marc.info/?l=linux-kernel&m=113751118609597&w=2

> Generally this is a tactic which should be used whenever things like this
> are virtualised.

Ok, it's a big invasive patchset, but there's no reason we can't do it.

thanks,
-serge
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
Previous Topic: Re: user namespaces config option
Next Topic: [PATCH] Fix check for return value of create_pid_namespace
Goto Forum:
  


Current Time: Fri Jul 18 10:15:57 GMT 2025

Total time taken to generate the page: 0.03123 seconds