Skip to contentSkip to conversation

syscall,pid: Extract bodies of sys_get{pid,ppid}() into do_get{pid,ppid}()

PATCH In review Ben Hutchings 2 participants 4 messages Sep 26, 2010

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 syscall,pid: Extract bodies of sys_get{pid,ppid}() into do_get{pid,ppid}()

Define do_get{pid,ppid}() for all architectures.

Change sys_get{pid,ppid}() to be wrappers for them, except on Alpha. While we're at it, move them to the more obvious kernel/pid.c.

Change all callers accordingly.

---
This is preparation for fixing sys_getxgid() on Alpha.

This applies on top of a previous quick-fix for TOMOYO
<http://article.gmane.org/gmane.linux.kernel.lsm/11708> which I hope to see applied in 2.6.36.

Ben.

 include/linux/pid.h      |    4 ++++
 kernel/auditsc.c         |    4 ++--
 kernel/pid.c             |   45 +++++++++++++++++++++++++++++++++++++++++++++
 kernel/timer.c           |   36 ------------------------------------
 security/tomoyo/common.c |    6 +-----
 5 files changed, 52 insertions(+), 43 deletions(-)
include/linux/pid.h +4 -0
index 49f1c2f..f79d402 100644
@@ -188,4 +188,8 @@ pid_t pid_vnr(struct pid *pid);
 		} while_each_thread(tg___, task);			\
 		task = tg___;						\
 	} while_each_pid_task(pid, type, task)
+
+extern pid_t do_getpid(void);
+extern pid_t do_getppid(void);
+
 #endif /* _LINUX_PID_H */
kernel/auditsc.c +2 -2
index 1b31c13..3c35ace 100644
@@ -461,7 +461,7 @@ static int audit_filter_rules(struct task_struct *tsk,
 		case AUDIT_PPID:
 			if (ctx) {
 				if (!ctx->ppid)
-					ctx->ppid = sys_getppid();
+					ctx->ppid = do_getppid();
 				result = audit_comparator(ctx->ppid, f->op, f->val);
 			}
 			break;
@@ -1320,7 +1320,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
 	/* tsk == current */
 	context->pid = tsk->pid;
 	if (!context->ppid)
-		context->ppid = sys_getppid();
+		context->ppid = do_getppid();
 	cred = current_cred();
 	context->uid   = cred->uid;
 	context->gid   = cred->gid;
kernel/pid.c +45 -0

48 lines not on this page · raw message

kernel/timer.c +0 -36
index 97bf05b..6248883 100644
@@ -1334,42 +1334,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, seconds)
 
 #ifndef __alpha__
 
-/*
- * The Alpha uses getxpid, getxuid, and getxgid instead.  Maybe this
- * should be moved into arch/i386 instead?
- */
-
-/**
- * sys_getpid - return the thread group id of the current process
- *
- * Note, despite the name, this returns the tgid not the pid.  The tgid and
- * the pid are identical unless CLONE_THREAD was specified on clone() in
- * which case the tgid is the same in all threads of the same group.
- *
- * This is SMP safe as current->tgid does not change.
- */
-SYSCALL_DEFINE0(getpid)
-{
-	return task_tgid_vnr(current);
-}
-
-/*
- * Accessing ->real_parent is not SMP-safe, it could
- * change from under us. However, we can use a stale
- * value of ->real_parent under rcu_read_lock(), see
- * release_task()->call_rcu(delayed_put_task_struct).
- */
-SYSCALL_DEFINE0(getppid)
-{
-	int pid;
-
-	rcu_read_lock();
-	pid = task_tgid_vnr(current->real_parent);
-	rcu_read_unlock();
-
-	return pid;
-}
-
 SYSCALL_DEFINE0(getuid)
 {
 	/* Only we change this so SMP safe */
security/tomoyo/common.c +1 -5
index c668b44..97192e1 100644
@@ -1416,19 +1416,15 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r)
 	const pid_t gpid = task_pid_nr(current);
 	static const int tomoyo_buffer_len = 4096;
 	char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
-	pid_t ppid;
 	if (!buffer)
 		return NULL;
 	do_gettimeofday(&tv);
