Merge "linker: fix error message for inaccessible libs"
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index eecbe6d..5e3ae45 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -57,3 +57,14 @@
Android all use the 32-bit `time_t`.
In the 64-bit ABI, `time_t` is 64-bit.
+
+`pthread_mutex_t` is too small for large pids
+---------------------------------------------
+
+This doesn't generally affect Android devices, because on devices
+`/proc/sys/kernel/pid_max` is usually too small to hit the 16-bit limit,
+but 32-bit bionic's `pthread_mutex` is a total of 32 bits, leaving just
+16 bits for the owner thread id. This means bionic isn't able to support
+mutexes for tids that don't fit in 16 bits. This typically manifests as
+a hang in `pthread_mutex_lock` if the libc startup code doesn't detect
+this condition and abort.
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 349d488..0b68280 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -77,11 +77,14 @@
netdClientInit();
}
-// We flag the __libc_preinit function as a constructor to ensure
-// that its address is listed in libc.so's .init_array section.
-// This ensures that the function is called by the dynamic linker
-// as soon as the shared library is loaded.
-__attribute__((constructor)) static void __libc_preinit() {
+// We flag the __libc_preinit function as a constructor to ensure that
+// its address is listed in libc.so's .init_array section.
+// This ensures that the function is called by the dynamic linker as
+// soon as the shared library is loaded.
+// We give this constructor priority 1 because we want libc's constructor
+// to run before any others (such as the jemalloc constructor), and lower
+// is better (http://b/68046352).
+__attribute__((constructor(1))) static void __libc_preinit() {
// Read the kernel argument block pointer from TLS.
void** tls = __get_tls();
KernelArgumentBlock** args_slot = &reinterpret_cast<KernelArgumentBlock**>(tls)[TLS_SLOT_BIONIC_PREINIT];
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c
index 7b858ae..b6a3077 100644
--- a/libc/stdio/fread.c
+++ b/libc/stdio/fread.c
@@ -43,6 +43,8 @@
size_t
fread(void *buf, size_t size, size_t count, FILE *fp) __overloadable
{
+ CHECK_FP(fp);
+
/*
* Extension: Catch integer overflow.
*/
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index bf6a8f8..02ea8f8 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -38,6 +38,9 @@
#include <pthread.h>
#include <stdbool.h>
#include <wchar.h>
+
+#include <async_safe/log.h>
+
#include "wcio.h"
/*
@@ -252,4 +255,13 @@
__END_DECLS
+// Sanity check a FILE* for nullptr, so we can emit a message while crashing
+// instead of doing a blind null-dereference.
+#define CHECK_FP(fp) \
+ do { \
+ if (__predict_false(fp == 0)) { \
+ async_safe_fatal("invalid FILE* %p passed to %s", fp, __FUNCTION__); \
+ } \
+ } while (0)
+
#endif
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 4d6438b..cf97a3f 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -44,6 +44,8 @@
#include <sys/stat.h>
#include <unistd.h>
+#include <async_safe/log.h>
+
#include "local.h"
#include "glue.h"
#include "private/bionic_fortify.h"
@@ -261,6 +263,7 @@
// all possible, no matter what.
// TODO: rewrite this mess completely.
FILE* freopen(const char* file, const char* mode, FILE* fp) {
+ CHECK_FP(fp);
int mode_flags;
int flags = __sflags(mode, &mode_flags);
if (flags == 0) {
@@ -361,6 +364,7 @@
__strong_alias(freopen64, freopen);
int fclose(FILE* fp) {
+ CHECK_FP(fp);
if (fp->_flags == 0) {
// Already freed!
errno = EBADF;
@@ -387,6 +391,7 @@
}
int fileno_unlocked(FILE* fp) {
+ CHECK_FP(fp);
int fd = fp->_file;
if (fd == -1) {
errno = EBADF;
@@ -396,6 +401,7 @@
}
int fileno(FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
return fileno_unlocked(fp);
}
@@ -405,24 +411,29 @@
}
void clearerr(FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
clearerr_unlocked(fp);
}
int feof_unlocked(FILE* fp) {
+ CHECK_FP(fp);
return ((fp->_flags & __SEOF) != 0);
}
int feof(FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
return feof_unlocked(fp);
}
int ferror_unlocked(FILE* fp) {
+ CHECK_FP(fp);
return __sferror(fp);
}
int ferror(FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
return ferror_unlocked(fp);
}
@@ -533,24 +544,29 @@
}
int fseeko(FILE* fp, off_t offset, int whence) {
+ CHECK_FP(fp);
static_assert(sizeof(off_t) == sizeof(long), "sizeof(off_t) != sizeof(long)");
return __fseeko64(fp, offset, whence, 8*sizeof(off_t));
}
__strong_alias(fseek, fseeko);
int fseeko64(FILE* fp, off64_t offset, int whence) {
+ CHECK_FP(fp);
return __fseeko64(fp, offset, whence, 8*sizeof(off_t));
}
int fsetpos(FILE* fp, const fpos_t* pos) {
+ CHECK_FP(fp);
return fseeko(fp, *pos, SEEK_SET);
}
int fsetpos64(FILE* fp, const fpos64_t* pos) {
+ CHECK_FP(fp);
return fseeko64(fp, *pos, SEEK_SET);
}
off_t ftello(FILE* fp) {
+ CHECK_FP(fp);
static_assert(sizeof(off_t) == sizeof(long), "sizeof(off_t) != sizeof(long)");
off64_t result = ftello64(fp);
if (result > LONG_MAX) {
@@ -562,16 +578,19 @@
__strong_alias(ftell, ftello);
off64_t ftello64(FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
return __ftello64_unlocked(fp);
}
int fgetpos(FILE* fp, fpos_t* pos) {
+ CHECK_FP(fp);
*pos = ftello(fp);
return (*pos == -1) ? -1 : 0;
}
int fgetpos64(FILE* fp, fpos64_t* pos) {
+ CHECK_FP(fp);
*pos = ftello64(fp);
return (*pos == -1) ? -1 : 0;
}
@@ -642,35 +661,43 @@
}
int fprintf(FILE* fp, const char* fmt, ...) {
+ CHECK_FP(fp);
PRINTF_IMPL(vfprintf(fp, fmt, ap));
}
int fgetc(FILE* fp) {
+ CHECK_FP(fp);
return getc(fp);
}
int fputc(int c, FILE* fp) {
+ CHECK_FP(fp);
return putc(c, fp);
}
int fscanf(FILE* fp, const char* fmt, ...) {
+ CHECK_FP(fp);
PRINTF_IMPL(vfscanf(fp, fmt, ap));
}
int fwprintf(FILE* fp, const wchar_t* fmt, ...) {
+ CHECK_FP(fp);
PRINTF_IMPL(vfwprintf(fp, fmt, ap));
}
int fwscanf(FILE* fp, const wchar_t* fmt, ...) {
+ CHECK_FP(fp);
PRINTF_IMPL(vfwscanf(fp, fmt, ap));
}
int getc(FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
return getc_unlocked(fp);
}
int getc_unlocked(FILE* fp) {
+ CHECK_FP(fp);
return __sgetc(fp);
}
@@ -683,10 +710,12 @@
}
ssize_t getline(char** buf, size_t* len, FILE* fp) {
+ CHECK_FP(fp);
return getdelim(buf, len, '\n', fp);
}
wint_t getwc(FILE* fp) {
+ CHECK_FP(fp);
return fgetwc(fp);
}
@@ -699,11 +728,13 @@
}
int putc(int c, FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
return putc_unlocked(c, fp);
}
int putc_unlocked(int c, FILE* fp) {
+ CHECK_FP(fp);
if (cantwrite(fp)) {
errno = EBADF;
return EOF;
@@ -724,6 +755,7 @@
}
wint_t putwc(wchar_t wc, FILE* fp) {
+ CHECK_FP(fp);
return fputwc(wc, fp);
}
@@ -738,6 +770,7 @@
}
void rewind(FILE* fp) {
+ CHECK_FP(fp);
ScopedFileLock sfl(fp);
fseek(fp, 0, SEEK_SET);
clearerr_unlocked(fp);
@@ -748,14 +781,17 @@
}
void setbuf(FILE* fp, char* buf) {
+ CHECK_FP(fp);
setbuffer(fp, buf, BUFSIZ);
}
void setbuffer(FILE* fp, char* buf, int size) {
+ CHECK_FP(fp);
setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
}
int setlinebuf(FILE* fp) {
+ CHECK_FP(fp);
return setvbuf(fp, nullptr, _IOLBF, 0);
}
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index e036c05..f7d2c53 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -43,6 +43,9 @@
#include <string>
#include <unordered_map>
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+
class ConfigParser {
public:
enum {
@@ -275,6 +278,15 @@
return true;
}
+static std::string getVndkVersionString() {
+ char vndk_version_str[1 + PROP_VALUE_MAX] = {};
+ __system_property_get("ro.vndk.version", vndk_version_str + 1);
+ if (strlen(vndk_version_str + 1) != 0 && strcmp(vndk_version_str + 1, "current") != 0) {
+ vndk_version_str[0] = '-';
+ }
+ return vndk_version_str;
+}
+
static Config g_config;
static constexpr const char* kDefaultConfigName = "default";
@@ -334,6 +346,9 @@
params.push_back({ "SDK_VER", buf });
}
+ static std::string vndk = getVndkVersionString();
+ params.push_back({ "VNDK_VER", vndk });
+
for (auto&& path : paths) {
format_string(&path, params);
}
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 46cd60c..317f0d2 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -130,7 +130,8 @@
// We have historically supported ':' as well as ' ' in LD_PRELOAD.
g_ld_preload_names = android::base::Split(path, " :");
g_ld_preload_names.erase(std::remove_if(g_ld_preload_names.begin(), g_ld_preload_names.end(),
- [](const std::string& s) { return s.empty(); }));
+ [](const std::string& s) { return s.empty(); }),
+ g_ld_preload_names.end());
}
}
diff --git a/tests/limits_test.cpp b/tests/limits_test.cpp
index ed42dbb..e5902ad 100644
--- a/tests/limits_test.cpp
+++ b/tests/limits_test.cpp
@@ -20,7 +20,7 @@
TEST(limits, macros) {
ASSERT_EQ(8, CHAR_BIT);
- ASSERT_EQ(static_cast<int>(sizeof(int)), WORD_BIT);
+ ASSERT_EQ(8 * static_cast<int>(sizeof(int)), WORD_BIT);
ASSERT_EQ(20, NZERO);
#if !defined(MB_LEN_MAX)
#error MB_LEN_MAX
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 3143c50..456ddde 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -985,16 +985,11 @@
VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_ROBUST_PRIO_PROTECT);
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_C_DEV);
- VERIFY_SYSCONF_UNSUPPORTED(_SC_2_CHAR_TERM);
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_LOCALEDEF);
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_SW_DEV);
VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_CRYPT);
- VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_ENH_I18N);
VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_LEGACY);
- VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_REALTIME);
- VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_REALTIME_THREADS);
- VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_SHM);
VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_UUCP);
#endif // defined(__BIONIC__)
}