On Sat, Oct 07, 2006 at 03:32:45PM +0200, Bram Moolenaar wrote:
> > here comes another bug report from the Debian bug tracking system, with
> > a small security issue.
> > 
> > Quoting from http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=290507:
> > 
> > >  Vim does not close temporary file (.file.swp) when executing shell, so
> > > program executed in shell can read and write from/to that file, even if
> > > It is not possible with normal command invocation. Not sure wheter it is
> > > really recurity problem though.
> > > 
> > >  Example:
> > > 
> > > # cd
> > > # vim file
> > > [edit file and enter :sh to run shell]
> > > # su user
> > > $ ls -l .file.swp
> > > ls: .file.swp: Permission denied
> > > $ ls -l /proc/self/fd
> > > ...
> > > lrwx------  1 user user 64 2005-01-14 15:55 11 -> /root/.file.swp
> > > ...
> > > $ echo -e '\nqwerty' >&11
> > > $ ^D
> > > # tail -1 .file.swp
> > > qwerty
> > > #
> > 
> > What's your opinion on this? Do you consider it a bug or not?
> 
> It's very normal for a program to keep files open when executing a shell
> command.  I don't see why Vim should close files before executing a
> shell command.
> 
> If there is a security issue it's that Linux allows writing directly
> into a file descriptor from another process.  In my opinion only a
> process itself should be able to do that.
> 
> Hmm, perhaps the problem is that system() or execvp() doesn't close the
> file descriptors in a child process?

Indeed, that is the case.  Children inherit their parent's file
descriptors unless the file descriptors are set to close on exec().
Attached patch does that.

-- 
James
GPG Key: 1024D/61326D40 2003-09-02 James Vega <[email protected]>
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 1108ab9..0b788f4 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -2801,7 +2801,6 @@ source_level(cookie)
 
 static char_u *get_one_sourceline __ARGS((struct source_cookie *sp));
 
-#if defined(WIN32) && defined(FEAT_CSCOPE)
 static FILE *fopen_noinh_readbin __ARGS((char *filename));
 
 /*
@@ -2811,13 +2810,21 @@ static FILE *fopen_noinh_readbin __ARGS((char *filename));
 fopen_noinh_readbin(filename)
     char    *filename;
 {
-    int	fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
+    int	fd_tmp = mch_open(filename, O_RDONLY
+#ifdef WIN32
+			  O_BINARY | O_NOINHERIT
+#endif
+			  , 0);
 
     if (fd_tmp == -1)
 	return NULL;
+#ifdef UNIX
+    else
+	fcntl(fd_tmp, F_SETFD, FD_CLOEXEC);
+#endif
+
     return fdopen(fd_tmp, READBIN);
 }
-#endif
 
 
 /*
@@ -2894,11 +2901,7 @@ do_source(fname, check_other, is_vimrc)
     apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
 #endif
 
-#if defined(WIN32) && defined(FEAT_CSCOPE)
     cookie.fp = fopen_noinh_readbin((char *)fname_exp);
-#else
-    cookie.fp = mch_fopen((char *)fname_exp, READBIN);
-#endif
     if (cookie.fp == NULL && check_other)
     {
 	/*
@@ -2915,11 +2918,7 @@ do_source(fname, check_other, is_vimrc)
 		*p = '.';
 	    else
 		*p = '_';
-#if defined(WIN32) && defined(FEAT_CSCOPE)
 	    cookie.fp = fopen_noinh_readbin((char *)fname_exp);
-#else
-	    cookie.fp = mch_fopen((char *)fname_exp, READBIN);
-#endif
 	}
     }
 
diff --git a/src/fileio.c b/src/fileio.c
index b17806b..00c2f6c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2252,6 +2252,10 @@ failed:
 
     if (!read_buffer && !read_stdin)
 	close(fd);				/* errors are ignored */
+#ifdef UNIX
+    else
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
     vim_free(buffer);
 
 #ifdef HAVE_DUP
diff --git a/src/memfile.c b/src/memfile.c
index 0b3cdd9..b1ca017 100644
--- a/src/memfile.c
+++ b/src/memfile.c
@@ -1347,5 +1347,8 @@ mf_do_open(mfp, fname, flags)
 	mch_copy_sec(fname, mfp->mf_fname);
 #endif
 	mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
+#ifdef UNIX
+	fcntl(mfp->mf_fd, F_SETFD, FD_CLOEXEC);
+#endif
     }
 }
diff --git a/src/memline.c b/src/memline.c
index 8c8019a..707ab92 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -490,6 +490,12 @@ ml_setname(buf)
 	    EMSG(_("E301: Oops, lost the swap file!!!"));
 	    return;
 	}
+#ifdef UNIX
+	else
+	{
+	    fcntl(mfp->mf_fd, F_SETFD, FD_CLOEXEC);
+	}
+#endif
     }
     if (!success)
 	EMSG(_("E302: Could not rename swap file"));

Attachment: signature.asc
Description: Digital signature

Reply via email to