diff options
author | Wayne Pollock | 2016-05-04 18:15:14 +0200 |
---|---|---|
committer | Sami Kerola | 2016-05-07 23:49:41 +0200 |
commit | 3e90d04af98c476f024ec12e5296b88d6dd830bf (patch) | |
tree | 7793e0a7154f4de494714fc7f8d061cbd52e086a /term-utils/write.c | |
parent | scriptreplay: avoid re-implementing strtod_or_err() (diff) | |
download | kernel-qcow2-util-linux-3e90d04af98c476f024ec12e5296b88d6dd830bf.tar.gz kernel-qcow2-util-linux-3e90d04af98c476f024ec12e5296b88d6dd830bf.tar.xz kernel-qcow2-util-linux-3e90d04af98c476f024ec12e5296b88d6dd830bf.zip |
write: fix setuid related regression
The write(1) is commonly a setuid binary, because common users cannot by
default write to each others terminals. Since the commit in reference, that
is part of releases v2.24 to v2.28, the write(1) has used access(2) to check
capability to write to a destination terminal. The catch is that access(2)
uses real UID and GID to when performing the accessibility. The obvious
correction is to avoid access(2) when in context of setuid binaries.
As a smaller fix, but equally important fix, ensure the 'msgsok' variable is
initialized to indicate no access. Uninitialized variable will almost
certainly do wrong thing at the time of check.
Breaking-commit: 0233a8ea18bec17dd59cfe1fec8281
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Karel Zak <kzak@redhat.com>
Signed-off-by: Wayne Pollock <profwaynepollock@gmail.com>
Diffstat (limited to 'term-utils/write.c')
-rw-r--r-- | term-utils/write.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/term-utils/write.c b/term-utils/write.c index 238040be2..14594f5d9 100644 --- a/term-utils/write.c +++ b/term-utils/write.c @@ -97,7 +97,7 @@ int main(int argc, char **argv) { time_t atime; uid_t myuid; - int msgsok, myttyfd, c; + int msgsok = 0, myttyfd, c; char tty[PATH_MAX], *mytty; static const struct option longopts[] = { @@ -151,7 +151,7 @@ int main(int argc, char **argv) if (!msgsok) errx(EXIT_FAILURE, _("you have write permission turned off")); - + msgsok = 0; } else mytty = "<no tty>"; @@ -230,7 +230,7 @@ void search_utmp(char *user, char *tty, char *mytty, uid_t myuid) struct utmp u; struct utmp *uptr; time_t bestatime, atime; - int nloggedttys, nttys, msgsok, user_is_me; + int nloggedttys, nttys, msgsok = 0, user_is_me; char atty[sizeof(u.ut_line) + 1]; utmpname(_PATH_UTMP); @@ -300,10 +300,10 @@ int term_chk(char *tty, int *msgsokP, time_t * atimeP, int showerror) warn("%s", path); return 1; } - - *msgsokP = !access(path, W_OK); - if (!root_access && *msgsokP) - *msgsokP = s.st_mode & S_IWGRP; + if (getuid() == 0) /* root can always write */ + *msgsokP = 1; + else + *msgsokP = (s.st_mode & S_IWGRP) && (getegid() == s.st_gid); *atimeP = s.st_atime; return 0; } |