summaryrefslogtreecommitdiffstats
path: root/login-utils/last.c
diff options
context:
space:
mode:
authorSami Kerola2014-01-21 23:05:05 +0100
committerKarel Zak2014-02-10 18:25:31 +0100
commit404fa3f93c00c7e130f5a0ec963b2dc6a3743986 (patch)
tree35d64216dd7d675e5260454b93147afa4eb7e84f /login-utils/last.c
parenthexdump: add highlighting support (diff)
downloadkernel-qcow2-util-linux-404fa3f93c00c7e130f5a0ec963b2dc6a3743986.tar.gz
kernel-qcow2-util-linux-404fa3f93c00c7e130f5a0ec963b2dc6a3743986.tar.xz
kernel-qcow2-util-linux-404fa3f93c00c7e130f5a0ec963b2dc6a3743986.zip
last: make session gone determination more robust
Earlier determination that used kill with signal zero to pid was prone to false positive reports, due reuse of pid space and unrelated processes. New function is_phantom() tries do a little bit better job, but fails to be perfect. It seems linking to gether utmp session start time or terminal id with /proc/<pid>/ information is not as simple as one might hope. Reported-by: Karel Zak <kzak@redhat.com> Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'login-utils/last.c')
-rw-r--r--login-utils/last.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/login-utils/last.c b/login-utils/last.c
index 5550dcb3f..e4a849776 100644
--- a/login-utils/last.c
+++ b/login-utils/last.c
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <ctype.h>
#include <utmp.h>
+#include <pwd.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -572,6 +573,26 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
+static int is_phantom(struct utmp *ut)
+{
+ struct passwd *pw;
+ char path[32];
+ FILE *f;
+ unsigned int loginuid, ret = 0;
+
+ pw = getpwnam(ut->ut_name);
+ if (!pw)
+ return 1;
+ sprintf(path, "/proc/%u/loginuid", ut->ut_pid);
+ if (!(f = fopen(path, "r")))
+ return 1;
+ if (fscanf(f, "%u", &loginuid) != 1)
+ ret = 1;
+ fclose(f);
+ if (!ret && pw->pw_uid != loginuid)
+ return 1;
+ return ret;
+}
static void process_wtmp_file(const struct last_control *ctl)
{
@@ -766,9 +787,7 @@ static void process_wtmp_file(const struct last_control *ctl)
if (!lastboot) {
c = R_NOW;
/* Is process still alive? */
- if (ut.ut_pid > 0 &&
- kill(ut.ut_pid, 0) != 0 &&
- errno == ESRCH)
+ if (is_phantom(&ut))
c = R_PHANTOM;
} else
c = whydown;