From d03d7130046964e2affef6a095fe8c2e17e23886 Mon Sep 17 00:00:00 2001 From: kappa Date: Fri, 30 Oct 2020 13:21:25 +0100 Subject: [PATCH] Clean up lines that cause warning messages in GCC There are several lines in the code which cause GCC to warn the user about undefined behaviour. Most of these are potential buffer overflow problems. Which come from either overwriting a buffer which may be too small for a given input, or writing to, or from, a string not guaranteed to be null-terminated, such as any of the char[] fields in a utmp struct. Almost all come from an improper usage of strcmp or strncmp or similar. --- timeoutd.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/timeoutd.c b/timeoutd.c index 80b918a..c0417d6 100644 --- a/timeoutd.c +++ b/timeoutd.c @@ -418,7 +418,10 @@ void read_wtmp() while (fread(&ut, sizeof(struct utmp), 1, fp) == 1) { - tm = localtime(&ut.ut_time); + /* ut.ut_tv.tv_sec is not guaranteed to be time_t and localtime requires a time_t + argument, and will break otherwise */ + time_t tmp_time = ut.ut_tv.tv_sec; + tm = localtime(&tmp_time); if (tm->tm_year != now.tm_year || tm->tm_yday != now.tm_yday) break; @@ -812,7 +815,7 @@ char *user; } #endif if (/*logout_p->elem.ut_type == DEAD_PROCESS &&*/ - !strcmp(login_p->elem.ut_line, logout_p->elem.ut_line)) + !strncmp(login_p->elem.ut_line, logout_p->elem.ut_line, UT_LINESIZE)) break; prev_p = logout_p; logout_p = logout_p->next; @@ -1050,7 +1053,7 @@ void check_idle() /* Check for exceeded time limits & logoff exceeders */ strncpy(dev, utmpp->ut_line, sizeof(dev) - 1); /* get device name */ dev[sizeof(dev) - 1] = '\0'; sprintf(path, "/dev/%s", dev); - if (stat(path, pstat) && !chk_xsession(dev, host) == TIMEOUTD_XSESSION_LOCAL) /* if can't get status for + if (stat(path, pstat) && chk_xsession(dev, host) != TIMEOUTD_XSESSION_LOCAL) /* if can't get status for port && if it's not a local Xsession */ { sprintf(errmsg, "Can't get status of user %s's terminal (%s)\n", @@ -1430,7 +1433,7 @@ void killit_xsession(pid, user, host) /* returns 1 when host seems to be a xSess int pid; char *host, *user; { - char msgbuf[1024], cmdbuf[1024]; + char msgbuf[512], cmdbuf[1024]; /* first, get the message into msgbuf */ if (limit_type == NOLOGINMSG) { sprintf(msgbuf, "Logins not allowed at this time. Please try again later."); @@ -1591,7 +1594,7 @@ pid_t ppid; FILE *proc_file; struct dirent *cont; char akt_pid[99]; - char path[256]; + char path[512]; proc = opendir("/proc/"); if(proc == NULL) { @@ -1599,8 +1602,8 @@ pid_t ppid; return -1; /* error */ } - while((cont = readdir(proc)) != NULL) - if(cont->d_type == 4 && isdigit(cont->d_name[0])) { /* check only PIDs */ + while((cont = readdir(proc)) != NULL) { + if(cont->d_type == DT_DIR && isdigit(cont->d_name[0])) { /* check only PIDs */ sprintf(path, "/proc/%s/status", cont->d_name); proc_file = fopen(path, "r"); if(!proc_file) @@ -1611,7 +1614,8 @@ pid_t ppid; if(atoi(akt_pid) == ppid) return (pid_t)atoi(cont->d_name); /* return pid of child */ - } /* if(cont->d_type == 4) */ + } + } return 0; /* no child found */ } /* getchild(ppid) */