Re: access() system call

CyberPeasant (listread@bedford.net)
Mon, 9 Feb 1998 00:52:12 -0500 (EST)


[ Followups to linux-c-programming@tower.itis.com, please ]

> Hello, All !
>
> I found strange behavior for access() system call :

It's strange, but is not a bug; see below:

> compiling and executing this program
>
> ------------------
> #include <stdio.h>
> #include <unistd.h>
>
> void main(void)
> {
> setreuid(1224,0);
> printf("reuid=%d,euid=%d\n",getuid(),geteuid());
> if ((access("/vmlinuz",R_OK | W_OK))<0)
> perror("access");
> if ((chmod("/dev/ttyS0",0600))<0)
> perror("chmod");
> setreuid(0,1224);
> printf("reuid=%d,euid=%d\n",getuid(),geteuid());
> if ((access("/vmlinuz",R_OK | W_OK))<0)
> perror("access");
> if ((chmod("/dev/ttyS0",0600))<0)
> perror("chmod");
>
> }
> ------------------
>
> gives following results :
>
> ------------------
>
> [root@unicorn]/home/vps/c# ./tuid
> reuid=1224,euid=0
> access: Permission denied
> reuid=0,euid=1224
> chmod: Operation not permitted
> [root@unicorn]/home/vps/c# ls -la /vmlinuz
> -rw-r--r-- 1 root root 374386 Jan 24 01:29 /vmlinuz
> [root@unicorn]/home/vps/c# ls -ls /dev/ttyS1
> 0 crw------- 1 uucp uucp 4, 65 Feb 8 22:37 /dev/ttyS1
> [root@unicorn]/home/vps/c#
>
> ------------------
>
> How can I read/write /vmlinuz but can't chmod() (I am not root) and why can
> I chmod() but can't access r/w /vmlinux ( I am real root at this )
>
> Any suggestions ?
>

Zero, I assume that uid(uucp) != 1224.

First, the chmod(2) behavior is correct, so the question is only about
access(2). The relevant comment from man 2 access is:

The check is done with the process's real uid and gid,
rather than with the effective ids as is done when actu-
ally attempting an operation. This is to allow set-UID
programs to easily determine the invoking user's author-
ity.

> setreuid(1224,0);
> printf("reuid=%d,euid=%d\n",getuid(),geteuid());
> if ((access("/vmlinuz",R_OK | W_OK))<0)

At the time of the first access call, the real uid is 1224, so the W_OK part
is untrue and access fails with EPERM. The first chmod call succeeds because
euid == 0.

At the time of the second access call, the real uid is 0, so it succeeds.
The effective uid is 1224 (!=0 && != uid(uucp)), so chmod fails.

If you need to check permissions relevant to the EUID, then use stat(2),
or fstat(2) if the file is already open.

stat(2) is not so convenient as access(2); so I will write a (probably
brain-damaged) routine named eaccess(), that will mimic access(2), but
use the euid. That will occur in maybe four or five hours, on linux-c-
programming only. It may be as simple as a setreuid(2) call within the
new function, but I need to check this out, lest I find my foot lodged
in my mouth again.

Dave

-- 
	"Bugs! Bugs! They're EVERYWHERE!"  Was this uttered by 
		( ) a programmer in the last week of a contract,
		( ) an alcoholic in the third day of withdrawal?
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu