2010-01-02 13:16:45

by Kevin Qu

[permalink] [raw]
Subject: how to get right euid?

I wrote a kernel module and it create a "file" in /proc.
The "file" permission is set to 644.
When check access permission, I use :

if( op == 4 || (op ==2 && current->euid == 0) )
return 0;

But it does not work on 2.6.29,
so I changed it like below:

if( op & 0x4 || (op & 0x2 && current_euid() == 0) )
return 0;

It works when read from the "file" in /proc,
but when write to it with sudo, like:

sudo echo "some thing" > /proc/my_file

It denied. (But it works when I su to superuser and do so.)

So I checked the current_euid(),
but it returns 1000 (not 0),Why?

Thanks for help.

Rofail Qu


2010-01-02 15:19:31

by Jeff Epler

[permalink] [raw]
Subject: Re: how to get right euid?

On Sat, Jan 02, 2010 at 09:16:42PM +0800, Kevin Qu wrote:
> sudo echo "some thing" > /proc/my_file
>
> It denied. (But it works when I su to superuser and do so.)
>
> So I checked the current_euid(),
> but it returns 1000 (not 0),Why?

This may be due to a misunderstanding of how shell redirects work.
Probably current_euid() is returning exactly the right thing.

When you execute
some command line > somefile
the shell opens somefile for writing and makes it be fd 1 (stdout) using
dup2. Then it execs 'some' with the argument array being
['some', 'command', 'line'].

So consider your sudo: The shell, running as user 1000, opens
'somefile' for writing, then execs 'sudo' which happens to be setuid
root.

Jeff

2010-01-05 16:00:43

by David Howells

[permalink] [raw]
Subject: Re: how to get right euid?


Kevin Qu <[email protected]> wrote:

> I wrote a kernel module and it create a "file" in /proc.
> The "file" permission is set to 644.
> When check access permission, I use :

Check where? In file_operations::open(), in file_operations::write() or in
inode_operations::permission()?

> if( op == 4 || (op ==2 && current->euid == 0) )
> return 0;
>
> But it does not work on 2.6.29,
> so I changed it like below:
>
> if( op & 0x4 || (op & 0x2 && current_euid() == 0) )
> return 0;

What is op? Is "op == N" equivalent to "op & N"? Should N be a symbolic
constant (MAY_READ or MAY_WRITE)?

> It works when read from the "file" in /proc,
> but when write to it with sudo, like:
>
> sudo echo "some thing" > /proc/my_file
>
> It denied. (But it works when I su to superuser and do so.)
>
> So I checked the current_euid(),
> but it returns 1000 (not 0),Why?

As Jeff said, where you're making the check matters.

In the above sudo command, the open() call is done by the shell, under the
EUID of whoever is logged in, whereas the write() call is done by the echo
command as executed by sudo, under the EUID set by sudo.

Note that if you're making the check in write(), the UID that you're checking
should be the one in struct file::f_cred.

David