If PATH starts with "/:", which(1) reads outside of allocated memory.
Maybe that caused the non-reproduceable coredump mentioned in [0]?

The function progname sets path = strdup(path) and pathcpy = path and
runs the following loop:

> while ((p = strsep(&pathcpy, ":")) != NULL) {
>         if (*p == '\0')
>                 p = ".";
>         plen = strlen(p);
>         while (p[plen-1] == '/')
>                 p[--plen] = '\0';       /* strip trailing '/' */
>         ...
> }

In the first iteration, we have p == path. If PATH begins with "/:",
we'll have p[0] == '/' and plen == 1, so the inner loop runs once, after
which plen == 0. Then, to check the loop condition the program accesses
p[plen-1], i.e., path[-1].

[0] https://marc.info/?l=openbsd-misc&m=145270213529011&w=2

Index: usr.bin/which/which.c
===================================================================
RCS file: /cvs/src/usr.bin/which/which.c,v
retrieving revision 1.22
diff -u -p -r1.22 which.c
--- usr.bin/which/which.c       29 Dec 2015 19:04:46 -0000      1.22
+++ usr.bin/which/which.c       14 Jan 2016 00:21:45 -0000
@@ -124,7 +124,7 @@ findprog(char *prog, char *path, int pro
                        p = ".";
 
                plen = strlen(p);
-               while (p[plen-1] == '/')
+               while (plen > 0 && p[plen-1] == '/')
                        p[--plen] = '\0';       /* strip trailing '/' */
 
                if (plen + 1 + proglen >= sizeof(filename)) {

Reply via email to