From 86a7f18f211af1abda5c855d2674b0fcb53de524 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Thu, 2 Apr 2015 23:03:46 +0200 Subject: *: Switch to POSIX utmpx API UTMP is SVID legacy, UTMPX is mandated by POSIX. Glibc and uClibc have identical layout of UTMP and UTMPX, both of these libc treat _PATH_UTMPX as _PATH_UTMP so from a user-perspective nothing changes except the names of the API entrypoints. Signed-off-by: Bernhard Reutner-Fischer --- libbb/utmp.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'libbb') diff --git a/libbb/utmp.c b/libbb/utmp.c index 8ad9ba27e..bd07670db 100644 --- a/libbb/utmp.c +++ b/libbb/utmp.c @@ -16,7 +16,7 @@ static void touch(const char *filename) void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname) { - struct utmp utent; + struct utmpx utent; char *id; unsigned width; @@ -45,17 +45,17 @@ void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, con tty_name += 3; strncpy(id, tty_name, width); - touch(_PATH_UTMP); - //utmpname(_PATH_UTMP); - setutent(); + touch(_PATH_UTMPX); + //utmpxname(_PATH_UTMPX); + setutxent(); /* Append new one (hopefully, unless we collide on ut_id) */ - pututline(&utent); - endutent(); + pututxline(&utent); + endutxent(); #if ENABLE_FEATURE_WTMP /* "man utmp" says wtmp file should *not* be created automagically */ /*touch(bb_path_wtmp_file);*/ - updwtmp(bb_path_wtmp_file, &utent); + updwtmpx(bb_path_wtmp_file, &utent); #endif } @@ -64,17 +64,17 @@ void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, con */ void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname) { - struct utmp utent; - struct utmp *utp; + struct utmpx utent; + struct utmpx *utp; - touch(_PATH_UTMP); - //utmpname(_PATH_UTMP); - setutent(); + touch(_PATH_UTMPX); + //utmpxname(_PATH_UTMPX); + setutxent(); /* Did init/getty/telnetd/sshd/... create an entry for us? * It should be (new_type-1), but we'd also reuse * any other potentially stale xxx_PROCESS entry */ - while ((utp = getutent()) != NULL) { + while ((utp = getutxent()) != NULL) { if (utp->ut_pid == pid // && ut->ut_line[0] && utp->ut_id[0] /* must have nonzero id */ @@ -88,25 +88,25 @@ void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const /* Stale record. Nuke hostname */ memset(utp->ut_host, 0, sizeof(utp->ut_host)); } - /* NB: pututline (see later) searches for matching utent - * using getutid(utent) - we must not change ut_id + /* NB: pututxline (see later) searches for matching utxent + * using getutxid(utent) - we must not change ut_id * if we want *exactly this* record to be overwritten! */ break; } } - //endutent(); - no need, pututline can deal with (and actually likes) + //endutxent(); - no need, pututxline can deal with (and actually likes) //the situation when utmp file is positioned on found record if (!utp) { if (new_type != DEAD_PROCESS) write_new_utmp(pid, new_type, tty_name, username, hostname); else - endutent(); + endutxent(); return; } - /* Make a copy. We can't use *utp, pututline's internal getutid + /* Make a copy. We can't use *utp, pututxline's internal getutxid * will overwrite it before it is used! */ utent = *utp; @@ -120,14 +120,14 @@ void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const utent.ut_tv.tv_sec = time(NULL); /* Update, or append new one */ - //setutent(); - pututline(&utent); - endutent(); + //setutxent(); + pututxline(&utent); + endutxent(); #if ENABLE_FEATURE_WTMP /* "man utmp" says wtmp file should *not* be created automagically */ /*touch(bb_path_wtmp_file);*/ - updwtmp(bb_path_wtmp_file, &utent); + updwtmpx(bb_path_wtmp_file, &utent); #endif } -- cgit v1.2.3-55-g6feb From 7b729edd33aea5361e0740df800a1a0a1ff70f7f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 2 Apr 2015 00:55:17 +0300 Subject: update copyright years Copyright years seem to be out of date, e.g. coreutils/truncate.c has Copyright (C) 2015. Signed-off-by: Aaro Koskinen Signed-off-by: Bernhard Reutner-Fischer --- libbb/appletlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbb') diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 8fd8fd525..e0b843d30 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -631,7 +631,7 @@ static int busybox_main(char **argv) full_write2_str(bb_banner); /* reuse const string */ full_write2_str(" multi-call binary.\n"); /* reuse */ full_write2_str( - "BusyBox is copyrighted by many authors between 1998-2012.\n" + "BusyBox is copyrighted by many authors between 1998-2015.\n" "Licensed under GPLv2. See source distribution for detailed\n" "copyright notices.\n" "\n" -- cgit v1.2.3-55-g6feb From 61d6ae244af424b2a05468307723f21c8810ab9e Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 19 Apr 2015 10:50:25 +0100 Subject: libbb: remove unnecessary argument to nonblock_immune_read The loop_on_EINTR argument to nonblock_immune_read is always set to 1. function old new delta xmalloc_reads 200 195 -5 pgetc 488 483 -5 argstr 1313 1308 -5 nonblock_immune_read 123 86 -37 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-52) Total: -52 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- include/libbb.h | 2 +- libbb/read_printf.c | 8 ++++---- shell/ash.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'libbb') diff --git a/include/libbb.h b/include/libbb.h index 0f8363b78..21da5f100 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -713,7 +713,7 @@ void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) F extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC; -extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR) FAST_FUNC; +extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count) FAST_FUNC; // NB: will return short read on error, not -1, // if some data was read before error occurred extern ssize_t full_read(int fd, void *buf, size_t count) FAST_FUNC; diff --git a/libbb/read_printf.c b/libbb/read_printf.c index 5ed6e3632..b6a17cc36 100644 --- a/libbb/read_printf.c +++ b/libbb/read_printf.c @@ -45,20 +45,20 @@ * which detects EAGAIN and uses poll() to wait on the fd. * Thankfully, poll() doesn't care about O_NONBLOCK flag. */ -ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR) +ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count) { struct pollfd pfd[1]; ssize_t n; while (1) { - n = loop_on_EINTR ? safe_read(fd, buf, count) : read(fd, buf, count); + n = safe_read(fd, buf, count); if (n >= 0 || errno != EAGAIN) return n; /* fd is in O_NONBLOCK mode. Wait using poll and repeat */ pfd[0].fd = fd; pfd[0].events = POLLIN; /* note: safe_poll pulls in printf */ - loop_on_EINTR ? safe_poll(pfd, 1, -1) : poll(pfd, 1, -1); + safe_poll(pfd, 1, -1); } } @@ -81,7 +81,7 @@ char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p) p = buf + sz; sz += 128; } - if (nonblock_immune_read(fd, p, 1, /*loop_on_EINTR:*/ 1) != 1) { + if (nonblock_immune_read(fd, p, 1) != 1) { /* EOF/error */ if (p == buf) { /* we read nothing */ free(buf); diff --git a/shell/ash.c b/shell/ash.c index 697a64fea..c51fb804d 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -5923,7 +5923,7 @@ expbackq(union node *cmd, int quoted, int quotes) read: if (in.fd < 0) break; - i = nonblock_immune_read(in.fd, buf, sizeof(buf), /*loop_on_EINTR:*/ 1); + i = nonblock_immune_read(in.fd, buf, sizeof(buf)); TRACE(("expbackq: read returns %d\n", i)); if (i <= 0) break; @@ -9696,7 +9696,7 @@ preadfd(void) #if ENABLE_FEATURE_EDITING retry: if (!iflag || g_parsefile->pf_fd != STDIN_FILENO) - nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1, /*loop_on_EINTR:*/ 1); + nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1); else { int timeout = -1; # if ENABLE_ASH_IDLE_TIMEOUT @@ -9738,7 +9738,7 @@ preadfd(void) } } #else - nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1, /*loop_on_EINTR:*/ 1); + nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1); #endif #if 0 /* disabled: nonblock_immune_read() handles this problem */ -- cgit v1.2.3-55-g6feb From de5edadee2dca2896492f97ab3a56e389305e74d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 21 Apr 2015 16:00:41 +0200 Subject: special-case {true,false,test} --help This also removes their help texts. function old new delta run_applet_no_and_exit 442 452 +10 packed_usage 30713 30625 -88 Signed-off-by: Denys Vlasenko --- coreutils/false.c | 8 +++----- coreutils/test.c | 11 +++-------- coreutils/true.c | 8 +++----- libbb/appletlib.c | 22 ++++++++++++---------- 4 files changed, 21 insertions(+), 28 deletions(-) (limited to 'libbb') diff --git a/coreutils/false.c b/coreutils/false.c index 59c2f321a..0591a6cdc 100644 --- a/coreutils/false.c +++ b/coreutils/false.c @@ -10,11 +10,9 @@ /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/000095399/utilities/false.html */ -//usage:#define false_trivial_usage -//usage: "" -//usage:#define false_full_usage "\n\n" -//usage: "Return an exit code of FALSE (1)" -//usage: +/* "false --help" is special-cased to ignore --help */ +//usage:#define false_trivial_usage NOUSAGE_STR +//usage:#define false_full_usage "" //usage:#define false_example_usage //usage: "$ false\n" //usage: "$ echo $?\n" diff --git a/coreutils/test.c b/coreutils/test.c index 88cc55050..7b8b10cd9 100644 --- a/coreutils/test.c +++ b/coreutils/test.c @@ -39,14 +39,9 @@ //config: help //config: Enable 64-bit support in test. -/* "test --help" does not print help (POSIX compat), only "[ --help" does. - * We display " EXPRESSION ]" here (not " EXPRESSION") - * Unfortunately, it screws up generated BusyBox.html. TODO. */ -//usage:#define test_trivial_usage -//usage: "EXPRESSION ]" -//usage:#define test_full_usage "\n\n" -//usage: "Check file types, compare values etc. Return a 0/1 exit code\n" -//usage: "depending on logical value of EXPRESSION" +/* "test --help" is special-cased to ignore --help */ +//usage:#define test_trivial_usage NOUSAGE_STR +//usage:#define test_full_usage "" //usage: //usage:#define test_example_usage //usage: "$ test 1 -eq 2\n" diff --git a/coreutils/true.c b/coreutils/true.c index 382e476a8..89f892961 100644 --- a/coreutils/true.c +++ b/coreutils/true.c @@ -10,11 +10,9 @@ /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/true.html */ -//usage:#define true_trivial_usage -//usage: "" -//usage:#define true_full_usage "\n\n" -//usage: "Return an exit code of TRUE (0)" -//usage: +/* "true --help" is special-cased to ignore --help */ +//usage:#define true_trivial_usage NOUSAGE_STR +//usage:#define true_full_usage "" //usage:#define true_example_usage //usage: "$ true\n" //usage: "$ echo $?\n" diff --git a/libbb/appletlib.c b/libbb/appletlib.c index e0b843d30..ba3d6e7a0 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -748,23 +748,25 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) xfunc_error_retval = EXIT_FAILURE; applet_name = APPLET_NAME(applet_no); -#if defined APPLET_NO_test /* Special case. POSIX says "test --help" * should be no different from e.g. "test --foo". * Thus for "test", we skip --help check. + * "true" and "false" are also special. */ - if (applet_no != APPLET_NO_test) + if (1 +#if defined APPLET_NO_test + && applet_no != APPLET_NO_test +#endif +#if defined APPLET_NO_true + && applet_no != APPLET_NO_true #endif - { - if (argc == 2 && strcmp(argv[1], "--help") == 0) { #if defined APPLET_NO_false - /* Someone insisted that "false --help" must exit 1. Sigh */ - if (applet_no != APPLET_NO_false) + && applet_no != APPLET_NO_false #endif - { - /* Make "foo --help" exit with 0: */ - xfunc_error_retval = 0; - } + ) { + if (argc == 2 && strcmp(argv[1], "--help") == 0) { + /* Make "foo --help" exit with 0: */ + xfunc_error_retval = 0; bb_show_usage(); } } -- cgit v1.2.3-55-g6feb From cee59053dcf47b4a3ab87f7654c1ed20620def16 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sat, 25 Apr 2015 21:32:48 +0200 Subject: Bionic lacks ttyname_r; provide a workaround Signed-off-by: Matt Whitlock Signed-off-by: Denys Vlasenko --- include/platform.h | 7 +++++++ libbb/platform.c | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'libbb') diff --git a/include/platform.h b/include/platform.h index df9594507..d5ab7bc29 100644 --- a/include/platform.h +++ b/include/platform.h @@ -368,6 +368,7 @@ typedef unsigned smalluint; #define HAVE_DPRINTF 1 #define HAVE_MEMRCHR 1 #define HAVE_MKDTEMP 1 +#define HAVE_TTYNAME_R 1 #define HAVE_PTSNAME_R 1 #define HAVE_SETBIT 1 #define HAVE_SIGHANDLER_T 1 @@ -480,6 +481,7 @@ typedef unsigned smalluint; #if defined(ANDROID) || defined(__ANDROID__) # undef HAVE_DPRINTF +# undef HAVE_TTYNAME_R # undef HAVE_GETLINE # undef HAVE_STPCPY # undef HAVE_STRCHRNUL @@ -505,6 +507,11 @@ extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC; extern char *mkdtemp(char *template) FAST_FUNC; #endif +#ifndef HAVE_TTYNAME_R +#define ttyname_r bb_ttyname_r +extern int ttyname_r(int fd, char *buf, size_t buflen); +#endif + #ifndef HAVE_SETBIT # define setbit(a, b) ((a)[(b) >> 3] |= 1 << ((b) & 7)) # define clrbit(a, b) ((a)[(b) >> 3] &= ~(1 << ((b) & 7))) diff --git a/libbb/platform.c b/libbb/platform.c index 8d90ca4e9..03bbb798b 100644 --- a/libbb/platform.c +++ b/libbb/platform.c @@ -194,3 +194,22 @@ ssize_t FAST_FUNC getline(char **lineptr, size_t *n, FILE *stream) return len; } #endif + +#ifndef HAVE_TTYNAME_R +int ttyname_r(int fd, char *buf, size_t buflen) +{ + int r; + char path[sizeof("/proc/self/fd/%d") + sizeof(int)*3]; + + if (!isatty(fd)) + return errno == EINVAL ? ENOTTY : errno; + sprintf(path, "/proc/self/fd/%d", fd); + r = readlink(path, buf, buflen); + if (r < 0) + return errno; + if (r >= buflen) + return ERANGE; + buf[r] = '\0'; + return 0; +} +#endif -- cgit v1.2.3-55-g6feb From 93b98ff5726fd620e1f123d04072b956412c1b55 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sun, 26 Apr 2015 13:14:50 +0200 Subject: Bionic lacks tcdrain; provide a workaround Signed-off-by: Matt Whitlock Signed-off-by: Denys Vlasenko --- libbb/missing_syscalls.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libbb') diff --git a/libbb/missing_syscalls.c b/libbb/missing_syscalls.c index dd430e3e2..e3c1e924b 100644 --- a/libbb/missing_syscalls.c +++ b/libbb/missing_syscalls.c @@ -39,4 +39,9 @@ int pivot_root(const char *new_root, const char *put_old) { return syscall(__NR_pivot_root, new_root, put_old); } + +int tcdrain(int fd) +{ + return ioctl(fd, TCSBRK, 1); +} #endif -- cgit v1.2.3-55-g6feb From a818777d4249e934ef7c9e6e7df8475d6692f315 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Tue, 12 May 2015 07:56:04 +0100 Subject: libbb: Enable support for !CONFIG_MULTIUSER Linux recently gained a new config option, CONFIG_MULTIUSER, that makes support for non-root users optional. This results in a number of syscalls being disabled: setuid, setregid, setgid, setreuid, setresuid, getresuid, setresgid, getresgid, setgroups, getgroups, setfsuid, setfsgid, capget, capset. Currently a number of busybox applets, including login, struggle to run when CONFIG_MULTIUSER is disabled. Even the root user is unable to login: login: can't set groups: Functi This patch adds code to make change_identity() a nop on single user systems. It works by recognising the signature errno value (ENOSYS, due to the system calls being disabled) and, to avoid security risks, only deploys when the current uid and target uid is the same. After the patch is applied any attempt to switch to a non-root user will fail. Thus a badly configured userspace (for example, one that tries to start a daemon as a non-root user when the kernel cannot support this) will report errors as one would expect. Signed-off-by: Daniel Thompson Signed-off-by: Denys Vlasenko --- libbb/change_identity.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'libbb') diff --git a/libbb/change_identity.c b/libbb/change_identity.c index 619db09a8..d48d86326 100644 --- a/libbb/change_identity.c +++ b/libbb/change_identity.c @@ -33,9 +33,28 @@ /* Become the user and group(s) specified by PW. */ void FAST_FUNC change_identity(const struct passwd *pw) { - if (initgroups(pw->pw_name, pw->pw_gid) == -1) - bb_perror_msg_and_die("can't set groups"); + int res; + + res = initgroups(pw->pw_name, pw->pw_gid); endgrent(); /* helps to close a fd used internally by libc */ + + if (res != 0) { + /* + * If initgroups() fails because a system call is unimplemented + * then we are running on a Linux kernel compiled without multiuser + * support (CONFIG_MULTIUSER is not defined). + * + * If we are running without multiuser support *and* the target uid + * already matches the current uid then we can skip the change of + * identity. + */ + if (errno == ENOSYS && pw->pw_uid == getuid()) { + return; + } + + bb_perror_msg_and_die("can't set groups"); + } + xsetgid(pw->pw_gid); xsetuid(pw->pw_uid); } -- cgit v1.2.3-55-g6feb