Merge "Update kernel headers to v5.0.3."
diff --git a/docs/status.md b/docs/status.md
index 85f9b60..0cbcb47 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -49,6 +49,11 @@
* `popen` now always uses `O_CLOEXEC`, not just with the `e` extension
* Bug fixes to handling of UTF-8 U+fffe/U+ffff and code points above U+10ffff
* `aligned_alloc` correctly verifies that `size` is a multiple of `alignment`
+ * Using `%n` with the printf family is now reported as a FORTIFY failure.
+ Previous versions of Android would ignore the `%n` but not consume the
+ corresponding pointer argument, leading to obscure errors. The scanf family
+ is unchanged.
+ * [fdsan](fdsan.md) detects common file descriptor errors at runtime.
New libc functions in P (API level 28):
* `aligned_alloc`
@@ -72,6 +77,10 @@
* `%C` and `%S` support in the printf family (previously only the wprintf family supported these)
* `%mc`/`%ms`/`%m[` support in the scanf family
* `%s` support in strptime (strftime already supported it)
+ * Using a `pthread_mutex_t` after it's been destroyed will be detected at
+ runtime and reported as a FORTIFY failure.
+ * Passing a null `FILE*` or `DIR*` to libc is now detected at runtime and
+ reported as a FORTIFY failure.
New libc functions in O (API level 26):
* `sendto` FORTIFY support
@@ -96,6 +105,11 @@
* `strtod_l`/`strtof_l`/`strtol_l`/`strtoul_l`
* <wctype.h> `towctrans`/`towctrans_l`/`wctrans`/`wctrans_l`
+New libc behavior in O (API level 26):
+ * Passing an invalid `pthread_t` to libc is now detected at runtime and
+ reported as a FORTIFY failure. Most commonly this is a result of confusing
+ `pthread_t` and `pid_t`.
+
New libc functions in N (API level 24):
* more FORTIFY support functions (`fread`/`fwrite`/`getcwd`/`pwrite`/`write`)
* all remaining `_FILE_OFFSET_BITS=64` functions, completing `_FILE_OFFSET_BITS=64` support in bionic (8)
@@ -108,6 +122,9 @@
* GNU extensions `fileno_unlocked`/`strchrnul`
* 32-bit `prlimit`
+New libc behavior in N (API level 24):
+ * `sem_wait` now returns EINTR when interrupted by a signal.
+
New libc functions in M (API level 23):
* <dirent.h> `telldir`, `seekdir`.
* <malloc.h> `malloc_info`.
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index d71e6d4..1169ed0 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -149,19 +149,19 @@
*
* Returns 0 for untagged and invalid file descriptors.
*/
-uint64_t android_fdsan_get_owner_tag(int fd);
+uint64_t android_fdsan_get_owner_tag(int fd) __INTRODUCED_IN(29);
/*
* Get an owner tag's string representation.
*
* The return value points to memory with static lifetime, do not attempt to modify it.
*/
-const char* android_fdsan_get_tag_type(uint64_t tag);
+const char* android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
/*
* Get an owner tag's value, with the type masked off.
*/
-uint64_t android_fdsan_get_tag_value(uint64_t tag);
+uint64_t android_fdsan_get_tag_value(uint64_t tag) __INTRODUCED_IN(29);
enum android_fdsan_error_level {
// No errors.
diff --git a/libc/include/bits/get_device_api_level_inlines.h b/libc/include/bits/get_device_api_level_inlines.h
index 9c6e243..d14eb2c 100644
--- a/libc/include/bits/get_device_api_level_inlines.h
+++ b/libc/include/bits/get_device_api_level_inlines.h
@@ -28,11 +28,9 @@
#pragma once
-#include <sys/cdefs.h>
+#if defined(__BIONIC_GET_DEVICE_API_LEVEL_INLINE)
-#if !defined(__BIONIC_GET_DEVICE_API_LEVEL_INLINE)
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static inline /* for versioner */
-#endif
+#include <sys/cdefs.h>
__BEGIN_DECLS
@@ -48,3 +46,5 @@
}
__END_DECLS
+
+#endif // __BIONIC_GET_DEVICE_API_LEVEL_INLINE
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 3089adc..724e5b7 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -137,7 +137,21 @@
const struct timespec* __timeout) __INTRODUCED_IN_64(28);
int pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);
+#if defined(__clang__)
+/*
+ * Disable -Wbuiltin-requires-header because clang confuses this declaration with the one defined in
+ * "llvm/tools/clang/include/clang/Basic/Builtins.def", which did not define any formal arguments.
+ * It seems to be an upstream bug and the fix (https://reviews.llvm.org/D58531) is still under
+ * review. Thus, let's disable the warning for this function declaration.
+ */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
+#endif
int pthread_create(pthread_t* __pthread_ptr, pthread_attr_t const* __attr, void* (*__start_routine)(void*), void*);
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
int pthread_detach(pthread_t __pthread);
void pthread_exit(void* __return_value) __noreturn;
diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp
index 9051308..1742d79 100644
--- a/libc/tzcode/bionic.cpp
+++ b/libc/tzcode/bionic.cpp
@@ -228,13 +228,18 @@
if (fd >= 0) return fd;
#else
// On the host, we don't expect those locations to exist, and we're not
- // worried about security so we trust $ANDROID_DATA, $ANDROID_RUNTIME_ROOT
- // and $ANDROID_ROOT to point us in the right direction.
+ // worried about security so we trust $ANDROID_DATA, $ANDROID_RUNTIME_ROOT,
+ // $ANDROID_TZDATA_ROOT, and $ANDROID_ROOT to point us in the right direction.
char* path = make_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
if (fd >= 0) return fd;
+ path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
+ fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
+ free(path);
+ if (fd >= 0) return fd;
+
path = make_path("ANDROID_RUNTIME_ROOT", "/etc/tz/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
diff --git a/linker/ld.config.format.md b/linker/ld.config.format.md
index 686d6be..faf5cc8 100644
--- a/linker/ld.config.format.md
+++ b/linker/ld.config.format.md
@@ -79,5 +79,8 @@
# and links it to default namespace
namespace.ns.links = default
namespace.ns.link.default.shared_libs = libc.so:libdl.so:libm.so:libstdc++.so
+
+# This defines what libraries are allowed to be loaded from ns1
+namespace.ns1.whitelisted = libsomething.so
```
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 49c8f11..c60ab6a 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -4156,6 +4156,7 @@
ns->set_isolated(ns_config->isolated());
ns->set_default_library_paths(ns_config->search_paths());
ns->set_permitted_paths(ns_config->permitted_paths());
+ ns->set_whitelisted_libs(ns_config->whitelisted_libs());
namespaces[ns_config->name()] = ns;
if (ns_config->visible()) {
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index f7f9c41..437aa86 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -552,6 +552,12 @@
ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
ns_config->set_visible(properties.get_bool(property_name_prefix + ".visible"));
+ std::string whitelisted =
+ properties.get_string(property_name_prefix + ".whitelisted", &lineno);
+ if (!whitelisted.empty()) {
+ ns_config->set_whitelisted_libs(android::base::Split(whitelisted, ":"));
+ }
+
// these are affected by is_asan flag
if (is_asan) {
property_name_prefix += ".asan";
diff --git a/linker/linker_config.h b/linker/linker_config.h
index 49739ee..a318bba 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -92,6 +92,10 @@
return permitted_paths_;
}
+ const std::vector<std::string>& whitelisted_libs() const {
+ return whitelisted_libs_;
+ }
+
const std::vector<NamespaceLinkConfig>& links() const {
return namespace_links_;
}
@@ -116,12 +120,17 @@
void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
permitted_paths_ = permitted_paths;
}
+
+ void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
+ whitelisted_libs_ = whitelisted_libs;
+ }
private:
const std::string name_;
bool isolated_;
bool visible_;
std::vector<std::string> search_paths_;
std::vector<std::string> permitted_paths_;
+ std::vector<std::string> whitelisted_libs_;
std::vector<NamespaceLinkConfig> namespace_links_;
DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceConfig);
diff --git a/linker/linker_config_test.cpp b/linker/linker_config_test.cpp
index 6a55bb2..4937056 100644
--- a/linker/linker_config_test.cpp
+++ b/linker/linker_config_test.cpp
@@ -56,6 +56,7 @@
"enable.target.sdk.version = true\n"
"additional.namespaces=system\n"
"additional.namespaces+=vndk\n"
+ "additional.namespaces+=vndk_in_system\n"
"namespace.default.isolated = true\n"
"namespace.default.search.paths = /vendor/${LIB}\n"
"namespace.default.permitted.paths = /vendor/${LIB}\n"
@@ -82,6 +83,12 @@
"namespace.vndk.asan.search.paths += /system/${LIB}/vndk\n"
"namespace.vndk.links = default\n"
"namespace.vndk.link.default.allow_all_shared_libs = true\n"
+ "namespace.vndk.link.vndk_in_system.allow_all_shared_libs = true\n"
+ "namespace.vndk_in_system.isolated = true\n"
+ "namespace.vndk_in_system.visible = true\n"
+ "namespace.vndk_in_system.search.paths = /system/${LIB}\n"
+ "namespace.vndk_in_system.permitted.paths = /system/${LIB}\n"
+ "namespace.vndk_in_system.whitelisted = libz.so:libyuv.so:libtinyxml2.so\n"
"\n";
static bool write_version(const std::string& path, uint32_t version) {
@@ -165,20 +172,24 @@
ASSERT_FALSE(default_ns_links[1].allow_all_shared_libs());
auto& ns_configs = config->namespace_configs();
- ASSERT_EQ(3U, ns_configs.size());
+ ASSERT_EQ(4U, ns_configs.size());
// find second namespace
const NamespaceConfig* ns_system = nullptr;
const NamespaceConfig* ns_vndk = nullptr;
+ const NamespaceConfig* ns_vndk_in_system = nullptr;
for (auto& ns : ns_configs) {
std::string ns_name = ns->name();
- ASSERT_TRUE(ns_name == "system" || ns_name == "default" || ns_name == "vndk")
+ ASSERT_TRUE(ns_name == "system" || ns_name == "default" ||
+ ns_name == "vndk" || ns_name == "vndk_in_system")
<< "unexpected ns name: " << ns->name();
if (ns_name == "system") {
ns_system = ns.get();
} else if (ns_name == "vndk") {
ns_vndk = ns.get();
+ } else if (ns_name == "vndk_in_system") {
+ ns_vndk_in_system = ns.get();
}
}
@@ -199,6 +210,11 @@
ASSERT_EQ(1U, ns_vndk_links.size());
ASSERT_EQ("default", ns_vndk_links[0].ns_name());
ASSERT_TRUE(ns_vndk_links[0].allow_all_shared_libs());
+
+ ASSERT_TRUE(ns_vndk_in_system != nullptr) << "vndk_in_system namespace was not found";
+ ASSERT_EQ(
+ std::vector<std::string>({"libz.so", "libyuv.so", "libtinyxml2.so"}),
+ ns_vndk_in_system->whitelisted_libs());
}
TEST(linker_config, smoke) {
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index fd72cdc..e870ef7 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -38,6 +38,14 @@
return true;
}
+ if (!whitelisted_libs_.empty()) {
+ const char *lib_name = basename(file.c_str());
+ if (std::find(whitelisted_libs_.begin(), whitelisted_libs_.end(),
+ lib_name) == whitelisted_libs_.end()) {
+ return false;
+ }
+ }
+
for (const auto& dir : ld_library_paths_) {
if (file_is_in_dir(file, dir)) {
return true;
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index cd8b09d..31aeeb6 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -110,6 +110,16 @@
permitted_paths_ = permitted_paths;
}
+ const std::vector<std::string>& get_whitelisted_libs() const {
+ return whitelisted_libs_;
+ }
+ void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
+ whitelisted_libs_ = whitelisted_libs;
+ }
+ void set_whitelisted_libs(const std::vector<std::string>& whitelisted_libs) {
+ whitelisted_libs_ = whitelisted_libs;
+ }
+
const std::vector<android_namespace_link_t>& linked_namespaces() const {
return linked_namespaces_;
}
@@ -157,6 +167,7 @@
std::vector<std::string> ld_library_paths_;
std::vector<std::string> default_library_paths_;
std::vector<std::string> permitted_paths_;
+ std::vector<std::string> whitelisted_libs_;
// Loader looks into linked namespace if it was not able
// to find a library in this namespace. Note that library
// lookup in linked namespaces are limited by the list of