From 1cc4f6be7a968e4277653e99cf7f468492ec7d0f Mon Sep 17 00:00:00 2001 From: "Andrew V. Samoilov" Date: Thu, 16 Nov 2000 17:09:08 +0000 Subject: [PATCH] * cons.saver.c (check_file): close fd on error. There was a bug, which allowed luser to write '\0' char to any symlinkable file in Linux system which don't ensure that fd's 0, 1, and 2 are open on startup of a SUID/SGID binary. Based on patch from bugtrack by Maurycy Prodeus . --- src/ChangeLog | 8 +++++++ src/cons.saver.c | 59 ++++++++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d694c3190..c0047c25a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2000-11-16 Andrew V. Samoilov + + * cons.saver.c (check_file): close fd on error. There was a bug, which + allowed luser to write '\0' char to any symlinkable file in Linux + system which don't ensure that fd's 0, 1, and 2 are open on startup + of a SUID/SGID binary. + Based on patch from bugtrack by Maurycy Prodeus . + 2000-11-14 Andrew V. Samoilov * layout.c (print_vfs_message): format string vulnerability fixed diff --git a/src/cons.saver.c b/src/cons.saver.c index 09f31a5e9..735d6da5b 100644 --- a/src/cons.saver.c +++ b/src/cons.saver.c @@ -42,6 +42,7 @@ #include #include #include /* For isdigit() */ +#include typedef struct WINDOW WINDOW; #include "cons.saver.h" @@ -116,39 +117,43 @@ int check_file (char *filename, int check_console, char **msg) if (fd == -1) return -1; - if (fstat (fd, &stat_buf) == -1) - return -1; + do { + if (fstat (fd, &stat_buf) == -1) + break; - /* Must be character device */ - if (!S_ISCHR (stat_buf.st_mode)){ - *msg = "Not a character device"; - return -1; - } + /* Must be character device */ + if (!S_ISCHR (stat_buf.st_mode)){ + *msg = "Not a character device"; + break; + } #ifdef DEBUG - fprintf (stderr, "Device: %x\n", stat_buf.st_rdev); + fprintf (stderr, "Device: %x\n", stat_buf.st_rdev); #endif - if (check_console){ - /* Second time: must be console */ - if ((stat_buf.st_rdev & 0xff00) != 0x0400){ - *msg = "Not a console"; - return -1; + if (check_console){ + /* Second time: must be console */ + if ((stat_buf.st_rdev & 0xff00) != 0x0400){ + *msg = "Not a console"; + break; + } + + if ((stat_buf.st_rdev & 0x00ff) > 63){ + *msg = "Minor device number too big"; + break; + } + + /* Must be owned by the user */ + if (stat_buf.st_uid != getuid ()){ + *msg = "Not a owner"; + break; + } } - - if ((stat_buf.st_rdev & 0x00ff) > 63){ - *msg = "Minor device number too big"; - return -1; - } - - /* Must be owned by the user */ - if (stat_buf.st_uid != getuid ()){ - *msg = "Not a owner"; - return -1; - } - } - /* Everything seems to be okay */ - return fd; + return fd; + } while (0); + + close (fd); + return -1; } /* Detect console */