Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Jan 2009 04:41:02 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Ed Schouten <ed@80386.nl>
Cc:        svn-src-head@FreeBSD.org, Tom Rhodes <trhodes@FreeBSD.org>, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org
Subject:   Re: svn commit: r187607 - head/usr.bin/truss
Message-ID:  <20090126041926.J43097@delplex.bde.org>
In-Reply-To: <20090125162123.GB17198@hoeg.nl>
References:  <200901230058.n0N0wEjY026935@svn.freebsd.org> <20090125162123.GB17198@hoeg.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 25 Jan 2009, Ed Schouten wrote:

> Hello Tom,
>
> * Tom Rhodes <trhodes@FreeBSD.org> wrote:
>> Author: trhodes
>> Date: Fri Jan 23 00:58:14 2009
>> New Revision: 187607
>> URL: http://svn.freebsd.org/changeset/base/187607
>>
>> Log:
>>   Attaching to the init process returns EINVAL,
>>   so give an example that is more likely to work.
>>   Stolen from the ktrace(1) manual page.
>>
>>   PR:		128222
>>   Submitted by:	Mateusz Guzik <mjguzik@gmail.com>
>>
>> Modified:
>>   head/usr.bin/truss/truss.1
>
> Isn't that a bug in ptrace(2), instead of a documentation bug?

I think it is the longstanding kernel bug in permissions checking
generally, that the init process and some other non-kernel processes
are bogusly marked as P_SYSTEM.  I use the following fix (this may
be incomplete):

% Index: init_main.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/kern/init_main.c,v
% retrieving revision 1.243
% diff -u -2 -r1.243 init_main.c
% --- init_main.c	16 Jun 2004 00:26:29 -0000	1.243
% +++ init_main.c	16 Jun 2004 05:56:22 -0000
% @@ -697,8 +686,8 @@
%  		panic("cannot fork init: %d\n", error);
%  	KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
% -	/* divorce init's credentials from the kernel's */
% +
% +	/* Divorce init's credentials from the kernel's. */
%  	newcred = crget();
%  	PROC_LOCK(initproc);
% -	initproc->p_flag |= P_SYSTEM;
%  	oldcred = initproc->p_ucred;
%  	crcopy(newcred, oldcred);
% @@ -710,7 +699,5 @@
%  	crfree(oldcred);
%  	cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
% -	mtx_lock_spin(&sched_lock);
% -	initproc->p_sflag |= PS_INMEM;
% -	mtx_unlock_spin(&sched_lock);
% +
%  	cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
%  }
% Index: kern_sig.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v
% retrieving revision 1.281
% diff -u -2 -r1.281 kern_sig.c
% --- kern_sig.c	11 Jun 2004 11:16:23 -0000	1.281
% +++ kern_sig.c	15 Feb 2005 08:40:46 -0000
% @@ -1312,5 +1307,5 @@
%  		LIST_FOREACH(p, &allproc, p_list) {
%  			PROC_LOCK(p);
% -			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
% +			if (p == initproc || p->p_flag & P_SYSTEM ||
%  			    p == td->td_proc) {
%  				PROC_UNLOCK(p);
% @@ -1343,5 +1338,5 @@
%  		LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
%  			PROC_LOCK(p); 
% -			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM) {
% +			if (p == initproc || p->p_flag & P_SYSTEM) {
%  				PROC_UNLOCK(p);
%  				continue;
% @@ -2127,5 +2170,5 @@
%  			 * Don't take default actions on system processes.
%  			 */
% -			if (p->p_pid <= 1) {
% +			if (p == initproc || p->p_flag & P_SYSTEM) {
%  #ifdef DIAGNOSTIC
%  				/*
% Index: vm_pageout.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/vm/vm_pageout.c,v
% retrieving revision 1.258
% diff -u -2 -r1.258 vm_pageout.c
% --- vm_pageout.c	24 Jun 2004 04:08:43 -0000	1.258
% +++ vm_pageout.c	10 Nov 2007 10:22:50 -0000
% @@ -1168,6 +1174,7 @@
%  			/*
%  			 * If this is a system or protected process, skip it.
% +			 * XXX style bugs, bogus 48.
%  			 */
% -			if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) ||
% +			if ((p->p_flag & P_SYSTEM) || (p == initproc) ||
%  			    (p->p_flag & P_PROTECTED) ||
%  			    ((p->p_pid < 48) && (swap_pager_avail != 0))) {

In kern_sig.c, this is partly just a style fix, since init was already
not assumed to be P_SYSTEM, but in the last hunk in kern_sig.c it
changes the code to match the comment, which might give stricter
permissions checking.

ktrace works with this fix:

% Script started on Mon Jan 26 04:29:36 2009
% ttyv1:root@besplex:/tmp/q> ktrace -p 1
% ttyv1:root@besplex:/tmp/q> kdump
% ttyv1:root@besplex:/tmp/q> kdump
% ttyv1:root@besplex:/tmp/q> kdump
% ttyv1:root@besplex:/tmp/q> kdump  # after a logout
%      1 init     RET   wait4 645/0x285
%      1 init     CALL  open(0x80a475b,0x2,0)
%      1 init     NAMI  "/var/run/utmp"
%      1 init     RET   open 0
% ...
%      1 init     CALL  fork
%      1 init     RET   fork 1987/0x7c3
%      1 init     CALL  gettimeofday(0xbfbfedc8,0)
%      1 init     RET   gettimeofday 0
%      1 init     CALL  wait4(0xffffffff,0,0,0)
% ttyv1:root@besplex:/tmp/q> exit
% 
% Script done on Mon Jan 26 04:30:37 2009

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090126041926.J43097>