Date: Wed, 12 May 2004 10:50:11 -0700 (PDT) From: "Dorr H. Clark" <dclark@applmath.scu.edu> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit Message-ID: <200405121750.i4CHoBtW065338@freefall.freebsd.org>
index | next in thread | raw e-mail
The following reply was made to PR bin/61355; it has been noted by GNATS.
From: "Dorr H. Clark" <dclark@applmath.scu.edu>
To: freebsd-gnats-submit@FreeBSD.org, eugen@kuzbass.ru
Cc:
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Wed, 12 May 2004 10:45:47 -0700
The fix is presented:
--- ../login_bak/login.c Fri Apr 25 19:51:03 2003
+++ ./login.c Sun May 2 04:16:06 2004
@@ -82,6 +82,9 @@
#include "login.h"
#include "pathnames.h"
+#include <sys/types.h>
+#include <utmp.h>
+
static int auth_pam(void);
static void bail(int, int);
static int export(const char *);
@@ -172,7 +175,16 @@
const char *shell = NULL;
login_cap_t *lc = NULL;
pid_t pid;
+ gid_t curr_gid;
+ char* login;
+ struct ttyent *tyTmp;
+ int fdAlt;
+ int ttyAlt;
+ struct utmp ut;
+ unsigned short int found_ut = 0;
+ FILE* utFile;
+
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
(void)signal(SIGHUP, SIG_IGN);
@@ -230,6 +242,9 @@
setproctitle("-%s", getprogname());
+ curr_gid = getgid();
+ login = getlogin();
+
for (cnt = getdtablesize(); cnt > 2; cnt--)
(void)close(cnt);
@@ -246,6 +261,28 @@
else
tty = ttyn;
+ /* set the current login's information so that we can come back to
it when the new user logs out*/
+ if ((utFile = fopen(_PATH_UTMP, "r")) == NULL)
+ syslog(LOG_ERR, "failed opening (%s): may not be able to
reset user properly", _PATH_UTMP);
+ if(utFile)
+ {
+ while(fread(&ut, sizeof(ut), 1, utFile))
+ {
+ if(!strcmp(ut.ut_line, tty))
+ {
+ found_ut = 1;
+ break;
+ }
+ }
+ if(!found_ut)
+ {
+ strncpy(ut.ut_line, tty, UT_LINESIZE);
+ strncpy(ut.ut_name, login, UT_NAMESIZE);
+ strncpy(ut.ut_host, "", UT_HOSTSIZE);
+ ut.ut_time = 0;
+ }
+ (void)fclose(utFile);
+ }
/*
* Get "login-retries" & "login-backoff" from default class
*/
@@ -509,6 +546,40 @@
int status;
setproctitle("-%s [pam]", getprogname());
waitpid(pid, &status, 0);
+ pam_cleanup();
+
+ /*now change the login back to the original user*/
+ //set the tty devices back to the original owner
+ if (ttyn != tname && chflags(ttyn, 0)) if (errno != EOPNOTSUPP
&& errno != EROFS)
+ {
+ syslog(LOG_ERR, "chflags(%s): %m", ttyn);
+ printf("chflags(%s): %m", ttyn);
+ }
+ if (ttyn != tname && chown(ttyn, uid, (gr =
getgrnam(TTYGRPNAME)) ? gr->gr_gid : curr_gid))
+ {
+ if (errno != EROFS)
+ {
+ syslog(LOG_ERR, "chown(%s): %m", ttyn);
+ printf("chown(%s): %m", ttyn);
+ }
+ }
+
+ /* set the tty session */
+ setttyent();
+ for (ttyAlt = 1; (tyTmp = getttyent()) != NULL; ++ttyAlt)
+ if (strcmp(tyTmp->ty_name, ut.ut_line) == 0)
+ break;
+ endttyent();
+ if (ttyAlt > 0 && (fdAlt = open(_PATH_UTMP, O_WRONLY|O_CREAT,
0644)) >= 0)
+ {
+ (void)lseek(fdAlt, (off_t)(ttyAlt * sizeof(struct utmp)),
L_SET);
+ (void)write(fdAlt, &ut, sizeof(struct utmp));
+ (void)close(fdAlt);
+ }
+
+ /*set the login back to the initial user*/
+ setlogin(login);
+
bail(NO_SLEEP_EXIT, 0);
}
This bug occurs when a user session is launched
through the "login" binary at a shell prompt
and then terminated, the system persists in
tracking the tty ownership as the departed user
(who has already logged off).
To fix the problem, we maintain the original loginid
and set that to be the owner of the tty, using the utmp
structure as tracked in the file /var/run/utmp
so when the login session exits the original owner
of the tty is restored.
This fix should be evaluated carefully for potential
exploits, although this risk can be balanced against
the fact that the bug itself represents a security issue.
Anirban Kundu, Engineer
Dorr H. Clark, Advisor,
Graduate School of Engineering
Santa Clara University
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200405121750.i4CHoBtW065338>
