How to check root powers on a struct proc ?
John Baldwin
jhb at FreeBSD.org
Fri Jun 17 19:37:36 GMT 2005
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 at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the freebsd-hackers
mailing list