Merge "cutils: Add clang FORTIFY support"
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index e7f1a07..a4a0b52 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1303,6 +1303,36 @@
return num;
}
+static std::string fb_fix_numeric_var(std::string var) {
+ // Some bootloaders (angler, for example), send spurious leading whitespace.
+ var = android::base::Trim(var);
+ // Some bootloaders (hammerhead, for example) use implicit hex.
+ // This code used to use strtol with base 16.
+ if (!android::base::StartsWith(var, "0x")) var = "0x" + var;
+ return var;
+}
+
+static unsigned fb_get_flash_block_size(Transport* transport, std::string name) {
+ std::string sizeString;
+ if (!fb_getvar(transport, name.c_str(), &sizeString)) {
+ /* This device does not report flash block sizes, so return 0 */
+ return 0;
+ }
+ sizeString = fb_fix_numeric_var(sizeString);
+
+ unsigned size;
+ if (!android::base::ParseUint(sizeString, &size)) {
+ fprintf(stderr, "Couldn't parse %s '%s'.\n", name.c_str(), sizeString.c_str());
+ return 0;
+ }
+ if (size < 4096 || (size & (size - 1)) != 0) {
+ fprintf(stderr, "Invalid %s %u: must be a power of 2 and at least 4096.\n",
+ name.c_str(), size);
+ return 0;
+ }
+ return size;
+}
+
static void fb_perform_format(Transport* transport,
const char* partition, int skip_if_not_supported,
const char* type_override, const char* size_override,
@@ -1345,11 +1375,7 @@
}
partition_size = size_override;
}
- // Some bootloaders (angler, for example), send spurious leading whitespace.
- partition_size = android::base::Trim(partition_size);
- // Some bootloaders (hammerhead, for example) use implicit hex.
- // This code used to use strtol with base 16.
- if (!android::base::StartsWith(partition_size, "0x")) partition_size = "0x" + partition_size;
+ partition_size = fb_fix_numeric_var(partition_size);
gen = fs_get_generator(partition_type);
if (!gen) {
@@ -1370,7 +1396,12 @@
}
fd = fileno(tmpfile());
- if (fs_generator_generate(gen, fd, size, initial_dir)) {
+
+ unsigned eraseBlkSize, logicalBlkSize;
+ eraseBlkSize = fb_get_flash_block_size(transport, "erase-block-size");
+ logicalBlkSize = fb_get_flash_block_size(transport, "logical-block-size");
+
+ if (fs_generator_generate(gen, fd, size, initial_dir, eraseBlkSize, logicalBlkSize)) {
fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
close(fd);
return;
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index 9b73165..5d9ccfe 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -14,18 +14,21 @@
#include <ext4_utils/make_ext4fs.h>
#include <sparse/sparse.h>
-static int generate_ext4_image(int fd, long long partSize, const std::string& initial_dir)
+static int generate_ext4_image(int fd, long long partSize, const std::string& initial_dir,
+ unsigned eraseBlkSize, unsigned logicalBlkSize)
{
if (initial_dir.empty()) {
- make_ext4fs_sparse_fd(fd, partSize, NULL, NULL);
+ make_ext4fs_sparse_fd_align(fd, partSize, NULL, NULL, eraseBlkSize, logicalBlkSize);
} else {
- make_ext4fs_sparse_fd_directory(fd, partSize, NULL, NULL, initial_dir.c_str());
+ make_ext4fs_sparse_fd_directory_align(fd, partSize, NULL, NULL, initial_dir.c_str(),
+ eraseBlkSize, logicalBlkSize);
}
return 0;
}
#ifdef USE_F2FS
-static int generate_f2fs_image(int fd, long long partSize, const std::string& initial_dir)
+static int generate_f2fs_image(int fd, long long partSize, const std::string& initial_dir,
+ unsigned /* unused */, unsigned /* unused */)
{
if (!initial_dir.empty()) {
fprintf(stderr, "Unable to set initial directory on F2FS filesystem\n");
@@ -39,7 +42,8 @@
const char* fs_type; //must match what fastboot reports for partition type
//returns 0 or error value
- int (*generate)(int fd, long long partSize, const std::string& initial_dir);
+ int (*generate)(int fd, long long partSize, const std::string& initial_dir,
+ unsigned eraseBlkSize, unsigned logicalBlkSize);
} generators[] = {
{ "ext4", generate_ext4_image},
@@ -58,7 +62,7 @@
}
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize,
- const std::string& initial_dir)
+ const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize)
{
- return gen->generate(tmpFileNo, partSize, initial_dir);
+ return gen->generate(tmpFileNo, partSize, initial_dir, eraseBlkSize, logicalBlkSize);
}
diff --git a/fastboot/fs.h b/fastboot/fs.h
index 0a68507..0a5f5a4 100644
--- a/fastboot/fs.h
+++ b/fastboot/fs.h
@@ -8,6 +8,6 @@
const struct fs_generator* fs_get_generator(const std::string& fs_type);
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize,
- const std::string& initial_dir);
+ const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0);
#endif
diff --git a/init/.clang-format b/init/.clang-format
new file mode 100644
index 0000000..48d423f
--- /dev/null
+++ b/init/.clang-format
@@ -0,0 +1,14 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+BinPackArguments: true
+BinPackParameters: true
+ColumnLimit: 100
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+IndentWidth: 4
+Standard: Auto
+TabWidth: 8
+UseTab: Never
+DerivePointerAlignment: false
+PointerAlignment: Left
+...
diff --git a/init/Android.mk b/init/Android.mk
index 9e61fb2..a10a714 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -134,3 +134,8 @@
LOCAL_CLANG := true
LOCAL_CPPFLAGS := -Wall -Wextra -Werror
include $(BUILD_NATIVE_TEST)
+
+
+# Include targets in subdirs.
+# =========================================================
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/init/test_service/Android.mk b/init/test_service/Android.mk
new file mode 100644
index 0000000..30c9e9d
--- /dev/null
+++ b/init/test_service/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2016 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Sample service for testing.
+# =========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := test_service
+LOCAL_SRC_FILES := test_service.cpp
+
+LOCAL_SHARED_LIBRARIES += libbase
+
+LOCAL_INIT_RC := test_service.rc
+
+include $(BUILD_EXECUTABLE)
diff --git a/init/test_service/README.md b/init/test_service/README.md
new file mode 100644
index 0000000..6773235
--- /dev/null
+++ b/init/test_service/README.md
@@ -0,0 +1,43 @@
+# Sample service for testing
+This is a sample service that can be used for testing init.
+
+## Design
+The service includes a `.rc` file that allows starting it from init.
+
+ service test_service /system/bin/test_service CapAmb 0000000000003000
+ class main
+ user system
+ group system
+ capabilities NET_ADMIN NET_RAW
+ disabled
+ oneshot
+
+The service accepts any even number of arguments on the command line
+(i.e. any number of pairs of arguments.)
+It will attempt to find the first element of each pair of arguments in
+`/proc/self/status`, and attempt to exactly match the second element of the pair
+to the relevant line of `proc/self/status`.
+
+### Example
+In the above case, the service will look for lines containing `CapAmb`:
+
+ cat /proc/self/status
+ ...
+ CapAmb: 0000000000003000
+
+And then attempt to exactly match the token after `:`, `0000000000003000`,
+with the command-line argument.
+If they match, the service exits successfully. If not, the service will exit
+with an error.
+
+## Usage
+ mmma -j <jobs> system/core/init/testservice
+ adb root
+ adb remount
+ adb sync
+ adb reboot
+ adb root
+ adb shell start test_service
+ adb logcat -b all -d | grep test_service
+
+Look for an exit status of 0.
diff --git a/init/test_service/test_service.cpp b/init/test_service/test_service.cpp
new file mode 100644
index 0000000..e7206f8
--- /dev/null
+++ b/init/test_service/test_service.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2016 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.
+
+#include <unistd.h>
+
+#include <map>
+#include <sstream>
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+
+void Usage(char* argv[]) {
+ printf("Usage: %s <status field> <value> [<status field> <value>]*\n", argv[0]);
+ printf("E.g.: $ %s Uid \"1000 1000 1000 1000\"\n", argv[0]);
+}
+
+int main(int argc, char* argv[]) {
+ if (argc < 3) {
+ Usage(argv);
+ LOG(FATAL) << "no status field requested";
+ }
+ if (argc % 2 == 0) {
+ // Since |argc| counts argv[0], if |argc| is odd, then the number of
+ // command-line arguments is even.
+ Usage(argv);
+ LOG(FATAL) << "need even number of command-line arguments";
+ }
+
+ std::string status;
+ bool res = android::base::ReadFileToString("/proc/self/status", &status, true);
+ if (!res) {
+ PLOG(FATAL) << "could not read /proc/self/status";
+ }
+
+ std::map<std::string, std::string> fields;
+ std::vector<std::string> lines = android::base::Split(status, "\n");
+ for (const auto& line : lines) {
+ std::vector<std::string> tokens = android::base::Split(line, ":");
+ if (tokens.size() >= 2) {
+ std::string field = tokens[0];
+ std::string value = android::base::Trim(tokens[1]);
+ if (field.length() > 0) {
+ fields[field] = value;
+ }
+ }
+ }
+
+ bool test_fails = false;
+ size_t uargc = static_cast<size_t>(argc); // |argc| >= 3.
+ for (size_t i = 1; i < static_cast<size_t>(argc); i = i + 2) {
+ std::string expected_value = argv[i + 1];
+ auto f = fields.find(argv[i]);
+ if (f != fields.end()) {
+ if (f->second != expected_value) {
+ LOG(ERROR) << "field '" << argv[i] << "' expected '" << expected_value
+ << "', actual '" << f->second << "'";
+ test_fails = true;
+ }
+ } else {
+ LOG(WARNING) << "could not find field '" << argv[i] << "'";
+ }
+ }
+
+ return test_fails ? 1 : 0;
+}
diff --git a/init/test_service/test_service.rc b/init/test_service/test_service.rc
new file mode 100644
index 0000000..91e1a0f
--- /dev/null
+++ b/init/test_service/test_service.rc
@@ -0,0 +1,7 @@
+service test_service /system/bin/test_service CapAmb 0000000000003000
+ class main
+ user system
+ group system
+ capabilities NET_ADMIN NET_RAW
+ disabled
+ oneshot
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 361b925..915afbd 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -60,9 +60,18 @@
cb.func_log = selinux_klog_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
- std::string hardware = property_get("ro.hardware");
-
ueventd_parse_config_file("/ueventd.rc");
+ ueventd_parse_config_file("/vendor/ueventd.rc");
+ ueventd_parse_config_file("/odm/ueventd.rc");
+
+ /*
+ * keep the current product name base configuration so
+ * we remain backwards compatible and allow it to override
+ * everything
+ * TODO: cleanup platform ueventd.rc to remove vendor specific
+ * device node entries (b/34968103)
+ */
+ std::string hardware = property_get("ro.hardware");
ueventd_parse_config_file(android::base::StringPrintf("/ueventd.%s.rc", hardware.c_str()).c_str());
device_init();
diff --git a/libappfuse/tests/FuseBufferTest.cc b/libappfuse/tests/FuseBufferTest.cc
index db35d33..1a1abd5 100644
--- a/libappfuse/tests/FuseBufferTest.cc
+++ b/libappfuse/tests/FuseBufferTest.cc
@@ -31,7 +31,7 @@
constexpr char kTempFile[] = "/data/local/tmp/appfuse_test_dump";
void OpenTempFile(android::base::unique_fd* fd) {
- fd->reset(open(kTempFile, O_CREAT | O_RDWR));
+ fd->reset(open(kTempFile, O_CREAT | O_RDWR, 0600));
ASSERT_NE(-1, *fd) << strerror(errno);
unlink(kTempFile);
ASSERT_NE(-1, *fd) << strerror(errno);
diff --git a/liblog/logd_reader.c b/liblog/logd_reader.c
index ccc7da8..9411f36 100644
--- a/liblog/logd_reader.c
+++ b/liblog/logd_reader.c
@@ -91,7 +91,7 @@
static int logdAvailable(log_id_t logId)
{
- if (logId > LOG_ID_KERNEL) {
+ if (logId >= LOG_ID_MAX || logId == LOG_ID_KERNEL) {
return -EINVAL;
}
if (logId == LOG_ID_SECURITY) {
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 0633a68..3b64f6d 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -46,7 +46,7 @@
/dev/tty0 0660 root system
/dev/graphics/* 0660 root graphics
/dev/msm_hw3dm 0660 system graphics
-/dev/input/* 0660 root input
+/dev/input/* 0640 system input
/dev/eac 0660 root audio
/dev/cam 0660 root camera
/dev/pmem 0660 system graphics
diff --git a/toolbox/getevent.c b/toolbox/getevent.c
index e6def6b..1fb315c 100644
--- a/toolbox/getevent.c
+++ b/toolbox/getevent.c
@@ -321,7 +321,7 @@
char idstr[80];
struct input_id id;
- fd = open(device, O_RDWR);
+ fd = open(device, O_RDONLY);
if(fd < 0) {
if(print_flags & PRINT_DEVICE_ERRORS)
fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));