How to find the real uid/gid of a process?

Jim Reid jim at cs.strath.ac.uk
Thu Jun 6 00:17:00 AEST 1991


In article <2884 at brchh104.bnr.ca> chris at bilby.cs.uwa.oz.au (chris mcdonald) writes:

   Me again, still trying to understand the SunOS kvm_* routines.

   I would like to determine the real uid and gid of each process, but can't
   seem to access them from each struct proc returned by kvm_nextproc();

   Assuming:
	       struct proc theproc;

   when I attempt to access theproc->p_cred I get a Memory Fault, and when I
   access it as root I get a Segv.  I see in <sys/ucred.h> there are some
   nice functions, such as crget(), but that these are only accessible in the
   kernel.

   Is there any way to get real uids and gids from the proc or user structs?

Yes. The address pointed at by proc->p_cred is a kernel virtual
address. It is therefore a mistake to dereference this pointer unless
a process is in the kernel (which yours isn't). You need to use
kvm_read() to fish out this data from the kernel:

	#include <sys/types.h>
	#include <sys/proc.h>
	#include <sys/ucred.h>
	#include <kvm.h>

	struct proc *pp;
	struct ucred mycred;
	kvm_t *kd;

	kd = kvm_open(......);
	pp = kvm_getproc(kd, XXX);
	kvm_read(kd, pp->p_cred, &mycred, sizeof(struct ucred));
	/*
	 * if this completes sucessfully, "mycred" contains a
	 * copy of process no. XXX's credential structure
	 */

   Unfortunately Leffler is no help on this.

Considering that SunOS != 4.3 BSD, this is hardly surprising. 

   While you're here, why are the cred #defines actually in
   <sys/user.h> and not <sys/proc.h> ?

This is for reasons of backwards compatibility. In the old days, the
per-process area (struct user) contained the uid and gid information
about a process. In some versions of UNIX, it still does. Sun
introduced a cred structure to hold this information some time ago. In
earlier SunOS releases, each process had its own credentials structure
stored inside its per-process user area. Now Sun have removed this
structure from the per-process user area, adding a pointer to a
credentials structure to the proc structure. [This is so that several
processes belonging to the same user can share the same credentials
structure.]

Now lots of kernel code was written with the old assumption that the
per-process user area still holds uid/gid information.

	if (u.u_uid == 0)
		/* current process is root */
	else
		/* it isn't */

That code is still in use at many sites - in fact it sometimes helps
"portability" of a device driver since modern UNIX installations will
provide #defines to convert canonical code like that to whatever is
appropriate for the actual kernel. [In other words, hide gory
implementation and/or version specific details.]

The #defines in <sys/user.h> are there to stop old code like this from
breaking: i.e. u.u_uid gets munged by the C preprocessor to
u.u_procp->p_cred->cr_uid which is where the process a ID is now
located in SunOS.

		Jim




More information about the Comp.sys.sun mailing list