From 5962f1a6dc7317e12472be884faba01dacc7a5c3cf88d95e88fb6e6938eb55d2 Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Thu, 27 Jan 2011 13:02:26 +0000 Subject: [PATCH] . OBS-URL: https://build.opensuse.org/package/show/Base:System/sysvinit?expand=0&rev=88 --- killproc-2.17.dif | 320 ++++++++++++++++++++++++++++++++++++++++++++-- sysvinit.changes | 7 + 2 files changed, 314 insertions(+), 13 deletions(-) diff --git a/killproc-2.17.dif b/killproc-2.17.dif index 404f75e..24d208c 100644 --- a/killproc-2.17.dif +++ b/killproc-2.17.dif @@ -1,21 +1,95 @@ --- libinit.c -+++ libinit.c 2011-01-21 18:25:49.019926024 +0000 -@@ -307,15 +307,16 @@ static void init_mounts(void) ++++ libinit.c 2011-01-27 12:58:48.944425833 +0000 +@@ -218,6 +218,26 @@ static struct _sys_signals { + { 0, "EXIT" } + }; + ++/* ++ * Calculate the depth of a directory, root has zero depth. ++ */ ++static size_t dirdepth(const char *const path) ++{ ++ const char *ptr = path; ++ size_t cnt = 0; ++ ++ do { ++ const size_t off = strcspn(ptr, "/"); ++ ptr += off; ++ if (*ptr++ != '/') ++ break; ++ if (*ptr) ++ cnt++; ++ } while (*ptr); ++ ++ return cnt; ++} ++ + typedef struct _mntinfo_ + { + struct _mntinfo_ *next; +@@ -226,6 +246,7 @@ typedef struct _mntinfo_ + int id, parid; + dev_t dev; + size_t nlen; ++ size_t deep; + char * point; + } MNTINFO; + +@@ -253,6 +274,7 @@ static void init_mounts(void) + p->point = ((char*)p)+alignof(MNTINFO); + strcpy(p->point, point); + p->nlen = nlen; ++ p->deep = dirdepth(point); + p->parid = parid; + p->dev = makedev(maj, min); + p->id = mid; +@@ -262,20 +284,20 @@ static void init_mounts(void) + p->prev = (MNTINFO*)0; + p->parent = p; + mounts = p; +- if (mid > max) +- max = mid; ++ if (p->id > max) ++ max = p->id; + } + fclose(mnt); + +- /* Sort mount points accordingly to the reverse mount order */ ++ /* Sort mount points accordingly to their reverse directory depth */ + save = (MNTINFO*)0; +- for (mid = 1; mid <= max; mid++) { ++ for (mid = 0; mounts; mid++) { + MNTINFO *m, *n, *l; + n = mounts; + l = (MNTINFO*)0; + for (m = mounts; n; m = n) { + n = m->next; +- if (m->id != mid) ++ if (m->deep != mid) + continue; + l = m->prev; + if (m == mounts) { +@@ -290,7 +312,6 @@ static void init_mounts(void) + m->next = save; + m->prev = (MNTINFO*)0; + save = m; +- break; + } + } + mounts = save; +@@ -307,15 +328,14 @@ static void init_mounts(void) } } -static MNTINFO *find_mount(const char * path) +static int find_mount(const char * path, MNTINFO *s) { -- MNTINFO *m; -+ MNTINFO *m, *p = s->parent; + MNTINFO *m; for (m = mounts; m; m = m->next) { - if (strncmp(path, m->point, m->nlen)) - continue; - break; -+ if (s == m && strncmp(path, m->point, m->nlen) == 0) -+ return 1; -+ if (p == m && strncmp(path, p->point, p->nlen) == 0) ++ if (s == m) + return 1; } - return m; @@ -23,10 +97,43 @@ } extern inline char * handl_buf(char *restrict buf) -@@ -728,19 +729,21 @@ int pidof (const char * inname, const ch +@@ -627,6 +647,7 @@ int pidof (const char * inname, const ch + pid_t pid; + char *swapname = NULL; + char *fullname = (char *)inname; ++ char *realname = NULL; + MNTINFO *prefix = NULL; + PROC *p, *n; + +@@ -659,12 +680,17 @@ int pidof (const char * inname, const ch + warn("cannot stat %s: %s\n", fullname, strerror(errno)); + return -1; + } +- init_mounts(); +- for (m = mounts; m; m = m->next) { +- if (m->dev != full_st.st_dev) +- continue; +- prefix = m; +- break; ++ realname = expandpath(fullname); ++ if (realname) { ++ init_mounts(); ++ for (m = mounts; m; m = m->next) { ++ if (m->dev != full_st.st_dev) ++ continue; ++ if (strncmp(realname, m->point, m->nlen) != 0) ++ continue; ++ prefix = m; ++ break; ++ } + } + } + +@@ -727,20 +753,21 @@ int pidof (const char * inname, const ch + */ if (!(flags & (KTHREAD|KSHORT)) && !isscrpt) { char entry[PATH_MAX+1]; - char *realname = NULL; +- char *realname = NULL; - const char *name; + const char *name = NULL; boolean found; @@ -55,7 +162,7 @@ if (fstatat(dfd, here(d->d_name, "exe"), &pid_st, 0) < 0) { if (errno != EPERM && errno != EACCES) -@@ -765,12 +768,22 @@ int pidof (const char * inname, const ch +@@ -765,18 +792,24 @@ int pidof (const char * inname, const ch if (strlen(fullname) > PATH_MAX) continue; @@ -75,7 +182,194 @@ } - if ((realname = realpath(name, NULL)) == (char*)0) -+ if ((realname = realpath(fullname, NULL)) == (char*)0) - continue; +- continue; +- +- if (strncmp(realname, name, PATH_MAX) == 0) ++ if (realname && strncmp(realname, name, PATH_MAX) == 0) + found = true; - if (strncmp(realname, name, PATH_MAX) == 0) +- free(realname); + + break; + } +@@ -896,6 +929,7 @@ int verify_pidfile (const char * pid_fil + pid_t pid; + char *swapname = NULL, *bufp; + char *fullname = (char *)inname; ++ char *realname = NULL; + struct stat pid_st, full_st; + char buf[BUFSIZ]; + +@@ -958,6 +992,7 @@ int verify_pidfile (const char * pid_fil + warn("cannot stat %s: %s\n", fullname, strerror(errno)); + return -1; + } ++ realname = expandpath(fullname); + } + + if (flags & (KTHREAD|KSHORT)) { +@@ -997,7 +1032,6 @@ int verify_pidfile (const char * pid_fil + + char entry[PATH_MAX+1]; + const char *name; +- char *realname; + boolean found; + ssize_t rll; + +@@ -1028,14 +1062,9 @@ int verify_pidfile (const char * pid_fil + break; + } + +- if ((realname = realpath(fullname, NULL)) == (char*)0) +- goto out; +- +- if (strncmp(realname, name, PATH_MAX) == 0) ++ if (realname && strncmp(realname, name, PATH_MAX) == 0) + found = true; + +- free(realname); +- + break; + } + +@@ -1115,6 +1144,7 @@ int check_pids (const char * inname, con + boolean isscrpt = false; + char *swapname = (char*)0; + char *fullname = (char *)inname; ++ char *realname = (char*)0; + const char *pid; + struct stat pid_st, full_st; + PROC *p, *n, *l; +@@ -1132,6 +1162,7 @@ int check_pids (const char * inname, con + warn("cannot stat %s: %s\n", fullname, strerror(errno)); + return -1; + } ++ realname = expandpath(fullname); + } + + if (flags & (KTHREAD|KSHORT)) { +@@ -1191,7 +1222,6 @@ int check_pids (const char * inname, con + + char entry[PATH_MAX+1]; + const char *name; +- char *realname; + ssize_t rll; + + if (pid_st.st_dev != full_st.st_dev) +@@ -1218,14 +1248,8 @@ int check_pids (const char * inname, con + if (strncmp(fullname, name, PATH_MAX) == 0) + continue; /* Found */ + +- if ((realname = realpath(fullname, NULL)) == (char*)0) +- goto ignore; /* Bogus */ +- +- if (strncmp(realname, name, PATH_MAX) == 0) { +- free(realname); ++ if (realname && strncmp(realname, name, PATH_MAX) == 0) + continue; /* Found */ +- } +- free(realname); + + break; + } +@@ -1807,4 +1831,100 @@ void clear_nfs(void) + } + } + ++/* ++ * Somehow the realpath(3) glibc function call, nevertheless ++ * it avoids lstat(2) system calls. ++ */ ++static char real[PATH_MAX+1]; ++char* expandpath(const char * path) ++{ ++ char tmpbuf[PATH_MAX+1]; ++ const char *start, *end; ++ char *curr, *dest; ++ int deep = MAXSYMLINKS; ++ ++ if (!path || *path == '\0') ++ return (char*)0; ++ ++ curr = &real[0]; ++ ++ if (*path != '/') { ++ if (!getcwd(curr, PATH_MAX)) ++ return (char*)0; ++ dest = rawmemchr(curr, '\0'); ++ } else { ++ *curr = '/'; ++ dest = curr + 1; ++ } ++ ++ for (start = end = path; *start; start = end) { ++ ++ while (*start == '/') ++ ++start; ++ ++ for (end = start; *end && *end != '/'; ++end) ++ ; ++ ++ if (end - start == 0) ++ break; ++ else if (end - start == 1 && start[0] == '.') { ++ ; ++ } else if (end - start == 2 && start[0] == '.' && start[1] == '.') { ++ if (dest > curr + 1) ++ while ((--dest)[-1] != '/') ++ ; ++ } else { ++ char lnkbuf[PATH_MAX+1]; ++ size_t len; ++ ssize_t n; ++ ++ if (dest[-1] != '/') ++ *dest++ = '/'; ++ ++ if (dest + (end - start) > curr + PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (char*)0; ++ } ++ ++ dest = mempcpy(dest, start, end - start); ++ *dest = '\0'; ++ ++ if (deep-- < 0) { ++ errno = ELOOP; ++ return (char*)0; ++ } ++ ++ errno = 0; ++ if ((n = readlink(curr, lnkbuf, PATH_MAX)) < 0) { ++ deep = MAXSYMLINKS; ++ if (errno == EINVAL) ++ continue; /* Not a symlink */ ++ return (char*)0; ++ } ++ lnkbuf[n] = '\0'; /* Don't be fooled by readlink(2) */ ++ ++ len = strlen(end); ++ if ((n + len) > PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (char*)0; ++ } ++ ++ memmove(&tmpbuf[n], end, len + 1); ++ path = end = memcpy(tmpbuf, lnkbuf, n); ++ ++ if (lnkbuf[0] == '/') ++ dest = curr + 1; ++ else if (dest > curr + 1) ++ while ((--dest)[-1] != '/'); ++ ++ } ++ } ++ ++ if (dest > curr + 1 && dest[-1] == '/') ++ --dest; ++ *dest = '\0'; ++ ++ return curr; ++} ++ + /* libinit.c ends here */ diff --git a/sysvinit.changes b/sysvinit.changes index d1227c6..c1655a8 100644 --- a/sysvinit.changes +++ b/sysvinit.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu Jan 27 13:00:09 UTC 2011 - werner@novell.com + +- Killproc: Sort mount info pointers in the reverse order of the + directory depth to become the string compare of the readed link + name of the exe link more safely. + ------------------------------------------------------------------- Fri Jan 21 19:26:44 CET 2011 - werner@suse.de