aboutsummaryrefslogtreecommitdiffstats
path: root/libc/bionic
diff options
context:
space:
mode:
Diffstat (limited to 'libc/bionic')
-rw-r--r--libc/bionic/__poll_chk.cpp49
-rw-r--r--libc/bionic/fchmod.cpp72
-rw-r--r--libc/bionic/fchmodat.cpp67
-rw-r--r--libc/bionic/jemalloc.h1
-rw-r--r--libc/bionic/libc_logging.cpp24
-rw-r--r--libc/bionic/poll.cpp1
6 files changed, 201 insertions, 13 deletions
diff --git a/libc/bionic/__poll_chk.cpp b/libc/bionic/__poll_chk.cpp
new file mode 100644
index 000000000..3acac4e6a
--- /dev/null
+++ b/libc/bionic/__poll_chk.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#undef _FORTIFY_SOURCE
+#include <poll.h>
+#include "private/libc_logging.h"
+
+#include <stdio.h>
+
+extern "C" int __poll_chk(struct pollfd* fds, nfds_t fd_count, int timeout, size_t fds_size) {
+fprintf(stderr, "__poll_chk %p %i %i %i\n", fds, (int)fd_count, timeout, (int) fds_size);
+ if (__predict_false(fds_size / sizeof(*fds) < fd_count)) {
+ __fortify_chk_fail("poll: pollfd array smaller than fd count", 0);
+ }
+ return poll(fds, fd_count, timeout);
+}
+
+extern "C" int __ppoll_chk(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask, size_t fds_size) {
+fprintf(stderr, "__ppoll_chk %p %i %p %p %i\n", fds, (int)fd_count, timeout, mask, (int) fds_size);
+ if (__predict_false(fds_size / sizeof(*fds) < fd_count)) {
+ __fortify_chk_fail("ppoll: pollfd array smaller than fd count", 0);
+ }
+ return ppoll(fds, fd_count, timeout, mask);
+}
diff --git a/libc/bionic/fchmod.cpp b/libc/bionic/fchmod.cpp
new file mode 100644
index 000000000..6e020b6be
--- /dev/null
+++ b/libc/bionic/fchmod.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+
+extern "C" int __fchmod(int, mode_t);
+
+int fchmod(int fd, mode_t mode) {
+ int saved_errno = errno;
+ int result = __fchmod(fd, mode);
+
+ if ((result == 0) || (errno != EBADF)) {
+ return result;
+ }
+
+ // fd could be an O_PATH file descriptor, and the kernel
+ // may not directly support fchmod() on such a file descriptor.
+ // Use /proc/self/fd instead to emulate this support.
+ // https://sourceware.org/bugzilla/show_bug.cgi?id=14578
+ //
+ // As of February 2015, there are no kernels which support fchmod
+ // on an O_PATH file descriptor, and "man open" documents fchmod
+ // on O_PATH file descriptors as returning EBADF.
+ int fd_flag = fcntl(fd, F_GETFL);
+ if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
+ errno = EBADF;
+ return -1;
+ }
+
+ char buf[40];
+ snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
+ errno = saved_errno;
+ result = chmod(buf, mode);
+ if ((result == -1) && (errno == ELOOP)) {
+ // Linux does not support changing the mode of a symlink.
+ // For fchmodat(AT_SYMLINK_NOFOLLOW), POSIX requires a return
+ // value of ENOTSUP. Assume that's true here too.
+ errno = ENOTSUP;
+ }
+
+ return result;
+}
diff --git a/libc/bionic/fchmodat.cpp b/libc/bionic/fchmodat.cpp
new file mode 100644
index 000000000..c28e15ac7
--- /dev/null
+++ b/libc/bionic/fchmodat.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "private/ErrnoRestorer.h"
+
+extern "C" int __fchmodat(int, const char*, mode_t);
+
+int fchmodat(int dirfd, const char* pathname, mode_t mode, int flags) {
+ if ((flags & ~AT_SYMLINK_NOFOLLOW) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (flags & AT_SYMLINK_NOFOLLOW) {
+ // Emulate AT_SYMLINK_NOFOLLOW using the mechanism described
+ // at https://sourceware.org/bugzilla/show_bug.cgi?id=14578
+ // comment #10
+
+ int fd = openat(dirfd, pathname, O_PATH | O_NOFOLLOW | O_CLOEXEC);
+ if (fd == -1) {
+ return -1; // returns errno from openat
+ }
+
+ // POSIX requires that ENOTSUP be returned when the system
+ // doesn't support setting the mode of a symbolic link.
+ // This is true for all Linux kernels.
+ // We rely on the O_PATH compatibility layer added in the
+ // fchmod() function to get errno correct.
+ int result = fchmod(fd, mode);
+ ErrnoRestorer errno_restorer; // don't let close() clobber errno
+ close(fd);
+ return result;
+ }
+
+ return __fchmodat(dirfd, pathname, mode);
+}
diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h
index feb1f43a5..98ea0eedb 100644
--- a/libc/bionic/jemalloc.h
+++ b/libc/bionic/jemalloc.h
@@ -18,6 +18,7 @@
#define LIBC_BIONIC_JEMALLOC_H_
#include <jemalloc/jemalloc.h>
+#include <malloc.h> // For struct mallinfo.
// Need to wrap memalign since je_memalign fails on non-power of 2 alignments.
#define je_memalign je_memalign_round_up_boundary
diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp
index 49a37628f..76bc46ddf 100644
--- a/libc/bionic/libc_logging.cpp
+++ b/libc/bionic/libc_logging.cpp
@@ -438,7 +438,7 @@ static int __libc_write_stderr(const char* tag, const char* msg) {
vec[1].iov_base = const_cast<char*>(": ");
vec[1].iov_len = 2;
vec[2].iov_base = const_cast<char*>(msg);
- vec[2].iov_len = strlen(msg) + 1;
+ vec[2].iov_len = strlen(msg);
vec[3].iov_base = const_cast<char*>("\n");
vec[3].iov_len = 1;
@@ -448,8 +448,7 @@ static int __libc_write_stderr(const char* tag, const char* msg) {
}
#ifdef TARGET_USES_LOGD
-static int __libc_open_log_socket()
-{
+static int __libc_open_log_socket() {
// ToDo: Ideally we want this to fail if the gid of the current
// process is AID_LOGD, but will have to wait until we have
// registered this in private/android_filesystem_config.h. We have
@@ -491,7 +490,6 @@ struct log_time { // Wire format
static int __libc_write_log(int priority, const char* tag, const char* msg) {
#ifdef TARGET_USES_LOGD
int main_log_fd = __libc_open_log_socket();
-
if (main_log_fd == -1) {
// Try stderr instead.
return __libc_write_stderr(tag, msg);
@@ -515,9 +513,9 @@ static int __libc_write_log(int priority, const char* tag, const char* msg) {
vec[3].iov_base = &priority;
vec[3].iov_len = 1;
vec[4].iov_base = const_cast<char*>(tag);
- vec[4].iov_len = strlen(tag) + 1;
+ vec[4].iov_len = strlen(tag);
vec[5].iov_base = const_cast<char*>(msg);
- vec[5].iov_len = strlen(msg) + 1;
+ vec[5].iov_len = strlen(msg);
#else
int main_log_fd = TEMP_FAILURE_RETRY(open("/dev/log/main", O_CLOEXEC | O_WRONLY));
if (main_log_fd == -1) {
@@ -532,9 +530,9 @@ static int __libc_write_log(int priority, const char* tag, const char* msg) {
vec[0].iov_base = &priority;
vec[0].iov_len = 1;
vec[1].iov_base = const_cast<char*>(tag);
- vec[1].iov_len = strlen(tag) + 1;
+ vec[1].iov_len = strlen(tag);
vec[2].iov_base = const_cast<char*>(msg);
- vec[2].iov_len = strlen(msg) + 1;
+ vec[2].iov_len = strlen(msg);
#endif
int result = TEMP_FAILURE_RETRY(writev(main_log_fd, vec, sizeof(vec) / sizeof(vec[0])));
@@ -614,7 +612,7 @@ void __fortify_chk_fail(const char* msg, uint32_t tag) {
if (tag != 0) {
__libc_android_log_event_uid(tag);
}
- __libc_fatal("FORTIFY_SOURCE: %s. Calling abort().", msg);
+ __libc_fatal("FORTIFY: %s", msg);
}
static void __libc_fatal(const char* format, va_list args) {
@@ -622,12 +620,12 @@ static void __libc_fatal(const char* format, va_list args) {
BufferOutputStream os(msg, sizeof(msg));
out_vformat(os, format, args);
- // log to stderr for the benefit of "adb shell" users.
+ // Log to stderr for the benefit of "adb shell" users.
struct iovec iov[2] = {
- {msg, strlen(msg)},
- {const_cast<void*>(static_cast<const void*>("\n")), 1},
+ { msg, os.total },
+ { const_cast<char*>("\n"), 1 },
};
- writev(2, iov, 2);
+ TEMP_FAILURE_RETRY(writev(2, iov, 2));
// Log to the log for the benefit of regular app developers (whose stdout and stderr are closed).
__libc_write_log(ANDROID_LOG_FATAL, "libc", msg);
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index d267229b7..23ef90a8f 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -26,6 +26,7 @@
* SUCH DAMAGE.
*/
+#undef _FORTIFY_SOURCE
#include <errno.h>
#include <sys/poll.h>
#include <sys/select.h>