tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
ksh privileged mode
Hello,
I'm seeing surprising behavior in ksh's privileged
mode versus /bin/sh's privileged mode. Bear with me
for a moment, as I lay my scene:
$ ls -l
-rw-rw---- 1 nobody nogroup 4 May 30 16:43 f
-rwxr-s--- 1 nobody nogroup 8728 May 30 16:43 gids
-rwxr-sr-x 1 nobody nogroup 8272 May 30 16:43 setgidsh
-rwxr-xr-x 1 jschauma wheel 9912 May 30 16:43 showaccess
"gids" is
printf("real : %d %d\n", getuid(), getgid());
printf("effective: %d %d\n", geteuid(), getegid());
"setgidsh" is just wrapper to let me run a shell with
egid != gid:
int main(int argc, char **argv) {
argv++;
execv(argv[0], argv);
perror("execl");
}
"showaccess" just prints what access(2) and
faccessat(2) say about the argument.
So now:
$ ./setgidsh /bin/sh
$ id
uid=1000(jschauma) gid=100(users) groups=100(users),0(wheel)
$ ./gids
sh: ./gids: permission denied
$
This is expected: /bin/sh resets e[gu]id if they don't
match at startup, unless '-p' is specified:
$ ./setgidsh /bin/sh -p
$ id
uid=1000(jschauma) gid=100(users) egid=32766(nogroup) groups=100(users),0(wheel)
$ ./gids
real : 1000 100
effective: 1000 32766
$
Ok, so far, so good.
csh flat out refuses to start if egid != gid unless
you pass the "-b" flag to enter "batch" mode:
$ ./setgidsh /bin/csh
csh: Permission denied.
$ ./setgidsh /bin/csh -b
% id
uid=1000(jschauma) gid=100(users) egid=32766(nogroup) groups=100(users),0(wheel)
% ./gids
real : 1000 100
effective: 1000 32766
Seems an odd choice for the flag, but ok.
So now with ksh:
$ ./setgidsh /bin/ksh
$ id
uid=1000(jschauma) gid=100(users) egid=32766(nogroup) groups=100(users),0(wheel)
$ cat f
foo
$ ./gids
/bin/ksh: ./gids: cannot execute - Permission denied
Here, ksh at startup determines that egid != gid and
so becomes "privileged". That's the same as if I had
invoked "/bin/ksh -p", but it seems that even though I
can use my egid for read/write access, I have no way
of allowing ksh to honor egid for execution: clearing
the "privileged" option resets my egid to my real
gid.
ksh uses access(2) in ksh/exec.c search_access() to
determine if it can invoke a given command, but
obviously access(2) doesn't use the effective [ug]id,
so will deny the command.
Now I _can_ run the command via env(1):
$ ./setgidsh /bin/ksh
$ id
uid=1000(jschauma) gid=100(users) egid=32766(nogroup) groups=100(users),0(wheel)
$ ./gids
/bin/ksh: ./gids: cannot execute - Permission denied
$ env ./gids
real : 1000 100
effective: 1000 32766
$
because my real-[ug]id is allowed to execute env(1),
so the privileged ksh does not complain, and env(1)
doesn't perform any such check and will simply
execve(2) "./gids" and let the kernel check the access
permissions.
This seems surprising if not flat out a bug: it
provides no actual protection, since I can still run
the command, and other shells let me explicitly allow
running commands with a different egid.
Is this something that should be fixed?
-Jan
Home |
Main Index |
Thread Index |
Old Index