diff --git a/src/ttyname.c b/src/ttyname.c index 6d70819ef..da98b031c 100644 --- a/src/ttyname.c +++ b/src/ttyname.c @@ -334,8 +334,7 @@ sudo_ttyname_dev(dev_t rdev) #if defined(sudo_kp_tdev) /* * Return a string from ttyname() containing the tty to which the process is - * attached or NULL if there is no tty associated with the process (or its - * parent). First tries sysctl using the current pid, then the parent's pid. + * attached or NULL if the process has no controlling tty. */ char * get_process_ttyname(void) @@ -343,38 +342,36 @@ get_process_ttyname(void) char *tty = NULL; struct sudo_kinfo_proc *ki_proc = NULL; size_t size = sizeof(*ki_proc); - int i, mib[6], rc; + int mib[6], rc; debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL) /* - * Lookup tty for this process and, failing that, our parent. - * Even if we redirect std{in,out,err} the kernel should still know. + * Lookup controlling tty for this process via sysctl. + * This will work even if std{in,out,err} are redirected. */ - for (i = 0; tty == NULL && i < 2; i++) { - mib[0] = CTL_KERN; - mib[1] = SUDO_KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = i ? (int)getppid() : (int)getpid(); - mib[4] = sizeof(*ki_proc); - mib[5] = 1; - do { - size += size / 10; - ki_proc = erealloc(ki_proc, size); - rc = sysctl(mib, sudo_kp_namelen, ki_proc, &size, NULL, 0); - } while (rc == -1 && errno == ENOMEM); - if (rc != -1) { - if (ki_proc->sudo_kp_tdev != (dev_t)-1) { - tty = sudo_ttyname_dev(ki_proc->sudo_kp_tdev); - if (tty == NULL) { - sudo_debug_printf(SUDO_DEBUG_WARN, - "unable to map device number %u to name", - ki_proc->sudo_kp_tdev); - } + mib[0] = CTL_KERN; + mib[1] = SUDO_KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = (int)getpid(); + mib[4] = sizeof(*ki_proc); + mib[5] = 1; + do { + size += size / 10; + ki_proc = erealloc(ki_proc, size); + rc = sysctl(mib, sudo_kp_namelen, ki_proc, &size, NULL, 0); + } while (rc == -1 && errno == ENOMEM); + if (rc != -1) { + if (ki_proc->sudo_kp_tdev != (dev_t)-1) { + tty = sudo_ttyname_dev(ki_proc->sudo_kp_tdev); + if (tty == NULL) { + sudo_debug_printf(SUDO_DEBUG_WARN, + "unable to map device number %u to name", + ki_proc->sudo_kp_tdev); } - } else { - sudo_debug_printf(SUDO_DEBUG_WARN, - "unable to resolve tty via KERN_PROC: %s", strerror(errno)); } + } else { + sudo_debug_printf(SUDO_DEBUG_WARN, + "unable to resolve tty via KERN_PROC: %s", strerror(errno)); } efree(ki_proc); @@ -383,8 +380,7 @@ get_process_ttyname(void) #elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) /* * Return a string from ttyname() containing the tty to which the process is - * attached or NULL if there is no tty associated with the process (or its - * parent). First tries /proc/pid/psinfo, then /proc/ppid/psinfo. + * attached or NULL if the process has no controlling tty. */ char * get_process_ttyname(void) @@ -392,20 +388,17 @@ get_process_ttyname(void) char path[PATH_MAX], *tty = NULL; struct psinfo psinfo; ssize_t nread; - int i, fd; + int fd; debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL) /* Try to determine the tty from pr_ttydev in /proc/pid/psinfo. */ - for (i = 0; tty == NULL && i < 2; i++) { - (void)snprintf(path, sizeof(path), "/proc/%u/psinfo", - i ? (unsigned int)getppid() : (unsigned int)getpid()); - if ((fd = open(path, O_RDONLY, 0)) == -1) - continue; + snprintf(path, sizeof(path), "/proc/%u/psinfo", (unsigned int)getpid()); + if ((fd = open(path, O_RDONLY, 0)) != -1) { nread = read(fd, &psinfo, sizeof(psinfo)); close(fd); if (nread == (ssize_t)sizeof(psinfo)) { dev_t rdev = (dev_t)psinfo.pr_ttydev; -#ifdef DEVNO64 +#if defined(_AIX) && defined(DEVNO64) if (psinfo.pr_ttydev & DEVNO64) rdev = makedev(major64(psinfo.pr_ttydev), minor64(psinfo.pr_ttydev)); #endif @@ -419,26 +412,20 @@ get_process_ttyname(void) #elif defined(__linux__) /* * Return a string from ttyname() containing the tty to which the process is - * attached or NULL if there is no tty associated with the process (or its - * parent). First tries field 7 in /proc/pid/stat, then /proc/ppid/stat. + * attached or NULL if the process has no controlling tty. */ char * get_process_ttyname(void) { - char *line = NULL, *tty = NULL; + char path[PATH_MAX], *line = NULL, *tty = NULL; size_t linesize = 0; ssize_t len; - int i; + FILE *fp; debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL) /* Try to determine the tty from tty_nr in /proc/pid/stat. */ - for (i = 0; tty == NULL && i < 2; i++) { - FILE *fp; - char path[PATH_MAX]; - (void)snprintf(path, sizeof(path), "/proc/%u/stat", - i ? (unsigned int)getppid() : (unsigned int)getpid()); - if ((fp = fopen(path, "r")) == NULL) - continue; + snprintf(path, sizeof(path), "/proc/%u/stat", (unsigned int)getpid()); + if ((fp = fopen(path, "r")) != NULL) { len = getline(&line, &linesize, fp); fclose(fp); if (len != -1) { @@ -456,33 +443,28 @@ get_process_ttyname(void) } } } + efree(line); } - efree(line); debug_return_str(tty); } #elif HAVE_PSTAT_GETPROC /* * Return a string from ttyname() containing the tty to which the process is - * attached or NULL if there is no tty associated with the process (or its - * parent). + * attached or NULL if the process has no controlling tty. */ char * get_process_ttyname(void) { struct pst_status pstat; char *tty = NULL; - int i; debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL) /* Try to determine the tty from psdev in struct pst_status. */ - for (i = 0; tty == NULL && i < 2; i++) { - const int pid = i ? (int)getppid() : (int)getpid(); - if (pstat_getproc(&pstat, sizeof(pstat), 0, pid) != -1) { - if (pstat.pst_term.psd_major != -1 && pstat.pst_term.psd_minor != -1) { - tty = sudo_ttyname_dev(makedev(pstat.pst_term.psd_major, - pstat.pst_term.psd_minor)); - } + if (pstat_getproc(&pstat, sizeof(pstat), 0, (int)getpid()) != -1) { + if (pstat.pst_term.psd_major != -1 && pstat.pst_term.psd_minor != -1) { + tty = sudo_ttyname_dev(makedev(pstat.pst_term.psd_major, + pstat.pst_term.psd_minor)); } } debug_return_str(tty); @@ -490,8 +472,7 @@ get_process_ttyname(void) #else /* * Return a string from ttyname() containing the tty to which the process is - * attached or NULL if there is no tty associated with the process. - * parent). + * attached or NULL if the process has no controlling tty. */ char * get_process_ttyname(void)