Merge "adb: add missing condition_variable include"
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp
index e9a3ebd..4b32b9d 100644
--- a/debuggerd/crasher/crasher.cpp
+++ b/debuggerd/crasher/crasher.cpp
@@ -289,7 +289,7 @@
munmap(map, sizeof(int));
map[0] = '8';
} else if (!strcasecmp(arg, "seccomp")) {
- set_seccomp_filter();
+ set_system_seccomp_filter();
syscall(99999);
#if defined(__arm__)
} else if (!strcasecmp(arg, "kuser_helper_version")) {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 4b94f9c..a2b80ad 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -38,6 +38,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
+#include <cutils/android_filesystem_config.h>
#include <cutils/android_reboot.h>
#include <cutils/partition_utils.h>
#include <cutils/properties.h>
@@ -353,7 +354,7 @@
reserved_blocks = max_reserved_blocks;
}
- if (ext4_r_blocks_count(sb) == reserved_blocks) {
+ if ((ext4_r_blocks_count(sb) == reserved_blocks) && (sb->s_def_resgid == AID_RESERVED_DISK)) {
return;
}
@@ -363,11 +364,12 @@
return;
}
- char buf[32];
- const char* argv[] = {TUNE2FS_BIN, "-r", buf, blk_device};
-
- snprintf(buf, sizeof(buf), "%" PRIu64, reserved_blocks);
LINFO << "Setting reserved block count on " << blk_device << " to " << reserved_blocks;
+
+ auto reserved_blocks_str = std::to_string(reserved_blocks);
+ auto reserved_gid_str = std::to_string(AID_RESERVED_DISK);
+ const char* argv[] = {
+ TUNE2FS_BIN, "-r", reserved_blocks_str.c_str(), "-g", reserved_gid_str.c_str(), blk_device};
if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
LERROR << "Failed to run " TUNE2FS_BIN " to set the number of reserved blocks on "
<< blk_device;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 34afed1..1c01d8c 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -638,6 +638,7 @@
* frees up memory of the return value without touching a and b. */
static struct fstab *in_place_merge(struct fstab *a, struct fstab *b)
{
+ if (!a && !b) return nullptr;
if (!a) return b;
if (!b) return a;
@@ -654,12 +655,13 @@
}
for (int i = a->num_entries, j = 0; i < total_entries; i++, j++) {
- // copy the pointer directly *without* malloc and memcpy
+ // Copy the structs by assignment.
a->recs[i] = b->recs[j];
}
- // Frees up b, but don't free b->recs[X] to make sure they are
- // accessible through a->recs[X].
+ // We can't call fs_mgr_free_fstab because a->recs still references the
+ // memory allocated by strdup.
+ free(b->recs);
free(b->fstab_filename);
free(b);
@@ -754,15 +756,17 @@
default_fstab = get_fstab_path();
}
- if (default_fstab.empty()) {
- LWARNING << __FUNCTION__ << "(): failed to find device default fstab";
+ struct fstab* fstab = nullptr;
+ if (!default_fstab.empty()) {
+ fstab = fs_mgr_read_fstab(default_fstab.c_str());
+ } else {
+ LINFO << __FUNCTION__ << "(): failed to find device default fstab";
}
+ struct fstab* fstab_dt = fs_mgr_read_fstab_dt();
+
// combines fstab entries passed in from device tree with
// the ones found from default_fstab file
- struct fstab *fstab_dt = fs_mgr_read_fstab_dt();
- struct fstab *fstab = fs_mgr_read_fstab(default_fstab.c_str());
-
return in_place_merge(fstab_dt, fstab);
}
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 4b6c502..7aa94b0 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -58,7 +58,6 @@
#include "init.h"
#include "persistent_properties.h"
-#include "space_tokenizer.h"
#include "util.h"
using android::base::ReadFileToString;
@@ -69,6 +68,7 @@
using android::base::Trim;
using android::base::WriteStringToFile;
using android::properties::BuildTrie;
+using android::properties::ParsePropertyInfoFile;
using android::properties::PropertyInfoAreaFile;
using android::properties::PropertyInfoEntry;
@@ -350,13 +350,15 @@
ufds[0].events = POLLIN;
ufds[0].revents = 0;
while (*timeout_ms > 0) {
- Timer timer;
- int nr = poll(ufds, 1, *timeout_ms);
- uint64_t millis = timer.duration().count();
- *timeout_ms = (millis > *timeout_ms) ? 0 : *timeout_ms - millis;
+ auto start_time = std::chrono::steady_clock::now();
+ int nr = poll(ufds, 1, *timeout_ms);
+ auto now = std::chrono::steady_clock::now();
+ auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
+ uint64_t millis = time_elapsed.count();
+ *timeout_ms = (millis > *timeout_ms) ? 0 : *timeout_ms - millis;
- if (nr > 0) {
- return true;
+ if (nr > 0) {
+ return true;
}
if (nr == 0) {
@@ -726,22 +728,6 @@
return 0;
}
-Result<PropertyInfoEntry> ParsePropertyInfoLine(const std::string& line) {
- auto tokenizer = SpaceTokenizer(line);
-
- auto property = tokenizer.GetNext();
- if (property.empty()) return Error() << "Did not find a property entry in '" << line << "'";
-
- auto context = tokenizer.GetNext();
- if (context.empty()) return Error() << "Did not find a context entry in '" << line << "'";
-
- // It is not an error to not find these, as older files will not contain them.
- auto exact_match = tokenizer.GetNext();
- auto schema = tokenizer.GetRemaining();
-
- return {property, context, schema, exact_match == "exact"};
-}
-
bool LoadPropertyInfoFromFile(const std::string& filename,
std::vector<PropertyInfoEntry>* property_infos) {
auto file_contents = std::string();
@@ -750,20 +736,14 @@
return false;
}
- for (const auto& line : Split(file_contents, "\n")) {
- auto trimmed_line = Trim(line);
- if (trimmed_line.empty() || StartsWith(trimmed_line, "#")) {
- continue;
- }
-
- auto property_info = ParsePropertyInfoLine(line);
- if (!property_info) {
- LOG(ERROR) << "Could not read line from '" << filename << "': " << property_info.error();
- continue;
- }
-
- property_infos->emplace_back(*property_info);
+ auto errors = std::vector<std::string>{};
+ ParsePropertyInfoFile(file_contents, property_infos, &errors);
+ // Individual parsing errors are reported but do not cause a failed boot, which is what
+ // returning false would do here.
+ for (const auto& error : errors) {
+ LOG(ERROR) << "Could not read line from '" << filename << "': " << error;
}
+
return true;
}
diff --git a/init/space_tokenizer.h b/init/space_tokenizer.h
deleted file mode 100644
index e7e22c5..0000000
--- a/init/space_tokenizer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _INIT_SPACE_TOKENIZER_H
-#define _INIT_SPACE_TOKENIZER_H
-
-namespace android {
-namespace init {
-
-class SpaceTokenizer {
- public:
- SpaceTokenizer(const std::string& string)
- : string_(string), it_(string_.begin()), end_(string_.end()) {}
-
- std::string GetNext() {
- auto next = std::string();
- while (it_ != end_ && !isspace(*it_)) {
- next.push_back(*it_++);
- }
- while (it_ != end_ && isspace(*it_)) {
- it_++;
- }
- return next;
- }
-
- std::string GetRemaining() { return std::string(it_, end_); }
-
- private:
- std::string string_;
- std::string::const_iterator it_;
- std::string::const_iterator end_;
-};
-
-} // namespace init
-} // namespace android
-
-#endif
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 2ecf5bc..2f2e262 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -122,6 +122,7 @@
#define AID_AUTOMOTIVE_EVS 1062 /* Automotive rear and surround view system */
#define AID_LOWPAN 1063 /* LoWPAN subsystem */
#define AID_HSM 1064 /* hardware security module subsystem */
+#define AID_RESERVED_DISK 1065 /* GID that has access to reserved disk space */
/* Changes to this file must be made in AOSP, *not* in internal branches. */
#define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
index 4b21edc..17983bc 100644
--- a/libnativeloader/Android.bp
+++ b/libnativeloader/Android.bp
@@ -19,4 +19,8 @@
"-fvisibility=hidden",
],
export_include_dirs: ["include"],
+ required: [
+ "llndk.libraries.txt",
+ "vndksp.libraries.txt",
+ ],
}
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index e9f0c0f..6ddec4d 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -662,22 +662,51 @@
return handle;
}
#else
- UNUSED(env, target_sdk_version, class_loader, library_path);
- *needs_native_bridge = false;
- void* handle = dlopen(path, RTLD_NOW);
- if (handle == nullptr) {
- if (NativeBridgeIsSupported(path)) {
- *needs_native_bridge = true;
- handle = NativeBridgeLoadLibrary(path, RTLD_NOW);
- if (handle == nullptr) {
- *error_msg = NativeBridgeGetError();
- }
+ UNUSED(env, target_sdk_version, class_loader);
+
+ // Do some best effort to emulate library-path support. It will not
+ // work for dependencies.
+ //
+ // Note: null has a special meaning and must be preserved.
+ std::string c_library_path; // Empty string by default.
+ if (library_path != nullptr && path != nullptr && path[0] != '/') {
+ ScopedUtfChars library_path_utf_chars(env, library_path);
+ c_library_path = library_path_utf_chars.c_str();
+ }
+
+ std::vector<std::string> library_paths = base::Split(c_library_path, ":");
+
+ for (const std::string& lib_path : library_paths) {
+ *needs_native_bridge = false;
+ const char* path_arg;
+ std::string complete_path;
+ if (path == nullptr) {
+ // Preserve null.
+ path_arg = nullptr;
} else {
- *needs_native_bridge = false;
+ complete_path = lib_path;
+ if (!complete_path.empty()) {
+ complete_path.append("/");
+ }
+ complete_path.append(path);
+ path_arg = complete_path.c_str();
+ }
+ void* handle = dlopen(path_arg, RTLD_NOW);
+ if (handle != nullptr) {
+ return handle;
+ }
+ if (NativeBridgeIsSupported(path_arg)) {
+ *needs_native_bridge = true;
+ handle = NativeBridgeLoadLibrary(path_arg, RTLD_NOW);
+ if (handle != nullptr) {
+ return handle;
+ }
+ *error_msg = NativeBridgeGetError();
+ } else {
*error_msg = dlerror();
}
}
- return handle;
+ return nullptr;
#endif
}
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 5cfa2c8..fd83ecc 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -900,7 +900,9 @@
downgrade_pressure = (int64_t)property_get_int32("ro.lmk.downgrade_pressure", 60);
is_go_device = property_get_bool("ro.config.low_ram", false);
- mlockall(MCL_FUTURE);
+ if (mlockall(MCL_CURRENT | MCL_FUTURE))
+ ALOGW("mlockall failed: errno=%d", errno);
+
sched_setscheduler(0, SCHED_FIFO, ¶m);
if (!init())
mainloop();
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 1d0cc33..b76160d 100755
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -45,7 +45,7 @@
'0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) % 10, '>'
LogAudit::LogAudit(LogBuffer* buf, LogReader* reader, int fdDmesg)
- : SocketListener(mSock = getLogSocket(), false),
+ : SocketListener(getLogSocket(), false),
logbuf(buf),
reader(reader),
fdDmesg(fdDmesg),
@@ -53,8 +53,7 @@
BOOL_DEFAULT_TRUE)),
events(__android_logger_property_get_bool("ro.logd.auditd.events",
BOOL_DEFAULT_TRUE)),
- initialized(false),
- tooFast(false) {
+ initialized(false) {
static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO),
'l',
'o',
@@ -78,54 +77,12 @@
write(fdDmesg, auditd_message, sizeof(auditd_message));
}
-void LogAudit::checkRateLimit() {
- // trim list for AUDIT_RATE_LIMIT_BURST_DURATION of history
- log_time oldest(AUDIT_RATE_LIMIT_BURST_DURATION, 0);
- bucket.emplace(android_log_clockid());
- oldest = bucket.back() - oldest;
- while (bucket.front() < oldest) bucket.pop();
-
- static const size_t upperThreshold =
- ((AUDIT_RATE_LIMIT_BURST_DURATION *
- (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) +
- 1) /
- 2;
- if (bucket.size() >= upperThreshold) {
- // Hit peak, slow down source
- if (!tooFast) {
- tooFast = true;
- audit_rate_limit(mSock, AUDIT_RATE_LIMIT_MAX);
- }
-
- // We do not need to hold on to the full set of timing data history,
- // let's ensure it does not grow without bounds. This also ensures
- // that std::dequeue underneath behaves almost like a ring buffer.
- do {
- bucket.pop();
- } while (bucket.size() >= upperThreshold);
- return;
- }
-
- if (!tooFast) return;
-
- static const size_t lowerThreshold =
- AUDIT_RATE_LIMIT_BURST_DURATION * AUDIT_RATE_LIMIT_MAX;
-
- if (bucket.size() >= lowerThreshold) return;
-
- tooFast = false;
- // Went below max sustained rate, allow source to speed up
- audit_rate_limit(mSock, AUDIT_RATE_LIMIT_DEFAULT);
-}
-
bool LogAudit::onDataAvailable(SocketClient* cli) {
if (!initialized) {
prctl(PR_SET_NAME, "logd.auditd");
initialized = true;
}
- checkRateLimit();
-
struct audit_message rep;
rep.nlh.nlmsg_type = 0;
@@ -486,6 +443,5 @@
audit_close(fd);
fd = -1;
}
- (void)audit_rate_limit(fd, AUDIT_RATE_LIMIT_DEFAULT);
return fd;
}
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 2bd02d4..5904966 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -18,7 +18,6 @@
#define _LOGD_LOG_AUDIT_H__
#include <map>
-#include <queue>
#include <sysutils/SocketListener.h>
@@ -34,11 +33,6 @@
bool events;
bool initialized;
- bool tooFast;
- int mSock;
- std::queue<log_time> bucket;
- void checkRateLimit();
-
public:
LogAudit(LogBuffer* buf, LogReader* reader, int fdDmesg);
int log(char* buf, size_t len);
diff --git a/logd/libaudit.c b/logd/libaudit.c
index dfd56f2..9d9a857 100644
--- a/logd/libaudit.c
+++ b/logd/libaudit.c
@@ -160,7 +160,8 @@
* and the the mask set to AUDIT_STATUS_PID
*/
status.pid = pid;
- status.mask = AUDIT_STATUS_PID;
+ status.mask = AUDIT_STATUS_PID | AUDIT_STATUS_RATE_LIMIT;
+ status.rate_limit = AUDIT_RATE_LIMIT; /* audit entries per second */
/* Let the kernel know this pid will be registering for audit events */
rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
@@ -183,26 +184,6 @@
return 0;
}
-int audit_rate_limit(int fd, unsigned rate_limit) {
- int rc;
- struct audit_message rep;
- struct audit_status status;
-
- memset(&status, 0, sizeof(status));
-
- status.mask = AUDIT_STATUS_RATE_LIMIT;
- status.rate_limit = rate_limit; /* audit entries per second */
-
- rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
- if (rc < 0) {
- return rc;
- }
-
- audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
-
- return 0;
-}
-
int audit_open() {
return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT);
}
diff --git a/logd/libaudit.h b/logd/libaudit.h
index a2afe47..2a93ea3 100644
--- a/logd/libaudit.h
+++ b/logd/libaudit.h
@@ -89,22 +89,8 @@
*/
extern int audit_setup(int fd, pid_t pid);
-/**
- * Sets the rate limit to receive audit netlink events from the kernel
- * @param fd
- * The fd returned by a call to audit_open()
- * @param max_rate
- * The cap of the maximum number of audit messages a second
- * @return
- * This function returns 0 on success, -errno on error.
- */
-
-/* Guidelines to follow for dynamic rate_limit */
-#define AUDIT_RATE_LIMIT_DEFAULT 20 /* acceptable burst rate */
-#define AUDIT_RATE_LIMIT_BURST_DURATION 10 /* number of seconds of burst */
-#define AUDIT_RATE_LIMIT_MAX 5 /* acceptable sustained rate */
-
-extern int audit_rate_limit(int fd, unsigned rate_limit);
+/* Max audit messages per second */
+#define AUDIT_RATE_LIMIT 5
__END_DECLS
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 9e1541b..7d7a22f 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -1195,51 +1195,14 @@
<< "fail as this device is in a bad state, "
<< "but is not strictly a unit test failure.";
}
- // sepolicy_rate_limiter_maximum
- { // maximum precharch test block.
- static constexpr int rate = AUDIT_RATE_LIMIT_MAX;
- static constexpr int duration = 2;
- // Two seconds of a liveable sustained rate
- EXPECT_EQ(rate * duration,
- count_avc(sepolicy_rate(rate, rate * duration)));
- }
- // sepolicy_rate_limiter_sub_burst
- { // maximum period below half way between sustainable and burst rate
- static constexpr int threshold =
- ((AUDIT_RATE_LIMIT_BURST_DURATION *
- (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) +
- 1) /
- 2;
- static constexpr int rate =
- (threshold / AUDIT_RATE_LIMIT_BURST_DURATION) - 1;
- static constexpr int duration = AUDIT_RATE_LIMIT_BURST_DURATION;
- EXPECT_EQ(rate * duration,
- count_avc(sepolicy_rate(rate, rate * duration)));
- }
- // sepolicy_rate_limiter_spam
- { // hit avc: hard beyond reason block.
- // maximum period of double the maximum burst rate
- static constexpr int threshold =
- ((AUDIT_RATE_LIMIT_BURST_DURATION *
- (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) +
- 1) /
- 2;
- static constexpr int rate = AUDIT_RATE_LIMIT_DEFAULT * 2;
- static constexpr int duration = threshold / AUDIT_RATE_LIMIT_DEFAULT;
- EXPECT_GE(
- ((AUDIT_RATE_LIMIT_DEFAULT * duration) * 115) / 100, // +15% margin
- count_avc(sepolicy_rate(rate, rate * duration)));
- // give logd another 3 seconds to react to the burst before checking
- sepolicy_rate(rate, rate * 3);
- // maximum period at double maximum burst rate (spam filter kicked in)
- EXPECT_GE(threshold * 2,
- count_avc(sepolicy_rate(
- rate, rate * AUDIT_RATE_LIMIT_BURST_DURATION)));
- // cool down, and check unspammy rate still works
- sleep(2);
- EXPECT_LE(AUDIT_RATE_LIMIT_BURST_DURATION - 1, // allow _one_ lost
- count_avc(sepolicy_rate(1, AUDIT_RATE_LIMIT_BURST_DURATION)));
- }
+
+ static const int rate = AUDIT_RATE_LIMIT;
+ static const int duration = 2;
+ // Two seconds of sustained denials. Depending on the overlap in the time
+ // window that the kernel is considering vs what this test is considering,
+ // allow some additional denials to prevent a flaky test.
+ EXPECT_LE(count_avc(sepolicy_rate(rate, rate * duration)),
+ rate * duration + rate);
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
diff --git a/property_service/OWNERS b/property_service/OWNERS
new file mode 100644
index 0000000..babbe4d
--- /dev/null
+++ b/property_service/OWNERS
@@ -0,0 +1 @@
+tomcherry@google.com
diff --git a/property_service/libpropertyinfoparser/Android.bp b/property_service/libpropertyinfoparser/Android.bp
index 3e732b5..ffaa2b3 100644
--- a/property_service/libpropertyinfoparser/Android.bp
+++ b/property_service/libpropertyinfoparser/Android.bp
@@ -1,10 +1,15 @@
cc_library_static {
name: "libpropertyinfoparser",
+ host_supported: true,
srcs: ["property_info_parser.cpp"],
cpp_std: "experimental",
- sanitize: {
- misc_undefined: ["signed-integer-overflow"],
+ target: {
+ linux: {
+ sanitize: {
+ misc_undefined: ["signed-integer-overflow"],
+ },
+ },
},
cppflags: [
"-Wall",
diff --git a/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h b/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h
index 8c3507e..2ee8161 100644
--- a/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h
+++ b/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h
@@ -18,6 +18,7 @@
#define PROPERTY_INFO_PARSER_H
#include <stdint.h>
+#include <stdlib.h>
namespace android {
namespace properties {
diff --git a/property_service/libpropertyinfoserializer/Android.bp b/property_service/libpropertyinfoserializer/Android.bp
index 20e5e13..0a1593b 100644
--- a/property_service/libpropertyinfoserializer/Android.bp
+++ b/property_service/libpropertyinfoserializer/Android.bp
@@ -1,8 +1,13 @@
cc_defaults {
name: "propertyinfoserializer_defaults",
+ host_supported: true,
cpp_std: "experimental",
- sanitize: {
- misc_undefined: ["signed-integer-overflow"],
+ target: {
+ linux: {
+ sanitize: {
+ misc_undefined: ["signed-integer-overflow"],
+ },
+ },
},
cppflags: [
"-Wall",
@@ -19,6 +24,7 @@
name: "libpropertyinfoserializer",
defaults: ["propertyinfoserializer_defaults"],
srcs: [
+ "property_info_file.cpp",
"property_info_serializer.cpp",
"trie_builder.cpp",
"trie_serializer.cpp",
diff --git a/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h b/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h
index f7e708e..d2ec385 100644
--- a/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h
+++ b/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h
@@ -41,6 +41,10 @@
const std::string& default_context, const std::string& default_schema,
std::string* serialized_trie, std::string* error);
+void ParsePropertyInfoFile(const std::string& file_contents,
+ std::vector<PropertyInfoEntry>* property_infos,
+ std::vector<std::string>* errors);
+
} // namespace properties
} // namespace android
diff --git a/property_service/libpropertyinfoserializer/property_info_file.cpp b/property_service/libpropertyinfoserializer/property_info_file.cpp
new file mode 100644
index 0000000..702f219
--- /dev/null
+++ b/property_service/libpropertyinfoserializer/property_info_file.cpp
@@ -0,0 +1,62 @@
+#include <property_info_serializer/property_info_serializer.h>
+
+#include <android-base/strings.h>
+
+#include "space_tokenizer.h"
+
+using android::base::Split;
+using android::base::StartsWith;
+using android::base::Trim;
+
+namespace android {
+namespace properties {
+
+bool ParsePropertyInfoLine(const std::string& line, PropertyInfoEntry* out, std::string* error) {
+ auto tokenizer = SpaceTokenizer(line);
+
+ auto property = tokenizer.GetNext();
+ if (property.empty()) {
+ *error = "Did not find a property entry in '" + line + "'";
+ return false;
+ }
+
+ auto context = tokenizer.GetNext();
+ if (context.empty()) {
+ *error = "Did not find a context entry in '" + line + "'";
+ return false;
+ }
+
+ // It is not an error to not find these, as older files will not contain them.
+ auto exact_match = tokenizer.GetNext();
+ auto schema = tokenizer.GetRemaining();
+
+ *out = {property, context, schema, exact_match == "exact"};
+ return true;
+}
+
+void ParsePropertyInfoFile(const std::string& file_contents,
+ std::vector<PropertyInfoEntry>* property_infos,
+ std::vector<std::string>* errors) {
+ // Do not clear property_infos to allow this function to be called on multiple files, with
+ // their results concatenated.
+ errors->clear();
+
+ for (const auto& line : Split(file_contents, "\n")) {
+ auto trimmed_line = Trim(line);
+ if (trimmed_line.empty() || StartsWith(trimmed_line, "#")) {
+ continue;
+ }
+
+ auto property_info_entry = PropertyInfoEntry{};
+ auto parse_error = std::string{};
+ if (!ParsePropertyInfoLine(trimmed_line, &property_info_entry, &parse_error)) {
+ errors->emplace_back(parse_error);
+ continue;
+ }
+
+ property_infos->emplace_back(property_info_entry);
+ }
+}
+
+} // namespace properties
+} // namespace android
diff --git a/property_service/libpropertyinfoserializer/space_tokenizer.h b/property_service/libpropertyinfoserializer/space_tokenizer.h
new file mode 100644
index 0000000..fba0c58
--- /dev/null
+++ b/property_service/libpropertyinfoserializer/space_tokenizer.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PROPERTY_INFO_SERIALIZER_SPACE_TOKENIZER_H
+#define PROPERTY_INFO_SERIALIZER_SPACE_TOKENIZER_H
+
+namespace android {
+namespace properties {
+
+class SpaceTokenizer {
+ public:
+ SpaceTokenizer(const std::string& string)
+ : string_(string), it_(string_.begin()), end_(string_.end()) {}
+
+ std::string GetNext() {
+ auto next = std::string();
+ while (it_ != end_ && !isspace(*it_)) {
+ next.push_back(*it_++);
+ }
+ while (it_ != end_ && isspace(*it_)) {
+ it_++;
+ }
+ return next;
+ }
+
+ std::string GetRemaining() { return std::string(it_, end_); }
+
+ private:
+ std::string string_;
+ std::string::const_iterator it_;
+ std::string::const_iterator end_;
+};
+
+} // namespace properties
+} // namespace android
+
+#endif
diff --git a/property_service/property_info_checker/Android.bp b/property_service/property_info_checker/Android.bp
new file mode 100644
index 0000000..6e9e7f1
--- /dev/null
+++ b/property_service/property_info_checker/Android.bp
@@ -0,0 +1,19 @@
+cc_binary {
+ name: "property_info_checker",
+ host_supported: true,
+ static_executable: true,
+ cpp_std: "experimental",
+ target: {
+ linux: {
+ sanitize: {
+ misc_undefined: ["signed-integer-overflow"],
+ },
+ },
+ },
+ static_libs: [
+ "libpropertyinfoserializer",
+ "libpropertyinfoparser",
+ "libbase",
+ ],
+ srcs: ["property_info_checker.cpp"],
+}
diff --git a/property_service/property_info_checker/property_info_checker.cpp b/property_service/property_info_checker/property_info_checker.cpp
new file mode 100644
index 0000000..e4f8264
--- /dev/null
+++ b/property_service/property_info_checker/property_info_checker.cpp
@@ -0,0 +1,51 @@
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+
+#include <property_info_serializer/property_info_serializer.h>
+
+using android::base::ReadFileToString;
+using android::properties::BuildTrie;
+using android::properties::ParsePropertyInfoFile;
+using android::properties::PropertyInfoEntry;
+
+int main(int argc, char** argv) {
+ if (argc < 2) {
+ std::cerr << "A list of property info files to be checked is expected on the command line"
+ << std::endl;
+ return -1;
+ }
+
+ auto property_info_entries = std::vector<PropertyInfoEntry>{};
+
+ for (int i = 1; i < argc; ++i) {
+ auto filename = argv[i];
+ auto file_contents = std::string{};
+ if (!ReadFileToString(filename, &file_contents)) {
+ std::cerr << "Could not read properties from '" << filename << "'" << std::endl;
+ return -1;
+ }
+
+ auto errors = std::vector<std::string>{};
+ ParsePropertyInfoFile(file_contents, &property_info_entries, &errors);
+ if (!errors.empty()) {
+ for (const auto& error : errors) {
+ std::cerr << "Could not read line from '" << filename << "': " << error << std::endl;
+ }
+ return -1;
+ }
+ }
+
+ auto serialized_contexts = std::string{};
+ auto build_trie_error = std::string{};
+
+ if (!BuildTrie(property_info_entries, "u:object_r:default_prop:s0", "\\s*", &serialized_contexts,
+ &build_trie_error)) {
+ std::cerr << "Unable to serialize property contexts: " << build_trie_error << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 492d63a..19269d8 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -77,7 +77,7 @@
#
# create some directories (some are mount points) and symlinks
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- sbin dev proc sys system data oem acct config storage mnt $(BOARD_ROOT_EXTRA_FOLDERS)); \
+ sbin dev proc sys system data odm oem acct config storage mnt $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
diff --git a/rootdir/init.zygote32.rc b/rootdir/init.zygote32.rc
index d836c4e..ac87979 100644
--- a/rootdir/init.zygote32.rc
+++ b/rootdir/init.zygote32.rc
@@ -2,7 +2,7 @@
class main
priority -20
user root
- group root readproc
+ group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
index 80bb673..a535846 100644
--- a/rootdir/init.zygote32_64.rc
+++ b/rootdir/init.zygote32_64.rc
@@ -2,7 +2,7 @@
class main
priority -20
user root
- group root readproc
+ group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
@@ -17,7 +17,7 @@
class main
priority -20
user root
- group root readproc
+ group root readproc reserved_disk
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
diff --git a/rootdir/init.zygote64.rc b/rootdir/init.zygote64.rc
index 05ec16f..6fc810b 100644
--- a/rootdir/init.zygote64.rc
+++ b/rootdir/init.zygote64.rc
@@ -2,7 +2,7 @@
class main
priority -20
user root
- group root readproc
+ group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index 09db7b0..7ddd52e 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -2,7 +2,7 @@
class main
priority -20
user root
- group root readproc
+ group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
@@ -17,7 +17,7 @@
class main
priority -20
user root
- group root readproc
+ group root readproc reserved_disk
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
diff --git a/trusty/storage/proxy/storage.c b/trusty/storage/proxy/storage.c
index c61e89d..5b83e21 100644
--- a/trusty/storage/proxy/storage.c
+++ b/trusty/storage/proxy/storage.c
@@ -379,7 +379,7 @@
}
if (req->size > MAX_READ_SIZE) {
- ALOGW("%s: request is too large (%zd > %zd) - refusing\n",
+ ALOGW("%s: request is too large (%u > %d) - refusing\n",
__func__, req->size, MAX_READ_SIZE);
msg->result = STORAGE_ERR_NOT_VALID;
goto err_response;