Source: psmisc
Version: 23.1-1
Severity: important
Tags: patch
User: debian-h...@lists.debian.org
Usertags: hurd

Hi,

Currently the latest version of psmisc fails to build from source and
is flagged as out-of-date. This is due to usage of PATH_MAX, which is
not defined on GNU/Hurd. The attached patch solve this problem by
dynamically allocating space for the strings 'fullpath, linkpath and
buf' in main() of src/pslog.c and freeing it when not needed any
longer.

Thanks!
Index: psmisc-23.1/src/pslog.c
===================================================================
--- psmisc-23.1.orig/src/pslog.c
+++ psmisc-23.1/src/pslog.c
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -100,30 +101,37 @@ main(int argc, char const *argv[])
 
   struct dirent *namelist;
 
-  char* fullpath = (char*) malloc(PATH_MAX+1);
-  if (!fullpath) {
-    perror ("malloc");
+  char *fullpath = NULL, *linkpath = NULL;
+  ssize_t linkname_size;
+  size_t len = 0;
+  int nbytes;
+  struct stat sb;
+  char *buf = NULL;
+  DIR *pid_dir;
+
+  if (argv[1][0] != '/')
+    len = snprintf(NULL, 0, "/proc/%s/fd/", argv[1]);
+  else
+    len = snprintf(NULL, 0, "%s/fd/", argv[1]);
+  if (len < 0)
     return 1;
-  }
+  len++;
 
-  char* linkpath = (char*) malloc(PATH_MAX+1);
-  if (!linkpath) {
+  fullpath = (char*) malloc(len);
+  if (fullpath == NULL) {
     perror ("malloc");
     return 1;
   }
 
-  ssize_t linkname_size;
-  char buf[PATH_MAX+1];
-  DIR *pid_dir;
+  if (argv[1][0] != '/')
+   nbytes = snprintf(fullpath, len, "/proc/%s/fd/", argv[1]);
+  else
+    nbytes = snprintf(fullpath, len, "%s/fd/", argv[1]);
 
-  if (argv[1][0] != '/') {
-    strncpy(fullpath, "/proc/", PATH_MAX);
-    strncat(fullpath, argv[1], PATH_MAX - strlen(fullpath));
-    strncat(fullpath, "/fd/", PATH_MAX - strlen(fullpath));
-  } else {
-      strncpy(fullpath, argv[1], PATH_MAX);
-      strncat(fullpath, "/fd/", PATH_MAX - strlen(fullpath));
-    }
+  if (nbytes < 0 || nbytes >= len) {
+    perror("snprintf");
+    return 1;
+  }
 
   pid_dir = opendir(fullpath);
   if (!pid_dir) {
@@ -134,11 +142,44 @@ main(int argc, char const *argv[])
   fprintf(stdout, "Pid no %s:\n", argv[1]);
 
   while((namelist = readdir(pid_dir))) {
-    strncpy(linkpath, fullpath, PATH_MAX);
-    strncat(linkpath, namelist->d_name, PATH_MAX - strlen(linkpath));
-    linkname_size = readlink(linkpath, buf, PATH_MAX -1);
-    buf[linkname_size+1] = '\0';
+    len = snprintf(NULL, 0, "%s%s", fullpath, namelist->d_name);
+    len++;
+    linkpath = (char*) malloc(len);
+    if (linkpath == NULL) {
+      perror ("malloc");
+      return 1;
+    }
+    nbytes = snprintf(linkpath, len, "%s%s", fullpath, namelist->d_name);
+    if (nbytes < 0 || nbytes >= len) {
+      perror("snprintf");
+      return 1;
+    }
+    if(lstat(linkpath, &sb) == -1) {
+      perror("lstat");
+      return 1;
+    }
+    
+    if (sb.st_size == 0) {
+      perror("lstat");
+      return 1;
+    }
+    len = sb.st_size + 1;
+    buf = (char*)malloc(len);
+    if (buf == NULL) {
+      perror ("malloc");
+      return 1;
+    }
+    linkname_size = readlink(linkpath, buf, len);
+    if (linkname_size == -1) {
+      perror("readlink");
+      return 1;
+    }
 
+    buf[linkname_size] = '\0';
+    if (linkname_size == len) {
+      perror("readlink: truncated buffer");
+      return 1;
+    }
     if (regexec(&re_log, buf, 0, NULL, 0) == 0) {
       fprintf(stdout, "Log path: %s\n", buf);
     }
@@ -148,6 +189,7 @@ main(int argc, char const *argv[])
 
   free(linkpath);
   free(fullpath);
+  free(buf);
   regfree(&re_log);
 
   if (closedir(pid_dir)) {

Reply via email to