1
1

* cons.saver.c: New variable console_minor. Eliminate variables

len and vcs_name.
(check_file): Set console_minor to the minor device number of
the console. Disallow /dev/tty0.
(detect_console): Don't parse tty_name, instead make sure that
it corresponds to console_minor. Check console first. Fallback
to /dev/vcc/a* if /dev/vcsa* cannot be opened.
(save_console): Use console_minor.
(restore_console): Likewise.
Этот коммит содержится в:
Pavel Roskin 2001-07-06 19:24:27 +00:00
родитель a44f9422d2
Коммит 91a799e3c0
2 изменённых файлов: 50 добавлений и 26 удалений

Просмотреть файл

@ -1,5 +1,15 @@
2001-07-06 Pavel Roskin <proski@gnu.org> 2001-07-06 Pavel Roskin <proski@gnu.org>
* cons.saver.c: New variable console_minor. Eliminate variables
len and vcs_name.
(check_file): Set console_minor to the minor device number of
the console. Disallow /dev/tty0.
(detect_console): Don't parse tty_name, instead make sure that
it corresponds to console_minor. Check console first. Fallback
to /dev/vcc/a* if /dev/vcsa* cannot be opened.
(save_console): Use console_minor.
(restore_console): Likewise.
* cons.saver.c (check_file): Eliminate using text messages to * cons.saver.c (check_file): Eliminate using text messages to
indicate errors. Improve debug messages. indicate errors. Improve debug messages.
(detect_console): Likewise. (detect_console): Likewise.

Просмотреть файл

@ -64,11 +64,10 @@ static signed char console_flag = -1;
*/ */
static int console_fd = -1; static int console_fd = -1;
static char *tty_name; static char *tty_name;
static int len; static int console_minor = 0;
static char *buffer = NULL; static char *buffer = NULL;
static int buffer_size = 0; static int buffer_size = 0;
static int columns, rows; static int columns, rows;
static char vcs_name [128];
static int vcs_fd; static int vcs_fd;
static void dwrite (int fd, char *buffer) static void dwrite (int fd, char *buffer)
@ -138,8 +137,9 @@ static int check_file (char *filename, int check_console)
break; break;
} }
/* Minor number must be below 64 */ /* Minor number must be between 1 and 63 */
if ((stat_buf.st_rdev & 0x00ff) > 63){ console_minor = (int) (stat_buf.st_rdev & 0x00ff);
if (console_minor < 1 || console_minor > 63){
break; break;
} }
@ -162,26 +162,44 @@ static int check_file (char *filename, int check_console)
creating a security hole */ creating a security hole */
static int detect_console (void) static int detect_console (void)
{ {
int xlen; char console_name [16];
static char vcs_name [16];
/* Must be console */
/* Handle the case for /dev/tty?? and /dev/vc/?? */
if (tty_name[len-5] == 't' || tty_name[len-5] == 'v')
xlen = len - 1;
else
xlen = len;
/* General: /dev/ttyn and /dev/vc/n */ /* Must be console */
if (tty_name[xlen - 5] != '/' || console_fd = check_file (tty_name, 1);
! (strncmp(tty_name+xlen-4,"tty",3) == 0 || if (console_fd == -1)
strncmp(tty_name+xlen-4,"vc/",3) == 0) ||
!isdigit(tty_name[xlen - 1]) ||
!isdigit(tty_name[len - 1]))
return -1; return -1;
snprintf (vcs_name, sizeof (vcs_name), "/dev/vcsa%s", tty_name + xlen - 1); /*
* Only allow /dev/ttyMINOR and /dev/vc/MINOR where MINOR is the minor
* device number of the console, set in check_file()
*/
switch (tty_name[5])
{
case 'v':
snprintf (console_name, sizeof (console_name), "/dev/vc/%d",
console_minor);
if (strncmp (console_name, tty_name, sizeof (console_name)) != 0)
return -1;
break;
case 't':
snprintf (console_name, sizeof (console_name), "/dev/tty%d",
console_minor);
if (strncmp (console_name, tty_name, sizeof (console_name)) != 0)
return -1;
break;
default:
return -1;
}
snprintf (vcs_name, sizeof (vcs_name), "/dev/vcsa%d", console_minor);
vcs_fd = check_file (vcs_name, 0); vcs_fd = check_file (vcs_name, 0);
console_fd = check_file (tty_name, 1);
/* Try devfs name */
if (vcs_fd == -1) {
snprintf (vcs_name, sizeof (vcs_name), "/dev/vcc/a%d", console_minor);
vcs_fd = check_file (vcs_name, 0);
}
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "vcs_fd = %d console_fd = %d\r\n", vcs_fd, console_fd); fprintf (stderr, "vcs_fd = %d console_fd = %d\r\n", vcs_fd, console_fd);
@ -191,9 +209,6 @@ static int detect_console (void)
console_flag = 3; console_flag = 3;
} }
if (console_fd == -1)
return -1;
return 0; return 0;
} }
@ -203,7 +218,7 @@ static void save_console (void)
if (!console_flag) if (!console_flag)
return; return;
buffer [1] = tty_name [len-1] - '0'; buffer [1] = console_minor;
if (console_flag >= 2){ if (console_flag >= 2){
/* Linux >= 1.1.67 */ /* Linux >= 1.1.67 */
/* Get screen contents and cursor position */ /* Get screen contents and cursor position */
@ -256,7 +271,7 @@ static void restore_console (void)
/* Linux >= 1.1.67 */ /* Linux >= 1.1.67 */
/* Restore screen contents and cursor position */ /* Restore screen contents and cursor position */
buffer [0] = 9; buffer [0] = 9;
buffer [1] = tty_name [len-1] - '0'; buffer [1] = console_minor;
ioctl (console_fd, TIOCLINUX, buffer); ioctl (console_fd, TIOCLINUX, buffer);
} }
if (console_flag == 3){ if (console_flag == 3){
@ -357,7 +372,6 @@ int main (int argc, char **argv)
/* Check that the argument is a legal console */ /* Check that the argument is a legal console */
tty_name = argv [1]; tty_name = argv [1];
len = strlen(tty_name);
if (detect_console () == -1){ if (detect_console () == -1){
/* Not a console -> no need for privileges */ /* Not a console -> no need for privileges */