Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jun 2005 15:36:13 -0400
From:      John Baldwin <jhb@FreeBSD.org>
To:        freebsd-hackers@freebsd.org
Cc:        Julian Elischer <julian@elischer.org>, Aziz Kezzou <french.linuxian@gmail.com>
Subject:   Re: How to check root powers on a struct proc ?
Message-ID:  <200506171536.14711.jhb@FreeBSD.org>
In-Reply-To: <42B31E65.2090803@elischer.org>
References:  <3727392705061709318b9346f@mail.gmail.com> <372739270506171123a82a450@mail.gmail.com> <42B31E65.2090803@elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Friday 17 June 2005 03:03 pm, Julian Elischer wrote:
> Aziz Kezzou wrote:
> >>Aziz Kezzou wrote:
> >>>Hi all,
> >>>I am trying to check that a process (struct proc) has root powers when
> >>>it calls my KLD system call.
> >>>I know from kern_jail.c that I can use suser() but this function takes
> >>>a struct thread* instead of struct proc* although the credentials
> >>>(struct ucred *p_ucred;) are stored in proc !
> >>
> >>no.. the thread has a credential that it inherrits from the proc.
> >>when a thread changes the credential of the process as a whole, the
> >>other threads in the kernel don't notice until they return from their
> >>syscalls.. in the mean time they continue to use the reference they
> >>hold to the old credential. This is so that a credential doesn;t change
> >> half way through a syscall.  the active credential at entry will be the
> >> active credential for that thread until it completes its time in the
> >> kernel.
> >>
> >>>Is there an esay way to get a struct thread* from a struct proc* ? or
> >>>should I simply use the function:  int suser_cred(struct ucred *cred,
> >>>int flag); with cred = p-> p_ucred
> >>
> >>why get a struct proc?  the thread has a pointer to the cred it is
> >> running under.
> >
> >I probably didn't make myself clear enough.
> >When my KLD system call is called I get a reference on the calling
> >process as "struct proc *p". Now how do I check if the calling process
> >has root powers ?
>
> why do you get a proc*?  Who is giving it to you?
>
>
> there is always a thread and it is always better to pass a thread than a
> proc.
> because you can trivially go from thread to proc but the converse is not
> easy..
> (there may be many threads)
>
> given a thread you can do td->td_proc to find the proc
>
> you can also find the current thread easily with  "curthread"
>
> so the current process is curthread->td_proc

However, td_ucred can only be used from curthread (it's that way to be fast 
for curthread on purpose.)

> >Would the following work  ? :
> >static int ukcoe_register_ud( struct proc *p, struct
> >ukcoe_register_ud_args* arg ) {
> >int error;
> >error = suser_cred(p->p_cred, 0);
> >if(error) return error;
> >
> >/* do the actual work*/
> >return 0;
> >}

You need some locks to avoid walking off a wild pointer.  Namely, you need to 
lock the target process.  See the various p_canfoo() functions for some 
examples.  Your code might be something like:

	int error;

	PROC_LOCK(p);
	error = suser_cred(p->p_ucred, 0);
	PROC_UNLOCK(p);
	/*
	 * XXX: Note that the cred is now free to change within that process
	 * now that the lock is dropped.
	 */
	if (error)
		return (error);
	...
	return (0);

-- 
John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org



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