]> granicus.if.org Git - procps-ng/commitdiff
Do not let sysctl abort due a missed file or directory under /proc.
authorWerner Fink <werner@suse.de>
Mon, 20 Dec 2010 12:22:24 +0000 (13:22 +0100)
committerJan Görig <jgorig@redhat.com>
Wed, 19 Jan 2011 11:26:01 +0000 (12:26 +0100)
Include signal.h for compiling w.

Signed-off-by: Werner Fink <werner@suse.de>
sysctl.c
w.c

index 1470df9a1c9b36b6c58b611b57fe2f565e0f05d8..9be79ce1d125c4505bee4623f0ee96ef1dfeb9d1 100644 (file)
--- 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 c2e996a8185d1d2a14cd46eb31e60c5dde3cd1d7..f479433c4b395c77cf60a92b6185c8c4aec0e708 100644 (file)
--- 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>