diff options
author | Karel Zak <kzak@redhat.com> | 2015-03-13 11:13:26 +0100 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2015-03-13 11:24:13 +0100 |
commit | c016a9239503e6278d8e2d276ac5ffa36f57bd3a (patch) | |
tree | 044eb606e877d5c1b7dadf75657bfe34925585f2 | |
parent | befb2f7914a48deec108f1a046ff0fd0a065bef6 (diff) | |
download | util-linux-c016a9239503e6278d8e2d276ac5ffa36f57bd3a.tar.gz |
last: fix utmplist usage
last(1) uses a global list of entries, this is unnecessary and it's
also mistake because the pointer to the list is not set to NULL when
last(1) opens another utmp file. For example:
last -f /var/log/wtmp -f /var/log/wtmp-20150220
ends with unexpected free() call or sometimes with never ending loop.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1201033
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | login-utils/last.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/login-utils/last.c b/login-utils/last.c index d6d8d9624..3d9a62bee 100644 --- a/login-utils/last.c +++ b/login-utils/last.c @@ -107,7 +107,6 @@ struct utmplist { struct utmplist *next; struct utmplist *prev; }; -struct utmplist *utmplist = NULL; /* Types of listing */ enum { @@ -622,8 +621,10 @@ static int is_phantom(const struct last_control *ctl, struct utmp *ut) static void process_wtmp_file(const struct last_control *ctl) { FILE *fp; /* Filepointer of wtmp file */ + char *filename; struct utmp ut; /* Current utmp entry */ + struct utmplist *ulist = NULL; /* All entries */ struct utmplist *p; /* Pointer into utmplist */ struct utmplist *next; /* Pointer into utmplist */ @@ -640,6 +641,7 @@ static void process_wtmp_file(const struct last_control *ctl) time(&lastdown); lastrch = lastdown; + filename = ctl->altv[ctl->alti]; /* * Fill in 'lastdate' @@ -655,8 +657,8 @@ static void process_wtmp_file(const struct last_control *ctl) /* * Open the utmp file */ - if ((fp = fopen(ctl->altv[ctl->alti], "r")) == NULL) - err(EXIT_FAILURE, _("cannot open %s"), ctl->altv[ctl->alti]); + if ((fp = fopen(filename, "r")) == NULL) + err(EXIT_FAILURE, _("cannot open %s"), filename); /* * Optimize the buffer size. @@ -670,7 +672,7 @@ static void process_wtmp_file(const struct last_control *ctl) begintime = ut.UL_UT_TIME; else { if (fstat(fileno(fp), &st) != 0) - err(EXIT_FAILURE, _("stat of %s failed"), ctl->altv[ctl->alti]); + err(EXIT_FAILURE, _("stat of %s failed"), filename); begintime = st.st_ctime; quit = 1; } @@ -787,7 +789,7 @@ static void process_wtmp_file(const struct last_control *ctl) * the same ut_line. */ c = 0; - for (p = utmplist; p; p = next) { + for (p = ulist; p; p = next) { next = p->next; if (strncmp(p->ut.ut_line, ut.ut_line, UT_LINESIZE) == 0) { @@ -796,11 +798,12 @@ static void process_wtmp_file(const struct last_control *ctl) quit = list(ctl, &ut, p->ut.UL_UT_TIME, R_NORMAL); c = 1; } - if (p->next) p->next->prev = p->prev; + if (p->next) + p->next->prev = p->prev; if (p->prev) p->prev->next = p->next; else - utmplist = p->next; + ulist = p->next; free(p); } } @@ -829,10 +832,11 @@ static void process_wtmp_file(const struct last_control *ctl) break; p = xmalloc(sizeof(struct utmplist)); memcpy(&p->ut, &ut, sizeof(struct utmp)); - p->next = utmplist; + p->next = ulist; p->prev = NULL; - if (utmplist) utmplist->prev = p; - utmplist = p; + if (ulist) + ulist->prev = p; + ulist = p; break; case EMPTY: @@ -848,23 +852,24 @@ static void process_wtmp_file(const struct last_control *ctl) /* * If we saw a shutdown/reboot record we can remove - * the entire current utmplist. + * the entire current ulist. */ if (down) { lastboot = ut.UL_UT_TIME; whydown = (ut.ut_type == SHUTDOWN_TIME) ? R_DOWN : R_CRASH; - for (p = utmplist; p; p = next) { + for (p = ulist; p; p = next) { next = p->next; free(p); } - utmplist = NULL; + ulist = NULL; down = 0; } } - printf(_("\n%s begins %s"), basename(ctl->altv[ctl->alti]), ctime(&begintime)); + printf(_("\n%s begins %s"), basename(filename), ctime(&begintime)); fclose(fp); - for (p = utmplist; p; p = next) { + + for (p = ulist; p; p = next) { next = p->next; free(p); } @@ -1001,7 +1006,7 @@ int main(int argc, char **argv) ctl.altc++; } - for (; ctl.alti < ctl.altc; ctl.alti++) { + for (ctl.alti = 0; ctl.alti < ctl.altc; ctl.alti++) { get_boot_time(&ctl.boot_time); process_wtmp_file(&ctl); free(ctl.altv[ctl.alti]); |