From eugen@www.svzserv.kemerovo.su  Wed Jan 14 02:54:41 2004
Return-Path: <eugen@www.svzserv.kemerovo.su>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C9AF916A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 14 Jan 2004 02:54:41 -0800 (PST)
Received: from www.svzserv.kemerovo.su (www.svzserv.kemerovo.su [213.184.65.80])
	by mx1.FreeBSD.org (Postfix) with ESMTP id F413343D49
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 14 Jan 2004 02:54:39 -0800 (PST)
	(envelope-from eugen@www.svzserv.kemerovo.su)
Received: from www.svzserv.kemerovo.su (eugen@localhost [127.0.0.1])
	by www.svzserv.kemerovo.su (8.12.10/8.12.10) with ESMTP id i0EAsbiY059250
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 14 Jan 2004 17:54:37 +0700 (KRAT)
	(envelope-from eugen@www.svzserv.kemerovo.su)
Received: (from eugen@localhost)
	by www.svzserv.kemerovo.su (8.12.10/8.12.10/Submit) id i0EAsbGU059249;
	Wed, 14 Jan 2004 17:54:37 +0700 (KRAT)
	(envelope-from eugen)
Message-Id: <200401141054.i0EAsbGU059249@www.svzserv.kemerovo.su>
Date: Wed, 14 Jan 2004 17:54:37 +0700 (KRAT)
From: Eugene Grosbein <eugen@kuzbass.ru>
Reply-To: Eugene Grosbein <eugen@kuzbass.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: login(1) does not restore terminal ownership on exit
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         61355
>Category:       bin
>Synopsis:       login(1) does not restore terminal ownership on exit
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 14 03:00:33 PST 2004
>Closed-Date:    
>Last-Modified:  Sun Apr 28 21:50:01 UTC 2013
>Originator:     Eugene Grosbein
>Release:        FreeBSD 4.9-STABLE i386
>Organization:
Svyaz Service JSC
>Environment:
System: FreeBSD www.svzserv.kemerovo.su 4.9-STABLE FreeBSD 4.9-STABLE #0: Mon Nov 3 13:18:36 KRAT 2003 eu@www.svzserv.kemerovo.su:/home4/obj/home/src/sys/WWW i386

	Same for 5.2-CURRENT

>Description:

	login(1) does not restore ownership of tty device and
	does not correct utmp(5) entry. This breaks many applications
	like w, screen etc.

>How-To-Repeat:

	Let's login as user 'eugen' from console.

FreeBSD/i386 (www.svzserv.kemerovo.su) (ttyv2)
 
login: eugen
Password:

eugen@www:~>tty
/dev/ttyv2
eugen@www:~>w|grep v2
eugen            v2       -                17:24       - -bash (bash)

	Now use login(1) to become user 'sa':

eugen@www:~>login sa
Password:
bash-2.05$ tty
/dev/ttyv2
bash-2.05$ w|grep v2
sa               v2       -                17:25       - -bash (bash)

	We are 'sa' now and terminal belongs to 'sa'.
	Now leave this account.

bash-2.05$ exit
logout

	And see bad things:

eugen@www:~>w|grep v2
sa               v2       -                17:25       - grep v2 (bash)
eugen@www:~>ls -l `tty`
crw--w----  1 sa  tty   12,   2 14     17:25 /dev/ttyv2

	utmp thinks that where is 'sa' still, so sysadmin will be fooled.
	Otoh, screen won't work anymore.

>Fix:

	Unknown.

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: gnats-admin->freebsd-bugs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Jan 14 09:16:15 PST 2004 
Responsible-Changed-Why:  
Rescue this from the "pending" category. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61355 

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

From: Eugene Grosbein <eugen@grosbein.pp.ru>
To: bug-followup@freebsd.org
Cc: dclark@applmath.scu.edu
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exi
Date: Sun, 8 Aug 2004 23:36:30 +0800

 Hi!
 
 I'm sorry, but this patch does not apply to 4.10-STABLE.
 
 Eugene Grosbein

From: "Dorr H. Clark" <dclark@applmath.scu.edu>
To: freebsd-gnats-submit@FreeBSD.org, eugen@kuzbass.ru
Cc:  
Subject: true Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Tue, 10 Aug 2004 15:14:25 -0700

 Eugene Grosbein wrote:
         
 > I'm sorry, but this patch does not apply to 4.10-STABLE.
  
 You are correct.  We were working with 5.x, which has the same issue.
 
 -Dorr H. Clark
 
 Graduate School of Engineering
 Santa Clara University

From: Eugene Grosbein <eugen@kuzbass.ru>
To: bug-followup@freebsd.org
Cc: stable@freebsd.org
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Mon, 9 May 2005 23:33:00 +0800

 Hi!
 
 The problem is still here for 4.11-STABLE and 5.4-STABLE:
 
 http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/61355
 
 Eugene Grosbein

From: Eugene Grosbein <eugen@grosbein.pp.ru>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Fri, 26 Jan 2007 20:34:24 +0700

 Hi!
 
 This is still the problem for FreeBSD 6.2 but effect differs.
 
 Now, after login/logout sequence a record describing the terminal
 just disappears from utmp and user become 'a stealth'.
 
 Eugene Grosbein.

From: Bruce Cran <bruce@cran.org.uk>
To: bug-followup@FreeBSD.org, eugen@kuzbass.ru
Cc:  
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Sun, 30 Mar 2008 21:51:51 +0100

 The behaviour on FreeBSD 6 and later is described in PR bin/75378.
 
 --
 Bruce

