summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bootstat/boot_event_record_store.cpp28
-rw-r--r--bootstat/boot_event_record_store_test.cpp8
-rw-r--r--debuggerd/crash_dump.cpp30
-rw-r--r--debuggerd/tombstoned/tombstoned.cpp2
-rw-r--r--debuggerd/tombstoned/tombstoned.rc2
-rw-r--r--include/cutils/multiuser.h1
-rw-r--r--include/private/android_filesystem_config.h4
-rw-r--r--init/Android.mk2
-rw-r--r--init/init.cpp70
-rw-r--r--init/property_service.cpp3
-rw-r--r--init/seccomp.cpp213
-rw-r--r--init/seccomp.h22
-rw-r--r--libcutils/fs_config.c3
-rw-r--r--libcutils/multiuser.c8
-rw-r--r--libcutils/tests/multiuser_test.cpp8
-rw-r--r--liblog/logger_write.c4
-rw-r--r--logd/tests/logd_test.cpp28
-rw-r--r--rootdir/init.rc8
18 files changed, 355 insertions, 89 deletions
diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp
index 78be9445a..f902af337 100644
--- a/bootstat/boot_event_record_store.cpp
+++ b/bootstat/boot_event_record_store.cpp
@@ -46,24 +46,6 @@ bool ParseRecordEventTime(const std::string& path, int32_t* uptime) {
46 46
47 *uptime = file_stat.st_mtime; 47 *uptime = file_stat.st_mtime;
48 48
49 // The following code (till function exit) is a debug test to ensure the
50 // validity of the file mtime value, i.e., to check that the record file
51 // mtime values are not changed once set.
52 // TODO(jhawkins): Remove this code.
53 std::string content;
54 if (!android::base::ReadFileToString(path, &content)) {
55 PLOG(ERROR) << "Failed to read " << path;
56 return false;
57 }
58
59 // Ignore existing bootstat records (which do not contain file content).
60 if (!content.empty()) {
61 int32_t value;
62 if (android::base::ParseInt(content, &value)) {
63 bootstat::LogHistogram("bootstat_mtime_matches_content", value == *uptime);
64 }
65 }
66
67 return true; 49 return true;
68} 50}
69 51
@@ -89,16 +71,6 @@ void BootEventRecordStore::AddBootEventWithValue(
89 return; 71 return;
90 } 72 }
91 73
92 // Writing the value as content in the record file is a debug measure to
93 // ensure the validity of the file mtime value, i.e., to check that the record
94 // file mtime values are not changed once set.
95 // TODO(jhawkins): Remove this block.
96 if (!android::base::WriteStringToFd(std::to_string(value), record_fd)) {
97 PLOG(ERROR) << "Failed to write value to " << record_path;
98 close(record_fd);
99 return;
100 }
101
102 // Fill out the stat structure for |record_path| in order to get the atime to 74 // Fill out the stat structure for |record_path| in order to get the atime to
103 // set in the utime() call. 75 // set in the utime() call.
104 struct stat file_stat; 76 struct stat file_stat;
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index 01c2cc105..90f6513e4 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -45,14 +45,6 @@ bool CreateEmptyBootEventRecord(const std::string& record_path, int32_t value) {
45 return false; 45 return false;
46 } 46 }
47 47
48 // Writing the value as content in the record file is a debug measure to
49 // ensure the validity of the file mtime value, i.e., to check that the record
50 // file mtime values are not changed once set.
51 // TODO(jhawkins): Remove this block.
52 if (!android::base::WriteStringToFd(std::to_string(value), record_fd)) {
53 return false;
54 }
55
56 // Set the |mtime| of the file to store the value of the boot event while 48 // Set the |mtime| of the file to store the value of the boot event while
57 // preserving the |atime|. 49 // preserving the |atime|.
58 struct timeval atime = {/* tv_sec */ 0, /* tv_usec */ 0}; 50 struct timeval atime = {/* tv_sec */ 0, /* tv_usec */ 0};
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index b9dfedbb6..831150b98 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -57,8 +57,9 @@ static bool pid_contains_tid(pid_t pid, pid_t tid) {
57} 57}
58 58
59// Attach to a thread, and verify that it's still a member of the given process 59// Attach to a thread, and verify that it's still a member of the given process
60static bool ptrace_attach_thread(pid_t pid, pid_t tid) { 60static bool ptrace_attach_thread(pid_t pid, pid_t tid, std::string* error) {
61 if (ptrace(PTRACE_ATTACH, tid, 0, 0) != 0) { 61 if (ptrace(PTRACE_ATTACH, tid, 0, 0) != 0) {
62 *error = StringPrintf("failed to attach to thread %d: %s", tid, strerror(errno));
62 return false; 63 return false;
63 } 64 }
64 65
@@ -67,7 +68,7 @@ static bool ptrace_attach_thread(pid_t pid, pid_t tid) {
67 if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) { 68 if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
68 PLOG(FATAL) << "failed to detach from thread " << tid; 69 PLOG(FATAL) << "failed to detach from thread " << tid;
69 } 70 }
70 errno = ECHILD; 71 *error = StringPrintf("thread %d is not in process %d", tid, pid);
71 return false; 72 return false;
72 } 73 }
73 return true; 74 return true;
@@ -244,9 +245,9 @@ int main(int argc, char** argv) {
244 245
245 check_process(target_proc_fd, target); 246 check_process(target_proc_fd, target);
246 247
247 int attach_error = 0; 248 std::string attach_error;
248 if (!ptrace_attach_thread(target, main_tid)) { 249 if (!ptrace_attach_thread(target, main_tid, &attach_error)) {
249 PLOG(FATAL) << "failed to attach to thread " << main_tid << " in process " << target; 250 LOG(FATAL) << attach_error;
250 } 251 }
251 252
252 check_process(target_proc_fd, target); 253 check_process(target_proc_fd, target);
@@ -268,10 +269,6 @@ int main(int argc, char** argv) {
268 TEMP_FAILURE_RETRY(dup2(devnull.get(), STDOUT_FILENO)); 269 TEMP_FAILURE_RETRY(dup2(devnull.get(), STDOUT_FILENO));
269 } 270 }
270 271
271 if (attach_error != 0) {
272 PLOG(FATAL) << "failed to attach to thread " << main_tid << " in process " << target;
273 }
274
275 LOG(INFO) << "performing dump of process " << target << " (target tid = " << main_tid << ")"; 272 LOG(INFO) << "performing dump of process " << target << " (target tid = " << main_tid << ")";
276 273
277 // At this point, the thread that made the request has been PTRACE_ATTACHed 274 // At this point, the thread that made the request has been PTRACE_ATTACHed
@@ -307,6 +304,7 @@ int main(int argc, char** argv) {
307 bool fatal_signal = signo != DEBUGGER_SIGNAL; 304 bool fatal_signal = signo != DEBUGGER_SIGNAL;
308 int resume_signal = fatal_signal ? signo : 0; 305 int resume_signal = fatal_signal ? signo : 0;
309 std::set<pid_t> siblings; 306 std::set<pid_t> siblings;
307 std::set<pid_t> attached_siblings;
310 if (resume_signal == 0) { 308 if (resume_signal == 0) {
311 if (!android::procinfo::GetProcessTids(target, &siblings)) { 309 if (!android::procinfo::GetProcessTids(target, &siblings)) {
312 PLOG(FATAL) << "failed to get process siblings"; 310 PLOG(FATAL) << "failed to get process siblings";
@@ -314,8 +312,10 @@ int main(int argc, char** argv) {
314 siblings.erase(main_tid); 312 siblings.erase(main_tid);
315 313
316 for (pid_t sibling_tid : siblings) { 314 for (pid_t sibling_tid : siblings) {
317 if (!ptrace_attach_thread(target, sibling_tid)) { 315 if (!ptrace_attach_thread(target, sibling_tid, &attach_error)) {
318 PLOG(FATAL) << "failed to attach to thread " << main_tid << " in process " << target; 316 LOG(WARNING) << attach_error;
317 } else {
318 attached_siblings.insert(sibling_tid);
319 } 319 }
320 } 320 }
321 } 321 }
@@ -328,14 +328,14 @@ int main(int argc, char** argv) {
328 std::string amfd_data; 328 std::string amfd_data;
329 329
330 if (backtrace) { 330 if (backtrace) {
331 dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, siblings, 0); 331 dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, attached_siblings, 0);
332 } else { 332 } else {
333 // Collect the list of open files. 333 // Collect the list of open files.
334 OpenFilesList open_files; 334 OpenFilesList open_files;
335 populate_open_files_list(target, &open_files); 335 populate_open_files_list(target, &open_files);
336 336
337 engrave_tombstone(output_fd.get(), backtrace_map.get(), open_files, target, main_tid, siblings, 337 engrave_tombstone(output_fd.get(), backtrace_map.get(), open_files, target, main_tid,
338 abort_address, fatal_signal ? &amfd_data : nullptr); 338 attached_siblings, abort_address, fatal_signal ? &amfd_data : nullptr);
339 } 339 }
340 340
341 bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false); 341 bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false);
@@ -357,7 +357,7 @@ int main(int argc, char** argv) {
357 } 357 }
358 } 358 }
359 359
360 for (pid_t tid : siblings) { 360 for (pid_t tid : attached_siblings) {
361 // Don't send the signal to sibling threads. 361 // Don't send the signal to sibling threads.
362 if (ptrace(PTRACE_DETACH, tid, 0, wait_for_gdb ? SIGSTOP : 0) != 0) { 362 if (ptrace(PTRACE_DETACH, tid, 0, wait_for_gdb ? SIGSTOP : 0) != 0) {
363 PLOG(ERROR) << "ptrace detach from " << tid << " failed"; 363 PLOG(ERROR) << "ptrace detach from " << tid << " failed";
diff --git a/debuggerd/tombstoned/tombstoned.cpp b/debuggerd/tombstoned/tombstoned.cpp
index 3c1dcaf3c..63e3dbd07 100644
--- a/debuggerd/tombstoned/tombstoned.cpp
+++ b/debuggerd/tombstoned/tombstoned.cpp
@@ -110,7 +110,7 @@ static unique_fd get_tombstone_fd() {
110 } 110 }
111 111
112 result.reset( 112 result.reset(
113 openat(tombstone_directory_fd, buf, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, O_CLOEXEC, 0700)); 113 openat(tombstone_directory_fd, buf, O_CREAT | O_EXCL | O_WRONLY | O_APPEND | O_CLOEXEC, 0700));
114 if (result == -1) { 114 if (result == -1) {
115 PLOG(FATAL) << "failed to create tombstone at " << kTombstoneDirectory << buf; 115 PLOG(FATAL) << "failed to create tombstone at " << kTombstoneDirectory << buf;
116 } 116 }
diff --git a/debuggerd/tombstoned/tombstoned.rc b/debuggerd/tombstoned/tombstoned.rc
index 3aacf332f..eaae9c475 100644
--- a/debuggerd/tombstoned/tombstoned.rc
+++ b/debuggerd/tombstoned/tombstoned.rc
@@ -1,6 +1,4 @@
1service tombstoned /system/bin/tombstoned 1service tombstoned /system/bin/tombstoned
2 class core
3
4 user tombstoned 2 user tombstoned
5 group system 3 group system
6 4
diff --git a/include/cutils/multiuser.h b/include/cutils/multiuser.h
index 4f23776df..5bd9c7b82 100644
--- a/include/cutils/multiuser.h
+++ b/include/cutils/multiuser.h
@@ -32,6 +32,7 @@ extern appid_t multiuser_get_app_id(uid_t uid);
32extern uid_t multiuser_get_uid(userid_t user_id, appid_t app_id); 32extern uid_t multiuser_get_uid(userid_t user_id, appid_t app_id);
33 33
34extern gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id); 34extern gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id);
35extern gid_t multiuser_get_ext_gid(userid_t user_id, appid_t app_id);
35extern gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id); 36extern gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id);
36 37
37/* TODO: switch callers over to multiuser_get_shared_gid() */ 38/* TODO: switch callers over to multiuser_get_shared_gid() */
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 7db28d8f4..8e2bc1cbe 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -127,6 +127,7 @@
127#define AID_MEDIA_VIDEO 1056 /* GID for video files on internal media storage */ 127#define AID_MEDIA_VIDEO 1056 /* GID for video files on internal media storage */
128#define AID_MEDIA_IMAGE 1057 /* GID for image files on internal media storage */ 128#define AID_MEDIA_IMAGE 1057 /* GID for image files on internal media storage */
129#define AID_TOMBSTONED 1058 /* tombstoned user */ 129#define AID_TOMBSTONED 1058 /* tombstoned user */
130#define AID_MEDIA_OBB 1059 /* GID for OBB files on internal media storage */
130/* Changes to this file must be made in AOSP, *not* in internal branches. */ 131/* Changes to this file must be made in AOSP, *not* in internal branches. */
131 132
132#define AID_SHELL 2000 /* adb and debug shell user */ 133#define AID_SHELL 2000 /* adb and debug shell user */
@@ -165,6 +166,9 @@
165#define AID_CACHE_GID_START 20000 /* start of gids for apps to mark cached data */ 166#define AID_CACHE_GID_START 20000 /* start of gids for apps to mark cached data */
166#define AID_CACHE_GID_END 29999 /* end of gids for apps to mark cached data */ 167#define AID_CACHE_GID_END 29999 /* end of gids for apps to mark cached data */
167 168
169#define AID_EXT_GID_START 30000 /* start of gids for apps to mark external data */
170#define AID_EXT_GID_END 39999 /* end of gids for apps to mark external data */
171
168#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */ 172#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
169#define AID_SHARED_GID_END 59999 /* end of gids for apps in each user to share */ 173#define AID_SHARED_GID_END 59999 /* end of gids for apps in each user to share */
170 174
diff --git a/init/Android.mk b/init/Android.mk
index 661569242..35e6f4fb1 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -70,6 +70,7 @@ LOCAL_SRC_FILES:= \
70 init.cpp \ 70 init.cpp \
71 keychords.cpp \ 71 keychords.cpp \
72 property_service.cpp \ 72 property_service.cpp \
73 seccomp.cpp \
73 signal_handler.cpp \ 74 signal_handler.cpp \
74 ueventd.cpp \ 75 ueventd.cpp \
75 ueventd_parser.cpp \ 76 ueventd_parser.cpp \
@@ -96,6 +97,7 @@ LOCAL_STATIC_LIBRARIES := \
96 libbase \ 97 libbase \
97 libc \ 98 libc \
98 libselinux \ 99 libselinux \
100 libseccomp_policy \
99 liblog \ 101 liblog \
100 libcrypto_utils \ 102 libcrypto_utils \
101 libcrypto \ 103 libcrypto \
diff --git a/init/init.cpp b/init/init.cpp
index ee5add898..ddc707faf 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -62,6 +62,7 @@
62#include "keychords.h" 62#include "keychords.h"
63#include "log.h" 63#include "log.h"
64#include "property_service.h" 64#include "property_service.h"
65#include "seccomp.h"
65#include "service.h" 66#include "service.h"
66#include "signal_handler.h" 67#include "signal_handler.h"
67#include "ueventd.h" 68#include "ueventd.h"
@@ -262,26 +263,18 @@ static void security_failure() {
262 panic(); 263 panic();
263} 264}
264 265
265#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits" 266static bool set_highest_available_option_value(std::string path, int min, int max)
266#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits" 267{
267
268/* __attribute__((unused)) due to lack of mips support: see mips block
269 * in set_mmap_rnd_bits_action */
270static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
271 std::string path;
272 if (compat) {
273 path = MMAP_RND_COMPAT_PATH;
274 } else {
275 path = MMAP_RND_PATH;
276 }
277 std::ifstream inf(path, std::fstream::in); 268 std::ifstream inf(path, std::fstream::in);
278 if (!inf) { 269 if (!inf) {
279 LOG(ERROR) << "Cannot open for reading: " << path; 270 LOG(ERROR) << "Cannot open for reading: " << path;
280 return false; 271 return false;
281 } 272 }
282 while (start >= min) { 273
274 int current = max;
275 while (current >= min) {
283 // try to write out new value 276 // try to write out new value
284 std::string str_val = std::to_string(start); 277 std::string str_val = std::to_string(current);
285 std::ofstream of(path, std::fstream::out); 278 std::ofstream of(path, std::fstream::out);
286 if (!of) { 279 if (!of) {
287 LOG(ERROR) << "Cannot open for writing: " << path; 280 LOG(ERROR) << "Cannot open for writing: " << path;
@@ -297,16 +290,33 @@ static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bo
297 if (str_val.compare(str_rec) == 0) { 290 if (str_val.compare(str_rec) == 0) {
298 break; 291 break;
299 } 292 }
300 start--; 293 current--;
301 } 294 }
302 inf.close(); 295 inf.close();
303 if (start < min) { 296
304 LOG(ERROR) << "Unable to set minimum required entropy " << min << " in " << path; 297 if (current < min) {
298 LOG(ERROR) << "Unable to set minimum option value " << min << " in " << path;
305 return false; 299 return false;
306 } 300 }
307 return true; 301 return true;
308} 302}
309 303
304#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
305#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
306
307/* __attribute__((unused)) due to lack of mips support: see mips block
308 * in set_mmap_rnd_bits_action */
309static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
310 std::string path;
311 if (compat) {
312 path = MMAP_RND_COMPAT_PATH;
313 } else {
314 path = MMAP_RND_PATH;
315 }
316
317 return set_highest_available_option_value(path, min, start);
318}
319
310/* 320/*
311 * Set /proc/sys/vm/mmap_rnd_bits and potentially 321 * Set /proc/sys/vm/mmap_rnd_bits and potentially
312 * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values. 322 * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
@@ -359,6 +369,25 @@ static int set_mmap_rnd_bits_action(const std::vector<std::string>& args)
359 return ret; 369 return ret;
360} 370}
361 371
372#define KPTR_RESTRICT_PATH "/proc/sys/kernel/kptr_restrict"
373#define KPTR_RESTRICT_MINVALUE 2
374#define KPTR_RESTRICT_MAXVALUE 4
375
376/* Set kptr_restrict to the highest available level.
377 *
378 * Aborts if unable to set this to an acceptable value.
379 */
380static int set_kptr_restrict_action(const std::vector<std::string>& args)
381{
382 std::string path = KPTR_RESTRICT_PATH;
383
384 if (!set_highest_available_option_value(path, KPTR_RESTRICT_MINVALUE, KPTR_RESTRICT_MAXVALUE)) {
385 LOG(ERROR) << "Unable to set adequate kptr_restrict value!";
386 security_failure();
387 }
388 return 0;
389}
390
362static int keychord_init_action(const std::vector<std::string>& args) 391static int keychord_init_action(const std::vector<std::string>& args)
363{ 392{
364 keychord_init(); 393 keychord_init();
@@ -763,6 +792,12 @@ int main(int argc, char** argv) {
763 792
764 // Now set up SELinux for second stage. 793 // Now set up SELinux for second stage.
765 selinux_initialize(false); 794 selinux_initialize(false);
795
796 // Install system-wide seccomp filter
797 if (!set_seccomp_filter()) {
798 LOG(ERROR) << "Failed to set seccomp policy";
799 security_failure();
800 }
766 } 801 }
767 802
768 // These directories were necessarily created before initial policy load 803 // These directories were necessarily created before initial policy load
@@ -811,6 +846,7 @@ int main(int argc, char** argv) {
811 // ... so that we can start queuing up actions that require stuff from /dev. 846 // ... so that we can start queuing up actions that require stuff from /dev.
812 am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); 847 am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
813 am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits"); 848 am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
849 am.QueueBuiltinAction(set_kptr_restrict_action, "set_kptr_restrict");
814 am.QueueBuiltinAction(keychord_init_action, "keychord_init"); 850 am.QueueBuiltinAction(keychord_init_action, "keychord_init");
815 am.QueueBuiltinAction(console_init_action, "console_init"); 851 am.QueueBuiltinAction(console_init_action, "console_init");
816 852
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 498a5a103..72fcb5b80 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -439,6 +439,8 @@ static void load_persistent_properties() {
439 439
440void property_load_boot_defaults() { 440void property_load_boot_defaults() {
441 load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT, NULL); 441 load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT, NULL);
442 load_properties_from_file(PROP_PATH_ODM_DEFAULT, NULL);
443 load_properties_from_file(PROP_PATH_VENDOR_DEFAULT, NULL);
442} 444}
443 445
444static void load_override_properties() { 446static void load_override_properties() {
@@ -501,6 +503,7 @@ void load_recovery_id_prop() {
501 503
502void load_system_props() { 504void load_system_props() {
503 load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL); 505 load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
506 load_properties_from_file(PROP_PATH_ODM_BUILD, NULL);
504 load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL); 507 load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
505 load_properties_from_file(PROP_PATH_FACTORY, "ro.*"); 508 load_properties_from_file(PROP_PATH_FACTORY, "ro.*");
506 load_recovery_id_prop(); 509 load_recovery_id_prop();
diff --git a/init/seccomp.cpp b/init/seccomp.cpp
new file mode 100644
index 000000000..d9f2f7929
--- /dev/null
+++ b/init/seccomp.cpp
@@ -0,0 +1,213 @@
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "seccomp.h"
18
19#include <vector>
20
21#include <sys/prctl.h>
22
23#include <linux/unistd.h>
24#include <linux/audit.h>
25#include <linux/filter.h>
26#include <linux/seccomp.h>
27
28#include "log.h"
29#include "seccomp_policy.h"
30
31#define syscall_nr (offsetof(struct seccomp_data, nr))
32#define arch_nr (offsetof(struct seccomp_data, arch))
33
34#if defined __arm__
35#define AUDIT_ARCH_NR AUDIT_ARCH_ARM
36#elif defined __aarch64__
37#define AUDIT_ARCH_NR AUDIT_ARCH_AARCH64
38#define AUDIT_ARCH_NR32 AUDIT_ARCH_ARM
39#elif defined __i386__
40#define AUDIT_ARCH_NR AUDIT_ARCH_I386
41#elif defined __x86_64__
42#define AUDIT_ARCH_NR AUDIT_ARCH_X86_64
43#define AUDIT_ARCH_NR32 AUDIT_ARCH_I386
44#elif defined __mips64__
45#define AUDIT_ARCH_NR AUDIT_ARCH_MIPS64
46#define AUDIT_ARCH_NR32 AUDIT_ARCH_MIPS
47#elif defined __mips__ && !defined __mips64__
48#define AUDIT_ARCH_NR AUDIT_ARCH_MIPS
49#else
50#error "Could not determine AUDIT_ARCH_NR for this architecture"
51#endif
52
53typedef std::vector<sock_filter> filter;
54
55// We want to keep the below inline functions for debugging and future
56// development even though they are not used currently.
57#pragma clang diagnostic push
58#pragma clang diagnostic ignored "-Wunused-function"
59
60static inline void Kill(filter& f) {
61 f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL));
62}
63
64static inline void Trap(filter& f) {
65 f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP));
66}
67
68static inline void Error(filter& f, __u16 retcode) {
69 f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO + retcode));
70}
71
72inline static void Trace(filter& f) {
73 f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE));
74}
75
76inline static void Allow(filter& f) {
77 f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
78}
79
80inline static void AllowSyscall(filter& f, __u32 num) {
81 f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, num, 0, 1));
82 f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
83}
84
85inline static void ExamineSyscall(filter& f) {
86 f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
87}
88
89#ifdef AUDIT_ARCH_NR32
90inline static int SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
91 auto jump_length = f.size() - offset - 1;
92 auto u8_jump_length = (__u8) jump_length;
93 if (u8_jump_length != jump_length) {
94 LOG(ERROR) << "Can't set jump greater than 255 - actual jump is " << jump_length;
95 return -1;
96 }
97 f[offset] = BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR32, u8_jump_length, 0);
98 return 0;
99}
100#endif
101
102inline static size_t ValidateArchitectureAndJumpIfNeeded(filter& f) {
103 f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, arch_nr));
104
105#ifdef AUDIT_ARCH_NR32
106 f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR, 2, 0));
107 f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR32, 1, 0));
108 Kill(f);
109 return f.size() - 2;
110#else
111 f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR, 1, 0));
112 Kill(f);
113 return 0;
114#endif
115}
116
117#pragma clang diagnostic pop
118
119static bool install_filter(filter const& f) {
120 struct sock_fprog prog = {
121 (unsigned short) f.size(),
122 (struct sock_filter*) &f[0],
123 };
124
125 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
126 PLOG(ERROR) << "SECCOMP: Could not set seccomp filter";
127 return false;
128 }
129
130 LOG(INFO) << "SECCOMP: Global filter installed";
131 return true;
132}
133
134bool set_seccomp_filter() {
135 filter f;
136
137 // Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
138 // jump that must be changed to point to the start of the 32-bit policy
139 // 32 bit syscalls will not hit the policy between here and the call to SetJump
140#ifdef AUDIT_ARCH_NR32
141 auto offset_to_32bit_filter =
142#endif
143 ValidateArchitectureAndJumpIfNeeded(f);
144
145 // Native filter
146 ExamineSyscall(f);
147
148#ifdef __aarch64__
149 // Syscalls needed to boot Android
150 AllowSyscall(f, __NR_pivot_root);
151 AllowSyscall(f, __NR_ioprio_get);
152 AllowSyscall(f, __NR_ioprio_set);
153 AllowSyscall(f, __NR_gettid);
154 AllowSyscall(f, __NR_futex);
155 AllowSyscall(f, __NR_clone);
156 AllowSyscall(f, __NR_rt_sigreturn);
157 AllowSyscall(f, __NR_rt_tgsigqueueinfo);
158 AllowSyscall(f, __NR_add_key);
159 AllowSyscall(f, __NR_request_key);
160 AllowSyscall(f, __NR_keyctl);
161 AllowSyscall(f, __NR_restart_syscall);
162 AllowSyscall(f, __NR_getrandom);
163
164 // Needed for performance tools
165 AllowSyscall(f, __NR_perf_event_open);
166
167 // Needed for treble
168 AllowSyscall(f, __NR_finit_module);
169
170 // Needed for trusty
171 AllowSyscall(f, __NR_syncfs);
172
173 // arm64-only filter - autogenerated from bionic syscall usage
174 for (size_t i = 0; i < arm64_filter_size; ++i)
175 f.push_back(arm64_filter[i]);
176#else
177 // Generic policy
178 Allow(f);
179#endif
180
181#ifdef AUDIT_ARCH_NR32
182 if (SetValidateArchitectureJumpTarget(offset_to_32bit_filter, f) != 0)
183 return -1;
184
185 // 32-bit filter for 64-bit platforms
186 ExamineSyscall(f);
187
188#ifdef __aarch64__
189 // Syscalls needed to boot android
190 AllowSyscall(f, 120); // __NR_clone
191 AllowSyscall(f, 240); // __NR_futex
192 AllowSyscall(f, 119); // __NR_sigreturn
193 AllowSyscall(f, 173); // __NR_rt_sigreturn
194 AllowSyscall(f, 363); // __NR_rt_tgsigqueueinfo
195 AllowSyscall(f, 224); // __NR_gettid
196
197 // Syscalls needed to run Chrome
198 AllowSyscall(f, 383); // __NR_seccomp - needed to start Chrome
199 AllowSyscall(f, 384); // __NR_getrandom - needed to start Chrome
200
201 // Syscalls needed to run GFXBenchmark
202 AllowSyscall(f, 190); // __NR_vfork
203
204 // arm32-on-arm64 only filter - autogenerated from bionic syscall usage
205 for (size_t i = 0; i < arm_filter_size; ++i)
206 f.push_back(arm_filter[i]);
207#else
208 // Generic policy
209 Allow(f);
210#endif
211#endif
212 return install_filter(f);
213}
diff --git a/init/seccomp.h b/init/seccomp.h
new file mode 100644
index 000000000..cda7a8929
--- /dev/null
+++ b/init/seccomp.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SECCOMP_H
18#define SECCOMP_H
19
20bool set_seccomp_filter();
21
22#endif
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 594b23def..b701bbaae 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -197,7 +197,10 @@ static const struct fs_path_config android_files[] = {
197 { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" }, 197 { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" },
198 { 00600, AID_ROOT, AID_ROOT, 0, "system/build.prop" }, 198 { 00600, AID_ROOT, AID_ROOT, 0, "system/build.prop" },
199 { 00600, AID_ROOT, AID_ROOT, 0, "vendor/build.prop" }, 199 { 00600, AID_ROOT, AID_ROOT, 0, "vendor/build.prop" },
200 { 00600, AID_ROOT, AID_ROOT, 0, "odm/build.prop" },
200 { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, 201 { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" },
202 { 00600, AID_ROOT, AID_ROOT, 0, "vendor/default.prop" },
203 { 00600, AID_ROOT, AID_ROOT, 0, "odm/default.prop" },
201 { 00644, AID_ROOT, AID_ROOT, 0, 0 }, 204 { 00644, AID_ROOT, AID_ROOT, 0, 0 },
202}; 205};
203 206
diff --git a/libcutils/multiuser.c b/libcutils/multiuser.c
index 0ef337d61..08d4d6c2e 100644
--- a/libcutils/multiuser.c
+++ b/libcutils/multiuser.c
@@ -37,6 +37,14 @@ gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id) {
37 } 37 }
38} 38}
39 39
40gid_t multiuser_get_ext_gid(userid_t user_id, appid_t app_id) {
41 if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
42 return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_EXT_GID_START);
43 } else {
44 return -1;
45 }
46}
47
40gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id) { 48gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id) {
41 if (app_id >= AID_APP_START && app_id <= AID_APP_END) { 49 if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
42 return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_SHARED_GID_START); 50 return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_SHARED_GID_START);
diff --git a/libcutils/tests/multiuser_test.cpp b/libcutils/tests/multiuser_test.cpp
index 2307ea8f8..c5f58b450 100644
--- a/libcutils/tests/multiuser_test.cpp
+++ b/libcutils/tests/multiuser_test.cpp
@@ -58,6 +58,14 @@ TEST(MultiuserTest, TestCache) {
58 EXPECT_EQ(1020000, multiuser_get_cache_gid(10, 10000)); 58 EXPECT_EQ(1020000, multiuser_get_cache_gid(10, 10000));
59} 59}
60 60
61TEST(MultiuserTest, TestExt) {
62 EXPECT_EQ(-1, multiuser_get_ext_gid(0, 0));
63 EXPECT_EQ(-1, multiuser_get_ext_gid(0, 1000));
64 EXPECT_EQ(30000, multiuser_get_ext_gid(0, 10000));
65 EXPECT_EQ(-1, multiuser_get_ext_gid(0, 50000));
66 EXPECT_EQ(1030000, multiuser_get_ext_gid(10, 10000));
67}
68
61TEST(MultiuserTest, TestShared) { 69TEST(MultiuserTest, TestShared) {
62 EXPECT_EQ(-1, multiuser_get_shared_gid(0, 0)); 70 EXPECT_EQ(-1, multiuser_get_shared_gid(0, 0));
63 EXPECT_EQ(-1, multiuser_get_shared_gid(0, 1000)); 71 EXPECT_EQ(-1, multiuser_get_shared_gid(0, 1000));
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index f19c3ab27..1a2d50612 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -262,6 +262,8 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
262 } 262 }
263 263
264#if defined(__ANDROID__) 264#if defined(__ANDROID__)
265 clock_gettime(android_log_clockid(), &ts);
266
265 if (log_id == LOG_ID_SECURITY) { 267 if (log_id == LOG_ID_SECURITY) {
266 if (vec[0].iov_len < 4) { 268 if (vec[0].iov_len < 4) {
267 return -EINVAL; 269 return -EINVAL;
@@ -351,8 +353,6 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
351 return -EPERM; 353 return -EPERM;
352 } 354 }
353 } 355 }
354
355 clock_gettime(android_log_clockid(), &ts);
356#else 356#else
357 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */ 357 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
358 { 358 {
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 703c0fb9d..13a792286 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -196,7 +196,9 @@ TEST(logd, statistics) {
196 EXPECT_TRUE(NULL != main_logs); 196 EXPECT_TRUE(NULL != main_logs);
197 197
198 char *radio_logs = strstr(cp, "\nChattiest UIDs in radio "); 198 char *radio_logs = strstr(cp, "\nChattiest UIDs in radio ");
199 EXPECT_TRUE(NULL != radio_logs); 199 if (!radio_logs) GTEST_LOG_(INFO) << "Value of: NULL != radio_logs\n"
200 "Actual: false\n"
201 "Expected: false\n";
200 202
201 char *system_logs = strstr(cp, "\nChattiest UIDs in system "); 203 char *system_logs = strstr(cp, "\nChattiest UIDs in system ");
202 EXPECT_TRUE(NULL != system_logs); 204 EXPECT_TRUE(NULL != system_logs);
@@ -942,8 +944,16 @@ static pid_t sepolicy_rate(unsigned rate, unsigned num) {
942 return 0; 944 return 0;
943 } 945 }
944 946
945 // Requests dac_read_search, falls back to request dac_override 947 // The key here is we are root, but we are in u:r:shell:s0,
946 rate /= 2; 948 // and the directory does not provide us DAC access
949 // (eg: 0700 system system) so we trigger the pair dac_override
950 // and dac_read_search on every try to get past the message
951 // de-duper. We will also rotate the file name in the directory
952 // as another measure.
953 static const char file[] = "/data/backup/cannot_access_directory_%u";
954 static const unsigned avc_requests_per_access = 2;
955
956 rate /= avc_requests_per_access;
947 useconds_t usec; 957 useconds_t usec;
948 if (rate == 0) { 958 if (rate == 0) {
949 rate = 1; 959 rate = 1;
@@ -951,15 +961,12 @@ static pid_t sepolicy_rate(unsigned rate, unsigned num) {
951 } else { 961 } else {
952 usec = (1000000 + (rate / 2)) / rate; 962 usec = (1000000 + (rate / 2)) / rate;
953 } 963 }
954 num = (num + 1) / 2; 964 num = (num + (avc_requests_per_access / 2)) / avc_requests_per_access;
955 965
956 if (usec < 2) usec = 2; 966 if (usec < 2) usec = 2;
957 967
958 while (num > 0) { 968 while (num > 0) {
959 if (access(android::base::StringPrintf( 969 if (access(android::base::StringPrintf(file, num).c_str(), F_OK) == 0) {
960 "/data/misc/logd/cannot_access_directory_%u",
961 num).c_str(),
962 F_OK) == 0) {
963 _exit(-1); 970 _exit(-1);
964 // NOTREACHED 971 // NOTREACHED
965 return 0; 972 return 0;
@@ -1002,7 +1009,7 @@ static int count_avc(pid_t pid) {
1002 1009
1003 // int len = get4LE(eventData + 4 + 1); 1010 // int len = get4LE(eventData + 4 + 1);
1004 log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0'; 1011 log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0';
1005 const char *cp = strstr(eventData + 4 + 1 + 4, "): avc: "); 1012 const char *cp = strstr(eventData + 4 + 1 + 4, "): avc: denied");
1006 if (!cp) continue; 1013 if (!cp) continue;
1007 1014
1008 ++count; 1015 ++count;
@@ -1055,8 +1062,7 @@ TEST(logd, sepolicy_rate_limiter_spam) {
1055 // give logd another 3 seconds to react to the burst before checking 1062 // give logd another 3 seconds to react to the burst before checking
1056 sepolicy_rate(rate, rate * 3); 1063 sepolicy_rate(rate, rate * 3);
1057 // maximum period at double the maximum burst rate (spam filter kicked in) 1064 // maximum period at double the maximum burst rate (spam filter kicked in)
1058 EXPECT_GE(((AUDIT_RATE_LIMIT_MAX * AUDIT_RATE_LIMIT_BURST_DURATION) * 130) / 1065 EXPECT_GE(threshold * 2,
1059 100, // +30% margin
1060 count_avc(sepolicy_rate(rate, 1066 count_avc(sepolicy_rate(rate,
1061 rate * AUDIT_RATE_LIMIT_BURST_DURATION))); 1067 rate * AUDIT_RATE_LIMIT_BURST_DURATION)));
1062 // cool down, and check unspammy rate still works 1068 // cool down, and check unspammy rate still works
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 791d67ffd..8d974fa12 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -118,7 +118,6 @@ on init
118 write /proc/sys/kernel/sched_child_runs_first 0 118 write /proc/sys/kernel/sched_child_runs_first 0
119 119
120 write /proc/sys/kernel/randomize_va_space 2 120 write /proc/sys/kernel/randomize_va_space 2
121 write /proc/sys/kernel/kptr_restrict 2
122 write /proc/sys/vm/mmap_min_addr 32768 121 write /proc/sys/vm/mmap_min_addr 32768
123 write /proc/sys/net/ipv4/ping_group_range "0 2147483647" 122 write /proc/sys/net/ipv4/ping_group_range "0 2147483647"
124 write /proc/sys/net/unix/max_dgram_qlen 600 123 write /proc/sys/net/unix/max_dgram_qlen 600
@@ -356,14 +355,13 @@ on post-fs-data
356 # We restorecon /data in case the userdata partition has been reset. 355 # We restorecon /data in case the userdata partition has been reset.
357 restorecon /data 356 restorecon /data
358 357
359 # start debuggerd to make debugging early-boot crashes easier.
360 start debuggerd
361 start debuggerd64
362
363 # Make sure we have the device encryption key. 358 # Make sure we have the device encryption key.
364 start vold 359 start vold
365 installkey /data 360 installkey /data
366 361
362 # start tombstoned to record early-boot crashes.
363 start tombstoned
364
367 # Start bootcharting as soon as possible after the data partition is 365 # Start bootcharting as soon as possible after the data partition is
368 # mounted to collect more data. 366 # mounted to collect more data.
369 mkdir /data/bootchart 0755 shell shell 367 mkdir /data/bootchart 0755 shell shell