summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2023-03-11 00:38:24 -0800
committerAlejandro Colomar <alx@kernel.org>2023-04-18 18:42:04 +0200
commit025e2e0769f3f345842412742da0276c865b9e6b (patch)
treea2faacdd690297dc6eb9d38b8bd1b6c208f2c2d2
parent97f79e3b2715d78c9342cbb292e1a3e72a23fe62 (diff)
Avoid silent truncation of console file datapaul
* libmisc/console.c (is_listed): Rework so that there is no fixed-size buffer, and no need to use fgets or strlcpy or strtok. Instead, the code works with arbitrary-sized input, without silently truncating data or mishandling NUL bytes in the console file. Signed-off-by: Paul Eggert <eggert@cs.ucla.edu>
-rw-r--r--libmisc/console.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/libmisc/console.c b/libmisc/console.c
index 7e2132dd..8264e1a3 100644
--- a/libmisc/console.c
+++ b/libmisc/console.c
@@ -24,7 +24,6 @@
static bool is_listed (const char *cfgin, const char *tty, bool def)
{
FILE *fp;
- char buf[1024], *s;
const char *cons;
/*
@@ -43,17 +42,17 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
*/
if (*cons != '/') {
- char *pbuf;
- strlcpy (buf, cons, sizeof (buf));
- pbuf = &buf[0];
- while ((s = strtok (pbuf, ":")) != NULL) {
- if (strcmp (s, tty) == 0) {
+ size_t ttylen = strlen (tty);
+ for (;;) {
+ if (strncmp (cons, tty, ttylen) == 0
+ && (cons[ttylen] == ':' || !cons[ttylen])) {
return true;
}
-
- pbuf = NULL;
+ cons = strchr (cons, ':');
+ if (!cons)
+ return false;
+ cons++;
}
- return false;
}
/*
@@ -70,21 +69,22 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
* See if this tty is listed in the console file.
*/
- while (fgets (buf, sizeof (buf), fp) != NULL) {
- /* Remove optional trailing '\n'. */
- buf[strcspn (buf, "\n")] = '\0';
- if (strcmp (buf, tty) == 0) {
- (void) fclose (fp);
- return true;
+ const char *tp = tty;
+ bool listed = false;
+ for (int c; 0 <= (c = getc (fp)); ) {
+ if (c == '\n') {
+ if (tp && !*tp) {
+ listed = true;
+ break;
+ }
+ tp = tty;
+ } else if (tp) {
+ tp = *tp == c && c ? tp + 1 : NULL;
}
}
- /*
- * This tty isn't a console.
- */
-
(void) fclose (fp);
- return false;
+ return listed;
}
/*
@@ -105,4 +105,3 @@ bool console (const char *tty)
return is_listed ("CONSOLE", tty, true);
}
-