add patch that stops screen from writing to a file when the last component

of the filename is  a symbolic link. Note: in some cases the file may still
be opened which can in itself be a problem.  This solves the security
hole where the bad-guy creates a symbolic link named /tmp/screen-exchange
pointing to a file that s/he wishes root to clobber.
This commit is contained in:
marc 1998-07-28 21:18:48 +00:00
parent 6c0a6df234
commit b41f97a782

View File

@ -0,0 +1,64 @@
--- fileio.c.~1~ Thu May 1 08:50:25 1997
+++ fileio.c Mon Jul 27 17:49:58 1998
@@ -291,6 +291,52 @@
DoCommand(args);
}
+/*
+ * Attempt to determine if we're opening the named file or if it
+ * has been replaced by a symbolic link to someplace not nice.
+ * Algorithm is:
+ *
+ * 1) lstat( name );
+ * if a symbolic link don't even try the open
+ * 2) fd = open( name );
+ * 3) fstat( fd );
+ * 4) lstat( name );
+ * 5) if fstat st_dev and st_ino don't match the lstat values
+ * then we lost a race and someone added a link between
+ * the first lstat and the open. Close the file and
+ * log an error. Note: this can still cause problems;
+ * e.g. a link to /dev/st0 will cause a tape to be
+ * rewound when the file is closed.
+ */
+static FILE *
+NoLinkOpen( char * fn, char * mode )
+{
+ struct stat linkstat;
+ struct stat filestat;
+ FILE * f;
+
+ if ( lstat( fn, &linkstat ) == 0 &&
+ linkstat.st_mode == S_IFLNK )
+ goto err;
+
+ f = fopen( fn, mode );
+ if ( ! f )
+ return 0;
+
+ if ( fstat( fileno( f ), &filestat ) == 0 &&
+ lstat( fn, &linkstat ) == 0 &&
+ linkstat.st_mode != S_IFLNK &&
+ linkstat.st_dev == filestat.st_dev &&
+ linkstat.st_ino == filestat.st_ino )
+ return f;
+
+ fclose( f );
+
+ err:
+ Msg(0, "Warning: file not opened, \"%s\" is a symbolic link.", fn);
+ return 0;
+}
+
void
WriteFile(dump)
int dump;
@@ -337,7 +383,7 @@
if (UserContext() > 0)
{
debug("Writefile: usercontext\n");
- if ((f = fopen(fn, mode)) == NULL)
+ if ((f = NoLinkOpen(fn, mode)) == NULL)
{
debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode);
UserReturn(0);