-	rcu_read_lock();
-	ppid = task_tgid_vnr(current->real_parent);
-	rcu_read_unlock();
 	snprintf(buffer, tomoyo_buffer_len - 1,
 		 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
 		 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
 		 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
 		 tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid,
-		 task_tgid_vnr(current), ppid,
+		 do_getpid(), do_getppid(),
 		 current_uid(), current_gid(), current_euid(),
 		 current_egid(), current_suid(), current_sgid(),
 		 current_fsuid(), current_fsgid());
Signature · 1 line
1.7.1
#1 lore raw

PATCH 2/2 alpha: Make sys_getxpid() call do_getppid()

sys_getxpid() was not following RCU protocol or considering namespace visibility for the parent pid. Change it to call do_geptpid() which does the right thing.

---
This is totally untested, and I've never written Alpha assembly before, so this definitely needs review and testing by an Alpha porter.

I've left the shortcut tgid lookup there as I assume it is still valid.

Ben.

 arch/alpha/kernel/entry.S |   21 ++++++---------------
 1 files changed, 6 insertions(+), 15 deletions(-)
arch/alpha/kernel/entry.S +6 -15
index ab1ee0a..5b1bc48 100644
@@ -857,24 +857,15 @@ sys_getxgid:
 	.globl	sys_getxpid
 	.ent	sys_getxpid
 sys_getxpid:
+	lda	$sp, -16($sp)
+	stq	$26, 0($sp)
 	.prologue 0
+	jsr	$26, do_getppid
+	ldq	$26, 0($sp)
+	lda	$sp, 16($sp)
+	stq	$0, 80($sp)
 	ldq	$2, TI_TASK($8)
-
-	/* See linux/kernel/timer.c sys_getppid for discussion
-	   about this loop.  */
-	ldq	$3, TASK_GROUP_LEADER($2)
-	ldq	$4, TASK_REAL_PARENT($3)
 	ldl	$0, TASK_TGID($2)
-1:	ldl	$1, TASK_TGID($4)
-#ifdef CONFIG_SMP
-	mov	$4, $5
-	mb
-	ldq	$3, TASK_GROUP_LEADER($2)
-	ldq	$4, TASK_REAL_PARENT($3)
-	cmpeq	$4, $5, $5
-	beq	$5, 1b
-#endif
-	stq	$1, 80($sp)
 	ret
 .end sys_getxpid
 
Signature · 1 line
1.7.1
#2 lore raw

Re: [PATCH 2/2] alpha: Make sys_getxpid() call do_getppid()

Quoted 10 lines · Ben Hutchings

sys_getxpid() was not following RCU protocol or considering namespace visibility for the parent pid. Change it to call do_geptpid() which does the right thing.

---
This is totally untested, and I've never written Alpha assembly before, so this definitely needs review and testing by an Alpha porter.

I've left the shortcut tgid lookup there as I assume it is still valid.

I think I have a better variant, getting rid of asm magic completely. Basically, in ptrace.h have

#define current_pt_regs() \
        ((struct pt_regs *)(current_thread_info() + 2*PAGE_SIZE) - 1)

(and turn force_successful_syscall_return() into (current_pt_regs()->r0 = 0), while we are at it) and do what I'm doing for e.g. getxgid and alpha_pipe:
SYSCALL_DEFINE0(getxgid)

{
        struct cred *cred = current->cred;
        current_pt_regs()->r20 = cred->egid;
        return cred->gid;
}

SYSCALL_DEFINE0(alpha_pipe)

{
        int fd[2];
        int res = do_pipe_flags(&fd, 0);
        if (!res) {
                /* The return values are in $0 and $20.  */
                current_pt_regs()->r20 = fd[1];
                res = fd[0];
        }
        return res;
}

I planned to hold it back until the merge window, since it's not a bugfix, but with that one... what the hell, might as well do it. Less asm glue is a Good Thing(tm).

One problem with your patch, though:

; git grep do_getppid
;

IOW, which tree is that against?

#3 lore raw

Re: [PATCH 2/2] alpha: Make sys_getxpid() call do_getppid()

On Sun, 2010-09-26 at 23:28 +0100, Al Viro wrote:
[...]

Quoted 10 lines

I planned to hold it back until the merge window, since it's not a bugfix, but with that one... what the hell, might as well do it. Less asm glue is a Good Thing(tm).

One problem with your patch, though:

; git grep do_getppid
;

IOW, which tree is that against?

The previous patch
<http://article.gmane.org/gmane.linux.ports.alpha/1165>, which I don't intend to go into 2.6.36.

Ben.

Signature · 2 lines
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.