]> granicus.if.org Git - mutt/commitdiff
[patch-0.94.5i.tlr.safe_symlink.1] Introduce
authorThomas Roessler <roessler@does-not-exist.org>
Sun, 6 Sep 1998 10:05:41 +0000 (10:05 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Sun, 6 Sep 1998 10:05:41 +0000 (10:05 +0000)
safe_symlink() for /tmp-safe symlinking in the
nametemplate code.

TODO
attach.c
lib.c
protos.h

diff --git a/TODO b/TODO
index c6489b1054370893fafb9b8a3c88f1873e6b1dcc..c46d082afbb893153a78af86975cd455a80891d3 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,10 +1,5 @@
 Problems are listed in approximate order of priority.
 
-- Re-visit nametemplate support.  Currently, we use
-  symbolic links in our temporary directory for this. When
-  using /tmp, this may have security implementations and
-  introduce race conditions.
-
 
 - Fix the "unexpected EXPUNGE" IMAP bug.
 
index 5492d61a4760b34a57afb279e77f726082e426ac..e9ee861fe369ece7013d0877392903f83755765c 100644 (file)
--- a/attach.c
+++ b/attach.c
@@ -106,7 +106,7 @@ int mutt_compose_attachment (BODY *a)
       {
        dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",
                                  a->filename, newfile));
-       if (symlink (a->filename, newfile) == -1)
+       if (safe_symlink (a->filename, newfile) == -1)
        {
          if (!mutt_yesorno ("Can't match nametemplate, continue?", 1))
            goto bailout;
@@ -228,7 +228,7 @@ int mutt_edit_attachment (BODY *a)
       {
        dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",
                                  a->filename, newfile));
-       if (symlink (a->filename, newfile) == -1)
+       if (safe_symlink (a->filename, newfile) == -1)
        {
          if (!mutt_yesorno ("Can't match nametemplate, continue?", 1))
            goto bailout;
@@ -360,7 +360,7 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
       if (fp == NULL)
       {
        /* send case: the file is already there */
-       if (symlink (a->filename, tempfile) == -1)
+       if (safe_symlink (a->filename, tempfile) == -1)
        {
          if (mutt_yesorno ("Can't match nametemplate, continue?", 1) == M_YES)
            strfcpy (tempfile, a->filename, sizeof (tempfile));
@@ -807,7 +807,7 @@ int mutt_print_attachment (FILE *fp, BODY *a)
     {
       if (!fp)
       {
-       if (symlink(a->filename, newfile) == -1)
+       if (safe_symlink(a->filename, newfile) == -1)
        {
          if (mutt_yesorno ("Can't match nametemplate, continue?", 1) != M_YES)
          {
diff --git a/lib.c b/lib.c
index 45d901d35f81590fa4b01f69c255a729762b1176..3d889c007e4e7b93f7ead1fe3d65e14f9c1d456a 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -656,6 +656,41 @@ void mutt_expand_fmt (char *dest, size_t destlen, const char *fmt, const char *s
   FREE(&_src);
 }
 
+static int 
+compare_stat (struct stat *osb, struct stat *nsb)
+{
+  if (osb->st_dev != nsb->st_dev || osb->st_ino != nsb->st_ino ||
+      osb->st_rdev != nsb->st_rdev)
+  {
+    return -1;
+  }
+
+  return 0;
+}
+
+int safe_symlink(const char *oldpath, const char *newpath)
+{
+  struct stat osb, nsb;
+
+  if(!oldpath || !newpath)
+    return -1;
+  
+  if(unlink(newpath) == -1 && errno != ENOENT)
+    return -1;
+  
+  if(symlink(oldpath, newpath) == -1)
+    return -1;
+  
+  if(stat(oldpath, &osb) == -1 || stat(newpath, &nsb) == -1
+     || compare_stat(&osb, &nsb) == -1)
+  {
+    unlink(newpath);
+    return -1;
+  }
+  
+  return 0;
+}
+
 int safe_open (const char *path, int flags)
 {
   struct stat osb, nsb;
@@ -666,8 +701,7 @@ int safe_open (const char *path, int flags)
 
   /* make sure the file is not symlink */
   if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
-      osb.st_dev != nsb.st_dev || osb.st_ino != nsb.st_ino ||
-      osb.st_rdev != nsb.st_rdev)
+      compare_stat(&osb, &nsb) == -1)
   {
     dprint (1, (debugfile, "safe_open(): %s is a symlink!\n", path));
     close (fd);
index b349dca420086de59a5d85f07b1c6db1d174832f..ad2583e2b02dee531feaa17a250a1a8684dca025 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -282,6 +282,7 @@ void safe_realloc (void **, size_t);
 void safe_free (void **);
 
 int safe_open (const char *, int);
+int safe_symlink (const char *, const char *);
 FILE *safe_fopen (const char *, const char *);
 
 ADDRESS *alias_reverse_lookup (ADDRESS *);