[procps] [PATCH 2/4] Do not let sysctl abort due a missed file or directory under /proc.

  • From: Werner Fink <werner@xxxxxxx>
  • To: undisclosed-recipients: ;
  • Date: Mon, 20 Dec 2010 13:22:24 +0100

 Do not let sysctl abort due a missed file or directory under /proc.
 Inlcude signal.h for compiling w.

Signed-off-by: Werner Fink <werner@xxxxxxx>

diff --git a/sysctl.c b/sysctl.c
index 1470df9..9be79ce 100644
--- a/sysctl.c
+++ b/sysctl.c
@@ -128,6 +128,7 @@ static int ReadSetting(const char *restrict const name) {
    char *restrict outname;
    char inbuf[1025];
    FILE *restrict fp;
+   struct stat ts;
 
    if (!name || !*name) {
       fprintf(stderr, ERR_INVALID_KEY, name);
@@ -144,6 +145,25 @@ static int ReadSetting(const char *restrict const name) {
    outname = strdup(name);
    slashdot(outname,'/','.'); /* change / to . */
 
+   if (stat(tmpname, &ts) < 0) {
+      if (!IgnoreError) {
+         perror(tmpname);
+         rc = -1;
+      }
+      goto out;
+   }
+   if ((ts.st_mode & S_IRUSR) == 0)
+      goto out;
+
+   if (S_ISDIR(ts.st_mode)) {
+      size_t len;
+      len = strlen(tmpname);
+      tmpname[len] = '/';
+      tmpname[len+1] = '\0';
+      rc = DisplayAll(tmpname);
+      goto out;
+   }
+
    fp = fopen(tmpname, "r");
 
    if (!fp) {
@@ -164,6 +184,7 @@ static int ReadSetting(const char *restrict const name) {
          break;
       }
    } else {
+      errno = 0;
       if(fgets(inbuf, sizeof inbuf - 1, fp)) {
          // this loop is required, see
          // /sbin/sysctl -a | egrep -6 dev.cdrom.info
@@ -194,18 +215,20 @@ static int ReadSetting(const char *restrict const name) {
             len = strlen(tmpname);
             tmpname[len] = '/';
             tmpname[len+1] = '\0';
+            fclose(fp);
             rc = DisplayAll(tmpname);
-            break;
+            goto out;
          }
          default:
             fprintf(stderr, ERR_UNKNOWN_READING, strerror(errno), outname);
             rc = -1;
+         case 0:
             break;
          }
       }
       fclose(fp);
    }
-
+out:
    free(tmpname);
    free(outname);
    return rc;
@@ -265,8 +288,9 @@ static int WriteSetting(const char *setting) {
    const char *value;
    const char *equals;
    char *tmpname;
-   FILE *fp;
    char *outname;
+   FILE *fp;
+   struct stat ts;
 
    if (!name) {        /* probably don't want to display this err */
       return 0;
@@ -299,6 +323,24 @@ static int WriteSetting(const char *setting) {
    outname[equals-name] = 0;
    slashdot(outname,'/','.'); /* change / to . */
  
+   if (stat(tmpname, &ts) < 0) {
+      if (!IgnoreError) {
+         perror(tmpname);
+         rc = -1;
+      }
+      goto out;
+   }
+
+   if ((ts.st_mode & S_IWUSR) == 0) {
+      fprintf(stderr, ERR_UNKNOWN_WRITING, strerror(EACCES), outname);
+      goto out;
+   }
+
+   if (S_ISDIR(ts.st_mode)) {
+      fprintf(stderr, ERR_UNKNOWN_WRITING, strerror(EACCES), outname);
+      goto out;
+   }
+
    fp = fopen(tmpname, "w");
 
    if (!fp) {
@@ -343,7 +385,7 @@ static int WriteSetting(const char *setting) {
          }
       }
    }
-
+out:
    free(tmpname);
    free(outname);
    return rc;
diff --git a/w.c b/w.c
index c2e996a..f479433 100644
--- a/w.c
+++ b/w.c
@@ -15,6 +15,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-- 
1.6.0.2


Other related posts:

  • » [procps] [PATCH 2/4] Do not let sysctl abort due a missed file or directory under /proc. - Werner Fink