Author: timb
Date: 2008-10-05 12:04:08 +0200 (Sun, 05 Oct 2008)
New Revision: 1486

Modified:
   trunk/openvas-libnasl/ChangeLog
   trunk/openvas-libnasl/nasl/nasl_cmd_exec.c
Log:
Fixed potential symlink attacks against fread, fwrite and file_open NASL 
functions


Modified: trunk/openvas-libnasl/ChangeLog
===================================================================
--- trunk/openvas-libnasl/ChangeLog     2008-10-04 07:54:24 UTC (rev 1485)
+++ trunk/openvas-libnasl/ChangeLog     2008-10-05 10:04:08 UTC (rev 1486)
@@ -1,3 +1,8 @@
+2008-10-05  Tim Brown <[EMAIL PROTECTED]>
+
+       * nasl/nasl_cmd_exec.c: Fixed potential symlink attacks against fread,
+       fwrite and file_open NASL functions.
+
 2008-09-24  Michael Wiegand <[EMAIL PROTECTED]>
 
        Post release version bump.

Modified: trunk/openvas-libnasl/nasl/nasl_cmd_exec.c
===================================================================
--- trunk/openvas-libnasl/nasl/nasl_cmd_exec.c  2008-10-04 07:54:24 UTC (rev 
1485)
+++ trunk/openvas-libnasl/nasl/nasl_cmd_exec.c  2008-10-05 10:04:08 UTC (rev 
1486)
@@ -233,7 +233,8 @@
 {
   tree_cell    *retc;
   char         *fname;
-  struct stat  st;
+  struct stat   lstat_info, fstat_info;
+  int          fd;
   char         *buf, *p;
   int          alen, len, n;
   FILE         *fp;
@@ -246,19 +247,41 @@
       nasl_perror(lexic, "fread: need one argument (file name)\n");
       return NULL;
     }
-  
-  if (stat(fname, &st) < 0)
-    {
-      nasl_perror(lexic, "fread: stat(%s): %s\n", fname, strerror(errno));
+
+  if (lstat(fname, &lstat_info) == -1) {
+    if (errno != ENOENT) {
+      nasl_perror(lexic, "fread: %s: %s\n", fname, strerror(errno));
       return NULL;
     }
-
-  fp = fopen(fname, "r");
-  if (fp == NULL)
-    {
+    fd = open(fname, O_RDONLY, 0600);
+    if (fd < 0) {
       nasl_perror(lexic, "fread: %s: %s\n", fname, strerror(errno));
       return NULL;
     }
+  } else {
+    fd = open(fname, O_RDONLY, 0600);
+    if (fd < 0) {
+      nasl_perror(lexic, "fread: %s: possible symlink attack!?! %s\n", fname, 
strerror(errno));
+      return NULL;
+    }
+    if (fstat(fd, &fstat_info) == -1) {
+        close(fd);
+        nasl_perror(lexic, "fread: %s: possible symlink attack!?! %s\n", 
fname, strerror(errno));
+        return NULL;
+    } else {
+      if (lstat_info.st_mode != fstat_info.st_mode || lstat_info.st_ino != 
fstat_info.st_ino || lstat_info.st_dev != fstat_info.st_dev) {
+        close(fd);
+        nasl_perror(lexic, "fread: %s: possible symlink attack!?!\n", fname);
+        return NULL;
+      }
+    }
+  }
+  fp = fdopen(fd, "r");
+  if(fp != FALSE) {
+    close(fp);
+    nasl_perror(lexic, "fread: %s: %s\n", fname, strerror(errno));
+    return NULL;
+  }
 
   alen = st.st_size + 1;
   buf = emalloc(alen);
@@ -338,6 +361,8 @@
 {
   tree_cell    *retc;
   char         *content, *fname;
+  struct stat   lstat_info, fstat_info;
+  int          fd;
   int          len, i, x;
   FILE         *fp;
 
@@ -356,12 +381,41 @@
     }
   len = get_var_size_by_name(lexic, "data");
   
-  fp = fopen(fname, "w");
-  if (fp == NULL)
-    {
+  if (lstat(fname, &lstat_info) == -1) {
+    if (errno != ENOENT) {
       nasl_perror(lexic, "fwrite: %s: %s\n", fname, strerror(errno));
       return NULL;
     }
+    fd = open(fname, O_WRONLY|O_CREAT, 0600);
+    if (fd < 0) {
+      nasl_perror(lexic, "fwrite: %s: %s\n", fname, strerror(errno));
+      return NULL;
+    }
+  } else {
+    fd = open(fname, O_WRONLY|O_CREAT, 0600);
+    if (fd < 0) {
+      nasl_perror(lexic, "fwrite: %s: possible symlink attack!?! %s\n", fname, 
strerror(errno));
+      return NULL;
+    }
+    if (fstat(fd, &fstat_info) == -1) {
+        close(fd);
+        nasl_perror(lexic, "fread: %s: possible symlink attack!?! %s\n", 
fname, strerror(errno));
+        return NULL;
+    } else {
+      if (lstat_info.st_mode != fstat_info.st_mode || lstat_info.st_ino != 
fstat_info.st_ino || lstat_info.st_dev != fstat_info.st_dev) {
+        close(fd);
+        nasl_perror(lexic, "fread: %s: possible symlink attack!?!\n", fname);
+        return NULL;
+      }
+    }
+  }
+  fp = fdopen(fd, "w");
+  if (fp != FALSE) {
+    close(fp);
+    nasl_perror(lexic, "fread: %s: %s\n", fname, strerror(errno));
+    return NULL;
+  }
+
   for (i = 0; i < len; )
     {
       x = fwrite(content + i, 1, len - i, fp);
@@ -445,6 +499,7 @@
 {
   tree_cell    *retc;
   char         *fname, *mode;
+  struct stat   lstat_info, fstat_info;
   int          fd; 
   int          imode = O_RDONLY;
 
@@ -475,12 +530,34 @@
    else if ( strcmp(mode, "a+") == 0 )
        imode = O_RDWR|O_APPEND|O_CREAT;
 
-  fd = open(fname, imode, 0600);
-  if ( fd < 0 )
-    {
+  if (lstat(fname, &lstat_info) == -1) {
+    if (errno != ENOENT) {
       nasl_perror(lexic, "file_open: %s: %s\n", fname, strerror(errno));
       return NULL;
     }
+    fd = open(fname, imode, 0600);
+    if (fd < 0) {
+      nasl_perror(lexic, "file_open: %s: %s\n", fname, strerror(errno));
+      return NULL;
+    }
+  } else {
+    fd = open(fname, imode, 0600);
+    if (fd < 0) {
+      nasl_perror(lexic, "file_open: %s: possible symlink attack!?! %s\n", 
fname, strerror(errno));
+      return NULL;
+    }
+    if (fstat(fd, &fstat_info) == -1) {
+        close(fd);
+        nasl_perror(lexic, "fread: %s: possible symlink attack!?! %s\n", 
fname, strerror(errno));
+        return NULL;
+    } else {
+      if (lstat_info.st_mode != fstat_info.st_mode || lstat_info.st_ino != 
fstat_info.st_ino || lstat_info.st_dev != fstat_info.st_dev) {
+        close(fd);
+        nasl_perror(lexic, "fread: %s: possible symlink attack!?!\n", fname);
+        return NULL;
+      }
+    }
+  }
 
   retc = alloc_typed_cell(CONST_INT);
   retc->x.i_val = fd;

_______________________________________________
Openvas-commits mailing list
[email protected]
http://lists.wald.intevation.org/mailman/listinfo/openvas-commits

Reply via email to