NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/59449: which(1) / whereis(1) fails if the euid/egid != uid/gid
>Number: 59449
>Category: bin
>Synopsis: which(1) / whereis(1) fails if the euid/egid != uid/gid
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri May 30 21:10:00 +0000 2025
>Originator: Jan Schaumann
>Release: NetBSD 10.1
>Organization:
>Environment:
NetBSD netbsd-linode 10.1 NetBSD 10.1 (GENERIC) #0: Mon Dec 16 13:08:11 UTC 2024 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
$ ident `which which` | grep whereis
$NetBSD: whereis.c,v 1.21 2008/10/17 10:53:26 apb Exp $
Architecture: x86_64
Machine: amd64
>Description:
At program startup, which(1)/whereis(1) attempts to
setgid/setuid to the euid/egid. This will fail if
euid/egid != uid/gid for the current process. As a
result, which(1)/whereis(1) will completely fail.
This is unexpected from the user's perspective.
Instead, I'd have expected the program to give me the
list of commands the real user can access, even if it
may not give me the full list of commands that the
euid/egid might be able to access.
>How-To-Repeat:
$ cat >setgidsh.c <<EOF
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
argv++;
execv(argv[0], argv);
perror("execl");
}
EOF
$ cc -o setgidsh setgidsh.c
$ sudo chown nobody:nogroup setgidsh
$ sudo chmod g+s setgidsh
$ ./setgidsh /bin/sh -p
$ id
uid=1000(linode) gid=100(users) euid=32767(nobody) groups=100(users),0(wheel)
$ which ls
which: Can't set uid to 32767: Operation not permitted
$
>Fix:
I think that instead of trying to setuid/setgid, the
call to access(2) in whereis.c could be followed by a
call to faccessat(2) with AT_EACCESS to cover the case
of different access by euid/egid.
Home |
Main Index |
Thread Index |
Old Index