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
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
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