Debian bug report logs -
#988, boring messages
Message sent to debian-devel@pixar.com:
Subject: Bug#988: `script' is insecure, and general tty insecurity
Reply-To: iwj10@cus.cam.ac.uk (Ian Jackson), debian-bugs@pixar.com
Resent-To: debian-devel@pixar.com
Resent-From: iwj10@cus.cam.ac.uk (Ian Jackson)
Resent-Sender: iwj10@cus.cam.ac.uk
Resent-Date: Wed, 14 Jun 1995 13:03:04 GMT
Resent-Message-ID: <debian-bugs-handler.988.06141256209927@pixar.com>
X-Debian-PR-Package: bsdutils
X-Debian-PR-Keywords:
Received: via spool for debian-bugs; Wed, 14 Jun 1995 13:03:04 GMT
Received: with rfc822 via encapsulated-mail id 06141256209927;
Wed, 14 Jun 1995 12:56:20 GMT
Received: from pixar.com by mongo.pixar.com with smtp
(Smail3.1.28.1 #15) id m0sLrxe-0007mTC; Wed, 14 Jun 95 05:54 PDT
Received: from bootes.cus.cam.ac.uk by pixar.com with SMTP id AA25300
(5.67b/IDA-1.5 for debian-bugs-pipe@mongo.pixar.com); Wed, 14 Jun 1995 05:52:52 -0700
Received: by bootes.cus.cam.ac.uk
(Smail-3.1.29.0 #36) id m0sLrxB-000C01C; Wed, 14 Jun 95 13:53 BST
Received: by chiark
id <m0sLrhb-0000XRZ@chiark.al.cl.cam.ac.uk>
(Debian /\oo/\ Smail3.1.29.1 #29.32); Wed, 14 Jun 95 13:37 BST
Message-Id: <m0sLrhb-0000XRZ@chiark.al.cl.cam.ac.uk>
Date: Wed, 14 Jun 95 13:37 BST
From: iwj10@cus.cam.ac.uk (Ian Jackson)
To: Debian bugs submission address <debian-bugs@pixar.com>
Package: bsdutils
Version: 1.2-1
chiark:~> tty
/dev/ttyp3
chiark:~> script
Script started, output file is typescript
chiark:~> tty
/dev/ttyp7
chiark:~> ls -al /dev/ttyp3 /dev/ttyp7
crw--w--w- 1 ian ian 4, 195 Jun 14 13:31 /dev/ttyp3
crw-rw-rw- 1 root root 4, 199 Jun 14 13:31 /dev/ttyp7
chiark:~> exit
exit
Script done, output file is typescript
chiark:~> ls -al /dev/ttyp3 /dev/ttyp7
crw--w--w- 1 ian ian 4, 195 Jun 14 13:31 /dev/ttyp3
crw-rw-rw- 1 root root 4, 199 Jun 14 13:31 /dev/ttyp7
chiark:~>
Clearly /dev/ttyp7 should, while script is running:
* not be readable by everyone
* be owned by the user (so that they can use mesg and biff)
* have mesg off by default
Fixing this will require the intervention of a setuid root program
(either script will have to be setuid or another program will have to
be made).
There may be other security problems, notably races in the pty
allocation.
In general this is a very messy area, and the solutions to the
problems here are likely to involve nontrivial amounts of thought,
coding and/or introduction of additional software. This problem with
programs like `script' is common on many unices, but we should arrange
to find solutions at least for programs we supply.
There are other problems related to having globally-writeable tty's.
IMO tty's should be made group-writeable only by a special group
(conventially called `tty'), to which all programs like `write' and
`talk' will have to be setgid. This is probably a major undertaking,
though, requiring changes to login, telnet, &c &c
Ian.
Message sent:
From: iwj10@thor.cam.ac.uk (Ian Jackson)
To: iwj10@cus.cam.ac.uk (Ian Jackson)
Subject: Bug#988: Acknowledgement (was: `script' is insecure, and general tty insecurity)
In-Reply-To: <m0sLrhb-0000XRZ@chiark.al.cl.cam.ac.uk>
References: <m0sLrhb-0000XRZ@chiark.al.cl.cam.ac.uk>
Thank you for the problem report you have sent regarding Debian GNU/Linux.
This is an automatically generated reply, to let you know your message has
been received. It is being forwarded to the developers' mailing list for
their attention; they will reply in due course.
If you wish to submit further information on your problem, please send
it to debian-bugs@pixar.com, but please ensure that the Subject
line of your message starts with "Bug#988" or "Re: Bug#988" so that
we can identify it as relating to the same problem.
Please do not reply to the address at the top of this message,
unless you wish to report a problem with the bug-tracking system.
Ian Jackson
(maintainer, debian-bugs)
Message sent to debian-devel@pixar.com:
Subject: Bug#988: script' is insecure, and general tty insecurity
Reply-To: bruce@pixar.com (Bruce Perens), debian-bugs@pixar.com
Resent-To: debian-devel@pixar.com
Resent-From: bruce@pixar.com (Bruce Perens)
Resent-Sender: iwj10@cus.cam.ac.uk
Resent-Date: Wed, 14 Jun 1995 19:48:02 GMT
Resent-Message-ID: <debian-bugs-handler.988.061419452012573@pixar.com>
X-Debian-PR-Package: bsdutils
X-Debian-PR-Keywords:
Received: via spool for debian-bugs; Wed, 14 Jun 1995 19:48:02 GMT
Received: with rfc822 via encapsulated-mail id 061419452012573;
Wed, 14 Jun 1995 19:45:20 GMT
Received: from pixar.com by mongo.pixar.com with smtp
(Smail3.1.28.1 #15) id m0sLyMD-0007hOC; Wed, 14 Jun 95 12:44 PDT
Received: from mongo.pixar.com by pixar.com with SMTP id AA16863
(5.67b/IDA-1.5 for debian-bugs-pipe@mongo.pixar.com); Wed, 14 Jun 1995 12:42:42 -0700
Received: by mongo.pixar.com (Smail3.1.28.1 #15)
id m0sLyKr-00051OC; Wed, 14 Jun 95 12:42 PDT
Message-Id: <m0sLyKr-00051OC@mongo.pixar.com>
Date: Wed, 14 Jun 95 12:42 PDT
From: bruce@pixar.com (Bruce Perens)
To: debian-bugs@pixar.com, iwj10@cus.cam.ac.uk (Ian Jackson)
Here is a get_pseudo_tty() function that attempts to jettision pernicious
listeners on the slave side. You can easily hack this to change the slave
to be owned by the real UID. I've also included an execute() function that
redirects input and output to the pseudo-tty. You can see how these are used
and also find a driver for doing asynchronous I/O using the select() system
call if you download the source for ax25-util. The calling sequence for
get_pseudo_tty() and execute() is:
int
main(int argc, char * * argv, char * * environment)
{
int masterFD;
int slaveFD;
static const char * argumentVector = { "/bin/sh", 0 };
masterFD = get_pseudo_tty(&slaveFD);
if ( masterFD < 0 )
complain_and_die();
/*
* Start the client program with input and output directed
* to the slave FD. Do I/O to that from the master FD.
*/
if ( !execute("/bin/sh", argumentVector, environment, slaveFD) )
complain_and_die();
...
}
- Bruce
BEGIN pseudo_tty.c
/* AX.25 Utilities: Attach an interface.
* Bruce Perens, November 1994
*
* Copyright 1994 Bruce Perens.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define NAME_SIZE 64
static const char Prototype[] = "/dev/pty";
#define PROTOTYPE_BASE 5 /* index to "pty" in prototype. */
static int
open_pseudo_tty(const char * name, int * slave)
{
char slaveName[NAME_SIZE];
int master = open(name, O_RDWR, 0);
struct termios t;
if ( master < 0 )
return -1;
strcpy(slaveName, name);
slaveName[PROTOTYPE_BASE] = 't';
/* Close master again to jettison any pernicious listeners on slave
* side. I'd like to be able to lock opens on the slave side while
* this is going on. This won't work if you're not root.
*/
chown(slaveName, 0, 0);
chmod(slaveName, 0600);
close(master);
/*
* Closing the master hung up on any listeners on the slave side. They
* can't open it again unless they are root.
*/
if ( (master = open(name, O_RDWR, 0)) < 0 )
return -1;
if ( (*slave = open(slaveName, O_RDWR, 0)) < 0 ) {
close(master);
return -1;
}
if ( tcgetattr(*slave, &t) == 0 ) {
/*
* Attempt to provide a consistent environment upon open.
* Of course if you are running a script you can override
* this by running stty.
*/
t.c_cc[VINTR] = 'c' & 0x1f;
t.c_cc[VQUIT] = '\\' & 0x1f;
t.c_cc[VERASE] = 'h' & 0x1f;
t.c_cc[VKILL] = 'u' & 0x1f;
t.c_cc[VEOF] = 'd' & 0x1f;
t.c_cc[VEOL] = '\n';
t.c_cc[VSTOP] = 's' & 0x1f;
t.c_cc[VSTART] = 'q' & 0x1f;
t.c_cc[VSUSP] = 'z' & 0x1f;
t.c_cc[VLNEXT] = 'v' & 0x1f;
t.c_cc[VWERASE] = 'w' & 0x1f;
t.c_cc[VREPRINT]= 'r' & 0x1f;
t.c_cc[VDISCARD]= 'o' & 0x1f;
t.c_iflag = BRKINT|ICRNL;
t.c_oflag = OPOST;
t.c_cflag = B9600|CS8|CREAD|HUPCL;
t.c_lflag = ISIG|ICANON|ECHO|ECHOE;
t.c_line = 0;
tcsetattr(*slave, TCSANOW, &t);
}
return master;
}
int
get_pseudo_tty(int * slave)
{
char name[NAME_SIZE];
char * const ones = &name[sizeof(Prototype)];
char * const tens = &name[sizeof(Prototype) - 1];
strcpy(name, Prototype);
name[sizeof(Prototype) + 1] = '\0';
for ( *tens = 'p'; *tens <= 's'; ++*tens ) {
int n;
for ( n = 0; n < 16; n++ ) {
static const char Hexits[16] = "0123456789abcdef";
int master;
*ones = Hexits[n];
master = open_pseudo_tty(name, slave);
if ( master >= 0 )
return master;
}
}
return -1;
}
BEGIN execute.c
/* AX.25 Utilities: Run a program, with input and output directed
* to a file descriptor.
*
*
* Bruce Perens, November 1994
*
* Copyright 1994 Bruce Perens.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
int
execute(
const char * file
,char * const * argv
,char * const * envp
,int ioFile)
{
int pid;
signal(SIGCLD, SIG_IGN); /* No zombies */
pid = fork();
if ( pid < 0 )
return -1;
else if ( pid == 0 ) {
/* In the child process */
int max = (int)sysconf(_SC_OPEN_MAX);
int fd;
int n;
for ( fd = 0; fd < max; fd++ ) {
if ( fd != ioFile )
close(fd);
}
/*
* If the IO file isn't 0, 1, or 2, I'm starting a new
* session on some other device.
*/
if ( ioFile > 2 )
setsid();
for ( fd = 0; fd <= 2; fd++ ) {
if ( fd != ioFile && dup2(ioFile, fd) != fd )
_exit(-1);
}
if ( ioFile > 2 )
close(ioFile);
/*
* Try to give the process as pristine an environment
* as possible.
*/
for ( n = 0; n < NSIG; n++ )
signal(n, SIG_DFL);
/*
* If I started a new session above, set the tty process
* group to match it.
*/
if ( ioFile > 2 )
tcsetpgrp(0, getpgrp());
execve(file, argv, envp);
_exit(-1);
}
return pid;
}
--
-- Attention Ham Radio Operators: For information on "Linux for Hams", read
-- the World Wide Web page http://www.hams.com/perens/LinuxForHams, or send
-- an e-mail message containing the word "help" to info@hams.com .
Message sent:
From: iwj10@thor.cam.ac.uk (Ian Jackson)
To: bruce@pixar.com (Bruce Perens)
Subject: Bug#988: Info received (was Bug#988: `script' is insecure, and general tty insecurity)
In-Reply-To: <m0sLyKr-00051OC@mongo.pixar.com>
References: <m0sLyKr-00051OC@mongo.pixar.com>
Thank you for the additional information you have supplied regarding
this problem report. It has been forwarded to the developers to
accompany the original report.
If you wish to continue to submit further information on your problem,
please do the same thing again: send it to debian-bugs@pixar.com, ensuring
that the Subject line starts with "Bug#988" or "Re: Bug#988" so that
we can identify it as relating to the same problem.
Please do not reply to the address at the top of this message,
unless you wish to report a problem with the bug-tracking system.
Ian Jackson
(maintainer, debian-bugs)
Ian Jackson /
iwj10@thor.cam.ac.uk,
with the debian-bugs tracking mechanism