From: Eugene Grosbein <egrosbein@rdtc.ru>
To: bug-followup@FreeBSD.ORG
Cc:  
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Tue, 04 Jan 2011 15:32:50 +0600

 This is still the problem for 8.2-PRERELEASE, in a way similar to 6.2:
 exiting 'nested' login session clears wtmp, so original session becomes 'invisible'
 with wrong tty ownership.
 
 Eugene Grosbein

From: Sergey Kandaurov <pluknet@gmail.com>
To: bug-followup@FreeBSD.org, eugen@kuzbass.ru
Cc:  
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Wed, 5 Jan 2011 20:17:51 +0300

 Strictly speaking, my 2c isn't related to the ticket, but still..
 To recover tty ownership, I used kqueue() to pwait until a
 "session" exec'ed from under su has finished (i.e. exec'ed
 shell has exited), then ioctl(..,DEVFSIO_RAPPLY,..).
 Messy but works.
 
 my 2c.

From: Eugene Grosbein <egrosbein@rdtc.ru>
To: bug-followup@FreeBSD.ORG
Cc:  
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Sun, 28 Apr 2013 19:56:57 +0700

 Hi!
 
 Please note that this problem was first reported over 9 years ago.
 
 The problem is still here with 9.1-STABLE. However, visual effects has changed again.
 
 That's what do we have now. First, login via ssh as user "eugen":
 
 $ tty
 /dev/pts/1
 $ w | grep pts/1
 eugen      pts/1    eg.sd.rdtc.ru            19:44       - grep pts/1
 
 Than, use /usr/bin/login to become user "support":
 
 $ login support
 
 Password:
 FreeBSD 9.1-STABLE (K-45-MONITOR) #7: Thu Mar 28 16:18:06 NOVT 2013
 ...
 Edit /etc/motd to change this login announcement.
 $ tty
 /dev/pts/1
 $ w | grep pts/1
 eugen      pts/1    eg.sd.rdtc.ru            19:44       - grep pts/1
 support    pts/1    -                        19:46       - grep pts/1
 
 In this version, login just added another record to utmp. That's just fine.
 
 Now leave nested session:
 
 $ exit
 logout
 $ w|grep pts/1
 eugen      pts/1    eg.sd.rdtc.ru            19:44       - grep pts/1
 $ ls -l `tty`
 crw--w----  1 support  tty  0x96 28  19:47 /dev/pts/1
 $ screen
 Cannot open your terminal '/dev/pts/1' - please check.
 
 As you can see, original problem is still here: terminal ownership has not been restored.
 
 Eugene Grosbein

From: Jilles Tjoelker <jilles@stack.nl>
To: bug-followup@FreeBSD.org, eugen@kuzbass.ru
Cc:  
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Sun, 28 Apr 2013 23:23:05 +0200

 > [nested login(1) does not restore tty ownership]
 
 If it didn't break anything, I would like to "solve" this problem by
 removing /usr/bin/login's setuid bit. You can use su (or sudo from
 ports) to become another user temporarily.
 
 With utmpx, I think the corruption of those files is solved. The utmpx
 code can handle overlapping sessions on the same tty.
 
 The tty ownership is normally reset to root:wheel by the new getty (for
 ttys managed via /etc/ttys) or by the destruction of the tty (for pseudo
 terminals). So it is probably safe to remember the old uid/gid and
 restore it later.
 
 Even with that, there is no isolation between the two users. Since there
 is no new session or revocation (and there cannot be), the nested user
 can continue to access the tty after the "logout". For the same reason,
 the setlogin() call affects both the old and the new user's processes;
 this is not undone afterwards either.
 
 -- 
 Jilles Tjoelker

From: Eitan Adler <lists@eitanadler.com>
To: bug-followup <bug-followup@freebsd.org>
Cc:  
Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
Date: Sun, 28 Apr 2013 17:44:34 -0400

 ---------- Forwarded message ----------
 From: Jilles Tjoelker <jilles@stack.nl>
 Date: 28 April 2013 17:30
 Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
 To: freebsd-bugs@freebsd.org
 
 
 The following reply was made to PR bin/61355; it has been noted by GNATS.
 
 From: Jilles Tjoelker <jilles@stack.nl>
 To: bug-followup@FreeBSD.org, eugen@kuzbass.ru
 Cc:
 Subject: Re: bin/61355: login(1) does not restore terminal ownership on exit
 Date: Sun, 28 Apr 2013 23:23:05 +0200
 
  > [nested login(1) does not restore tty ownership]
 
  If it didn't break anything, I would like to "solve" this problem by
  removing /usr/bin/login's setuid bit. You can use su (or sudo from
  ports) to become another user temporarily.
 
  With utmpx, I think the corruption of those files is solved. The utmpx
  code can handle overlapping sessions on the same tty.
 
  The tty ownership is normally reset to root:wheel by the new getty (for
  ttys managed via /etc/ttys) or by the destruction of the tty (for pseudo
  terminals). So it is probably safe to remember the old uid/gid and
  restore it later.
 
  Even with that, there is no isolation between the two users. Since there
  is no new session or revocation (and there cannot be), the nested user
  can continue to access the tty after the "logout". For the same reason,
  the setlogin() call affects both the old and the new user's processes;
  this is not undone afterwards either.
 
  --
  Jilles Tjoelker
 _______________________________________________
 freebsd-bugs@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
 To unsubscribe, send any mail to "freebsd-bugs-unsubscribe@freebsd.org"
 
 
 -- 
 Eitan Adler
>Unformatted:
