From 6ca0444420223c224162674902d4f6e4e093962d Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sun, 11 Feb 2007 16:19:28 +0000 Subject: [PATCH] syslogd: fix "readpath bug" by using readlink instead libbb: rename xgetcwd and xreadlink --- applets/busybox.c | 2 +- archival/tar.c | 4 ++-- coreutils/ls.c | 2 +- coreutils/pwd.c | 3 ++- coreutils/stat.c | 4 ++-- debianutils/readlink.c | 2 +- include/libbb.h | 4 ++-- libbb/copy_file.c | 2 +- libbb/lineedit.c | 2 +- libbb/simplify_path.c | 2 +- libbb/xgetcwd.c | 4 ++-- libbb/xreadlink.c | 2 +- shell/hush.c | 4 ++-- shell/lash.c | 6 +++--- sysklogd/syslogd.c | 43 ++++++++++++++++++++++++------------------ 15 files changed, 47 insertions(+), 39 deletions(-) diff --git a/applets/busybox.c b/applets/busybox.c index 99af9ca02..0387d79b7 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -92,7 +92,7 @@ int busybox_main(int argc, char **argv) /* link */ // XXX: FIXME: this is broken. Why not just use argv[0] ? - busybox = xreadlink("/proc/self/exe"); + busybox = xmalloc_readlink_or_warn("/proc/self/exe"); if (!busybox) return 1; install_links(busybox, use_symbolic_links); diff --git a/archival/tar.c b/archival/tar.c index d8e36749e..57da0b6b8 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -273,8 +273,8 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, tbInfo->hlInfo->name, 0); #endif } else if (S_ISLNK(statbuf->st_mode)) { - char *lpath = xreadlink(fileName); - if (!lpath) /* Already printed err msg inside xreadlink() */ + char *lpath = xmalloc_readlink_or_warn(fileName); + if (!lpath) return FALSE; header.typeflag = SYMTYPE; strncpy(header.linkname, lpath, sizeof(header.linkname)); diff --git a/coreutils/ls.c b/coreutils/ls.c index 798bc8201..34fae5026 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -664,7 +664,7 @@ static int list_single(struct dnode *dn) break; case LIST_SYMLINK: if (S_ISLNK(dn->dstat.st_mode)) { - char *lpath = xreadlink(dn->fullname); + char *lpath = xmalloc_readlink_or_warn(dn->fullname); if (!lpath) break; printf(" -> "); #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR diff --git a/coreutils/pwd.c b/coreutils/pwd.c index b4599b4f3..d96f6a8e5 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c @@ -16,7 +16,8 @@ int pwd_main(int argc, char **argv) { char *buf; - if ((buf = xgetcwd(NULL)) != NULL) { + buf = xrealloc_getcwd_or_warn(NULL); + if (buf != NULL) { puts(buf); fflush_stdout_and_exit(EXIT_SUCCESS); } diff --git a/coreutils/stat.c b/coreutils/stat.c index ff14a1599..20ade9472 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c @@ -188,7 +188,7 @@ static void print_stat(char *pformat, size_t buf_len, char m, case 'N': strncat(pformat, "s", buf_len); if (S_ISLNK(statbuf->st_mode)) { - char *linkname = xreadlink(filename); + char *linkname = xmalloc_readlink_or_warn(filename); if (linkname == NULL) { bb_perror_msg("cannot read symbolic link '%s'", filename); return; @@ -477,7 +477,7 @@ static int do_stat(char const *filename, char const *format) pw_ent = getpwuid(statbuf.st_uid); if (S_ISLNK(statbuf.st_mode)) - linkname = xreadlink(filename); + linkname = xmalloc_readlink_or_warn(filename); if (linkname) printf(" File: \"%s\" -> \"%s\"\n", filename, linkname); else diff --git a/debianutils/readlink.c b/debianutils/readlink.c index 8f9cfe431..1a2c1efb7 100644 --- a/debianutils/readlink.c +++ b/debianutils/readlink.c @@ -38,7 +38,7 @@ int readlink_main(int argc, char **argv) if (opt) { buf = realpath(fname, bb_common_bufsiz1); } else { - buf = xreadlink(fname); + buf = xmalloc_readlink_or_warn(fname); } if (!buf) diff --git a/include/libbb.h b/include/libbb.h index 218a1935c..077b65840 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -258,8 +258,8 @@ extern int ndelay_off(int fd); extern DIR *xopendir(const char *path); extern DIR *warn_opendir(const char *path); -char *xgetcwd(char *cwd); -char *xreadlink(const char *path); +char *xrealloc_getcwd_or_warn(char *cwd); +char *xmalloc_readlink_or_warn(const char *path); char *xmalloc_realpath(const char *path); extern void xstat(const char *filename, struct stat *buf); extern pid_t spawn(char **argv); diff --git a/libbb/copy_file.c b/libbb/copy_file.c index 632064eaa..bd785b71c 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c @@ -233,7 +233,7 @@ int copy_file(const char *source, const char *dest, int flags) } else if (S_ISLNK(source_stat.st_mode)) { char *lpath; - lpath = xreadlink(source); + lpath = xmalloc_readlink_or_warn(source); if (symlink(lpath, dest) < 0) { bb_perror_msg("cannot create symlink '%s'", dest); free(lpath); diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 937d70d1f..16256f726 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1090,7 +1090,7 @@ static void parse_prompt(const char *prmt_ptr) size_t cur_prmt_len = 0; char flg_not_length = '['; char *prmt_mem_ptr = xzalloc(1); - char *pwd_buf = xgetcwd(0); + char *pwd_buf = xrealloc_getcwd_or_warn(NULL); char buf2[PATH_MAX + 1]; char buf[2]; char c; diff --git a/libbb/simplify_path.c b/libbb/simplify_path.c index b714c66b6..7e68e3911 100644 --- a/libbb/simplify_path.c +++ b/libbb/simplify_path.c @@ -16,7 +16,7 @@ char *bb_simplify_path(const char *path) if (path[0] == '/') start = xstrdup(path); else { - s = xgetcwd(NULL); + s = xrealloc_getcwd_or_warn(NULL); start = concat_path_file(s, path); free(s); } diff --git a/libbb/xgetcwd.c b/libbb/xgetcwd.c index 0ac450d3b..ec1d8f7a4 100644 --- a/libbb/xgetcwd.c +++ b/libbb/xgetcwd.c @@ -18,7 +18,7 @@ */ char * -xgetcwd(char *cwd) +xrealloc_getcwd_or_warn(char *cwd) { char *ret; unsigned path_max; @@ -26,7 +26,7 @@ xgetcwd(char *cwd) path_max = (unsigned) PATH_MAX; path_max += 2; /* The getcwd docs say to do this. */ - if (cwd==0) + if (cwd == NULL) cwd = xmalloc(path_max); while ((ret = getcwd(cwd, path_max)) == NULL && errno == ERANGE) { diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index fb67cdef1..18a8b9467 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c @@ -11,7 +11,7 @@ * yourself. You have been warned. */ -char *xreadlink(const char *path) +char *xmalloc_readlink_or_warn(const char *path) { enum { GROWBY = 80 }; /* how large we will grow strings by */ diff --git a/shell/hush.c b/shell/hush.c index 573724075..7658aebed 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -423,8 +423,8 @@ static const struct built_in_command bltins[] = { static const char *set_cwd(void) { if (cwd == bb_msg_unknown) - cwd = NULL; /* xgetcwd(arg) called free(arg) */ - cwd = xgetcwd((char *)cwd); + cwd = NULL; /* xrealloc_getcwd_or_warn(arg) called free(arg) */ + cwd = xrealloc_getcwd_or_warn((char *)cwd); if (!cwd) cwd = bb_msg_unknown; return cwd; diff --git a/shell/lash.c b/shell/lash.c index 502e0d829..09067fda0 100644 --- a/shell/lash.c +++ b/shell/lash.c @@ -217,7 +217,7 @@ static int builtin_cd(struct child_prog *child) bb_perror_msg("cd: %s", newdir); return EXIT_FAILURE; } - cwd = xgetcwd((char *)cwd); + cwd = xrealloc_getcwd_or_warn((char *)cwd); if (!cwd) cwd = bb_msg_unknown; return EXIT_SUCCESS; @@ -342,7 +342,7 @@ static int builtin_jobs(struct child_prog *child) /* built-in 'pwd' handler */ static int builtin_pwd(struct child_prog ATTRIBUTE_UNUSED *dummy) { - cwd = xgetcwd((char *)cwd); + cwd = xrealloc_getcwd_or_warn((char *)cwd); if (!cwd) cwd = bb_msg_unknown; puts(cwd); @@ -1569,7 +1569,7 @@ int lash_main(int argc_l, char **argv_l) } /* initialize the cwd -- this is never freed...*/ - cwd = xgetcwd(0); + cwd = xrealloc_getcwd_or_warn(NULL); if (!cwd) cwd = bb_msg_unknown; diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 97ddf09b5..53290f1cc 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -24,9 +24,6 @@ #define DEBUG 0 -/* Path to the unix socket */ -static const char *dev_log_name; - /* Path for the file where all log messages are written */ static const char *logFilePath = "/var/log/messages"; static int logFD = -1; @@ -446,7 +443,6 @@ static void quit_signal(int sig) { timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"syslogd exiting", 0); puts("syslogd exiting"); - unlink(dev_log_name); if (ENABLE_FEATURE_IPC_SYSLOG) ipcsyslog_cleanup(); exit(1); @@ -464,9 +460,9 @@ static void do_syslogd(void) ATTRIBUTE_NORETURN; static void do_syslogd(void) { struct sockaddr_un sunx; - socklen_t addr_len; int sock_fd; fd_set fds; + char *dev_log_name; /* Set up signal handlers */ signal(SIGINT, quit_signal); @@ -480,22 +476,33 @@ static void do_syslogd(void) signal(SIGALRM, do_mark); alarm(markInterval); - dev_log_name = xmalloc_realpath(_PATH_LOG); - if (!dev_log_name) - dev_log_name = _PATH_LOG; - - /* Unlink old /dev/log (or object it points to) */ - unlink(dev_log_name); - memset(&sunx, 0, sizeof(sunx)); sunx.sun_family = AF_UNIX; - strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path)); - sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0); - addr_len = sizeof(sunx.sun_family) + strlen(sunx.sun_path); - xbind(sock_fd, (struct sockaddr *) &sunx, addr_len); + strcpy(sunx.sun_path, "/dev/log"); - if (chmod(dev_log_name, 0666) < 0) { - bb_perror_msg_and_die("cannot set permission on %s", dev_log_name); + /* Unlink old /dev/log or object it points to. */ + /* (if it exists, bind will fail) */ + logmode = LOGMODE_NONE; + dev_log_name = xmalloc_readlink_or_warn("/dev/log"); + logmode = LOGMODE_STDIO; + if (dev_log_name) { + int fd = xopen(".", O_NONBLOCK); + xchdir("/dev"); + /* we do not check whether this is a link also */ + unlink(dev_log_name); + fchdir(fd); + close(fd); + safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path)); + free(dev_log_name); + } else { + unlink("/dev/log"); + } + + sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0); + xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx)); + + if (chmod("/dev/log", 0666) < 0) { + bb_perror_msg_and_die("cannot set permission on /dev/log"); } if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) { ipcsyslog_init();