Skip to content

Commit

Permalink
sudo_ttyname_dev: On Linux try to use /proc/self/fd/{0,1,2} if possible.
Browse files Browse the repository at this point in the history
If one of std{in,out,err} matches the specified device, try to
resolve it to a path by using /proc/self/fd/{0,1,2}.  This avoids
searching all of /dev and works in a chroot where /proc is mounted
but /dev/pts is not.  GitHub issue #421.
  • Loading branch information
millert committed Nov 16, 2024
1 parent 7e8f006 commit b7efb8a
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion lib/util/ttyname_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,39 @@ char *
sudo_ttyname_dev_v1(dev_t rdev, char *buf, size_t buflen)
{
const char *devsearch, *devsearch_end;
char path[PATH_MAX], *ret;
char path[PATH_MAX], *ret = NULL;
const char *cp, *ep;
size_t len;
debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL);

#ifdef __linux__
/*
* First check std{in,out,err} and use /proc/self/fd/{0,1,2} if possible.
*/
for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) {
char fdpath[] = "/proc/self/fd/N";
struct stat sb;

if (fstat(fd, &sb) == -1 || !S_ISCHR(sb.st_mode))
continue;
if (rdev != sb.st_rdev)
continue;

fdpath[sizeof("/proc/self/fd/N") - 2] = '0' + fd;
len = readlink(fdpath, buf, buflen);
if (len != (size_t)-1) {
if (len == buflen) {
errno = ERANGE; /* buf too small */
} else {
/* readlink(2) does not NUL-terminate. */
buf[len] = '\0';
ret = buf;
}
goto done;
}
}
#endif

/*
* First, check /dev/console.
*/
Expand Down

0 comments on commit b7efb8a

Please sign in to comment.