pkgsrc-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: 'sudo' "use_pty" broken on serial or wscons terminals
>The default behavior of recent "security/sudo" is to open a pty. While
>this works fine in XTerm (or similar) or over an SSH connection, it
>breaks programs run at a real serial terminal or wscons text console.
>
>Displayed text stair-steps each line keyboard input is either ignored,
>lost, or misdirected.
>
There's an inconsistency in the returned maj./min. devnos. for the current
terminal when it is a console which depends on the method you use to get this
info.
```
$ fgrep constty /etc/ttys
constty "/usr/libexec/getty Pc" vt100 on secure
$
```
When you go through the filesystem like ttyname(3), for the console FD we get:
```
$ tty
/dev/constty
```
But, if you use sysctl(KERN_PROC2) we get something else entirely:
```
$ ./ttyname
/dev/ttyE0
```
because when wscons takes over the console, it overwrites the maj/min with
different ones. (Maybe file a PR for this?)
This inconsistency causes sudo to think that the current tty isn't a terminal.
To fix this issue, you can
a) either use `ttyE0' instead of `constty' -- like the other BSDs do:
```
constty "/usr/libexec/getty Pc" vt100 on secure
ttyE0 "/usr/libexec/getty Pc" wsvt25 on secure
```
That should work for standard VT console; or,
b) try this patch:
```
diff -urN sudo-1.9.15p5.orig/src/exec.c sudo-1.9.15p5/src/exec.c
--- sudo-1.9.15p5.orig/src/exec.c 2023-12-15 19:08:31.000000000 +0000
+++ sudo-1.9.15p5/src/exec.c 2024-03-23 14:14:59.597489636 +0000
@@ -395,8 +395,12 @@
if (!S_ISCHR(fd_sb->st_mode))
debug_return_bool(false);
+#ifdef __NetBSD__
+ debug_return_bool(tty_sb ? tty_sb->st_rdev == fd_sb->st_rdev || isatty(fd) : isatty(fd));
+#else
/* Compare with tty_sb if available, else just check that fd is a tty. */
debug_return_bool(tty_sb ? tty_sb->st_rdev == fd_sb->st_rdev : isatty(fd));
+#endif
}
/*
```
HTH.
-RVP
ttyname.c source:
```
/**
* TTY name using sysctl(3) a la sudo(8).
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <err.h>
#include <errno.h>
#include <fts.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static ssize_t getproclist(struct kinfo_proc2** kpp);
static void prtty(struct kinfo_proc2 ki);
int
main(void)
{
struct kinfo_proc2* ka;
ssize_t nprocs, i;
nprocs = getproclist(&ka);
if (nprocs == -1)
err(EXIT_FAILURE, "can't get process list");
// printf("total = %lu\n", nprocs);
for (i = 0; i < nprocs; i++)
prtty(ka[i]);
free(ka);
return 0;
}
static ssize_t
getproclist(struct kinfo_proc2** kpp)
{
struct kinfo_proc2* kp = NULL;
int mib[6], rc;
size_t osiz, siz = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC2;
mib[2] = KERN_PROC_PID;
mib[3] = (int)getpid();
mib[4] = sizeof (struct kinfo_proc2);
mib[5] = 1;
rc = sysctl(mib, 6, NULL, &siz, NULL, 0);
if (rc == -1)
return -1;
if (siz == 0)
goto out;
do {
siz += siz / 10;
void* p = realloc(kp, siz);
if (p == NULL) {
free(kp);
return -1;
}
kp = p;
osiz = siz;
mib[5] = (int)(siz / sizeof (struct kinfo_proc2));
rc = sysctl(mib, 6, kp, &siz, NULL, 0);
} while (rc == -1 && errno == ENOMEM && siz == osiz);
if (rc == -1) {
free(kp);
return -1;
}
out:
*kpp = kp;
return (ssize_t)(siz / sizeof (struct kinfo_proc2));
}
static void
prtty(struct kinfo_proc2 ki)
{
FTS* ftsp;
FTSENT* fe;
char* const dirs[] = { "/dev", NULL };
if ((ftsp = fts_open(dirs, FTS_NOCHDIR|FTS_PHYSICAL, NULL)) == NULL)
return;
// printf("0x%x = ", ki.p_tdev);
while ((fe = fts_read(ftsp)) != NULL) {
if (fe->fts_statp->st_rdev == ki.p_tdev) {
printf("%s\n", fe->fts_path);
break;
}
}
fts_close(ftsp);
}
```
Home |
Main Index |
Thread Index |
Old Index