diff options
| -rw-r--r-- | adb/Android.mk | 5 | ||||
| -rw-r--r-- | adb/adb.c | 31 | ||||
| -rw-r--r-- | include/cutils/aref.h | 62 | ||||
| -rw-r--r-- | include/cutils/bitops.h | 69 | ||||
| -rw-r--r-- | init/devices.c | 4 | ||||
| -rw-r--r-- | libnetutils/dhcp_utils.c | 2 | ||||
| -rw-r--r-- | logwrapper/logwrapper.c | 24 | ||||
| -rw-r--r-- | rootdir/init.rc | 6 |
8 files changed, 194 insertions, 9 deletions
diff --git a/adb/Android.mk b/adb/Android.mk index d6b0146..a803978 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -16,7 +16,8 @@ EXTRA_SRCS := ifeq ($(HOST_OS),linux) USB_SRCS := usb_linux.c EXTRA_SRCS := get_my_path_linux.c - LOCAL_LDLIBS += -lrt -lncurses -lpthread + LOCAL_LDLIBS += -lrt -ldl -lpthread + LOCAL_CFLAGS += -DWORKAROUND_BUG6558362 endif ifeq ($(HOST_OS),darwin) @@ -140,7 +141,7 @@ include $(BUILD_EXECUTABLE) ifneq ($(SDK_ONLY),true) include $(CLEAR_VARS) -LOCAL_LDLIBS := -lrt -lncurses -lpthread +LOCAL_LDLIBS := -lrt -ldl -lpthread LOCAL_SRC_FILES := \ adb.c \ @@ -983,6 +983,33 @@ void start_device_log(void) #endif #if ADB_HOST + +#ifdef WORKAROUND_BUG6558362 +#include <sched.h> +#define AFFINITY_ENVVAR "ADB_CPU_AFFINITY_BUG6558362" +void adb_set_affinity(void) +{ + cpu_set_t cpu_set; + const char* cpunum_str = getenv(AFFINITY_ENVVAR); + char* strtol_res; + int cpu_num; + + if (!cpunum_str || !*cpunum_str) + return; + cpu_num = strtol(cpunum_str, &strtol_res, 0); + if (*strtol_res != '\0') + fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, AFFINITY_ENVVAR); + + sched_getaffinity(0, sizeof(cpu_set), &cpu_set); + D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); + CPU_ZERO(&cpu_set); + CPU_SET(cpu_num, &cpu_set); + sched_setaffinity(0, sizeof(cpu_set), &cpu_set); + sched_getaffinity(0, sizeof(cpu_set), &cpu_set); + D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); +} +#endif + int launch_server(int server_port) { #ifdef HAVE_WIN32_PROC @@ -1186,6 +1213,10 @@ int adb_main(int is_daemon, int server_port) #if ADB_HOST HOST = 1; + +#ifdef WORKAROUND_BUG6558362 + if(is_daemon) adb_set_affinity(); +#endif usb_vendors_init(); usb_init(); local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); diff --git a/include/cutils/aref.h b/include/cutils/aref.h new file mode 100644 index 0000000..460ac02 --- /dev/null +++ b/include/cutils/aref.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2013 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 _CUTILS_AREF_H_ +#define _CUTILS_AREF_H_ + +#include <stddef.h> +#include <sys/cdefs.h> + +#ifdef ANDROID_SMP +#include <cutils/atomic-inline.h> +#else +#include <cutils/atomic.h> +#endif + +__BEGIN_DECLS + +#define AREF_TO_ITEM(aref, container, member) \ + (container *) (((char*) (aref)) - offsetof(container, member)) + +struct aref +{ + volatile int32_t count; +}; + +static inline void aref_init(struct aref *r) +{ + r->count = 1; +} + +static inline int32_t aref_count(struct aref *r) +{ + return r->count; +} + +static inline void aref_get(struct aref *r) +{ + android_atomic_inc(&r->count); +} + +static inline void aref_put(struct aref *r, void (*release)(struct aref *)) +{ + if (android_atomic_dec(&r->count) == 1) + release(r); +} + +__END_DECLS + +#endif // _CUTILS_AREF_H_ diff --git a/include/cutils/bitops.h b/include/cutils/bitops.h index 1b3b762..eb44236 100644 --- a/include/cutils/bitops.h +++ b/include/cutils/bitops.h @@ -17,10 +17,79 @@ #ifndef __CUTILS_BITOPS_H #define __CUTILS_BITOPS_H +#include <stdbool.h> +#include <string.h> +#include <strings.h> #include <sys/cdefs.h> __BEGIN_DECLS +/* + * Bitmask Operations + * + * Note this doesn't provide any locking/exclusion, and isn't atomic. + * Additionally no bounds checking is done on the bitmask array. + * + * Example: + * + * int num_resources; + * unsigned int resource_bits[BITS_TO_WORDS(num_resources)]; + * bitmask_init(resource_bits, num_resources); + * ... + * int bit = bitmask_ffz(resource_bits, num_resources); + * bitmask_set(resource_bits, bit); + * ... + * if (bitmask_test(resource_bits, bit)) { ... } + * ... + * bitmask_clear(resource_bits, bit); + * + */ + +#define BITS_PER_WORD (sizeof(unsigned int) * 8) +#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD) +#define BIT_IN_WORD(x) ((x) % BITS_PER_WORD) +#define BIT_WORD(x) ((x) / BITS_PER_WORD) +#define BIT_MASK(x) (1 << BIT_IN_WORD(x)) + +static inline void bitmask_init(unsigned int *bitmask, int num_bits) +{ + memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int)); +} + +static inline int bitmask_ffz(unsigned int *bitmask, int num_bits) +{ + int bit, result; + unsigned int i; + + for (i = 0; i < BITS_TO_WORDS(num_bits); i++) { + bit = ffs(~bitmask[i]); + if (bit) { + // ffs is 1-indexed, return 0-indexed result + bit--; + result = BITS_PER_WORD * i + bit; + if (result >= num_bits) + return -1; + return result; + } + } + return -1; +} + +static inline void bitmask_set(unsigned int *bitmask, int bit) +{ + bitmask[BIT_WORD(bit)] |= BIT_MASK(bit); +} + +static inline void bitmask_clear(unsigned int *bitmask, int bit) +{ + bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit); +} + +static inline bool bitmask_test(unsigned int *bitmask, int bit) +{ + return bitmask[BIT_WORD(bit)] & BIT_MASK(bit); +} + static inline int popcount(unsigned int x) { return __builtin_popcount(x); diff --git a/init/devices.c b/init/devices.c index dd875d6..b07a1a6 100644 --- a/init/devices.c +++ b/init/devices.c @@ -881,8 +881,8 @@ void device_init(void) sehandle = selinux_android_file_context_handle(); } - /* is 64K enough? udev uses 16MB! */ - device_fd = uevent_open_socket(64*1024, true); + /* is 256K enough? udev uses 16MB! */ + device_fd = uevent_open_socket(256*1024, true); if(device_fd < 0) return; diff --git a/libnetutils/dhcp_utils.c b/libnetutils/dhcp_utils.c index 2f5fdd3..bd48eff 100644 --- a/libnetutils/dhcp_utils.c +++ b/libnetutils/dhcp_utils.c @@ -216,7 +216,7 @@ int dhcp_do_request(const char *interface, p2p_interface, DHCP_CONFIG_PATH, prop_value, interface); else snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-f %s %s", DAEMON_NAME, - DHCP_CONFIG_PATH, p2p_interface, interface); + p2p_interface, DHCP_CONFIG_PATH, interface); memset(prop_value, '\0', PROPERTY_VALUE_MAX); property_set(ctrl_prop, daemon_cmd); if (wait_for_property(daemon_prop_name, desired_status, 10) < 0) { diff --git a/logwrapper/logwrapper.c b/logwrapper/logwrapper.c index 3b876d4..dd777c0 100644 --- a/logwrapper/logwrapper.c +++ b/logwrapper/logwrapper.c @@ -35,14 +35,17 @@ void fatal(const char *msg) { void usage() { fatal( - "Usage: logwrapper BINARY [ARGS ...]\n" + "Usage: logwrapper [-d] BINARY [ARGS ...]\n" "\n" "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n" "the Android logging system. Tag is set to BINARY, priority is\n" - "always LOG_INFO.\n"); + "always LOG_INFO.\n" + "\n" + "-d: Causes logwrapper to SIGSEGV when BINARY terminates\n" + " fault address is set to the status of wait()\n"); } -void parent(const char *tag, int parent_read) { +void parent(const char *tag, int seg_fault_on_exit, int parent_read) { int status; char buffer[4096]; @@ -102,6 +105,8 @@ void parent(const char *tag, int parent_read) { } else ALOG(LOG_INFO, "logwrapper", "%s wait() failed: %s (%d)", tag, strerror(errno), errno); + if (seg_fault_on_exit) + *(int *)status = 0; // causes SIGSEGV with fault_address = status } void child(int argc, char* argv[]) { @@ -119,6 +124,7 @@ void child(int argc, char* argv[]) { int main(int argc, char* argv[]) { pid_t pid; + int seg_fault_on_exit = 0; int parent_ptty; int child_ptty; @@ -128,6 +134,16 @@ int main(int argc, char* argv[]) { usage(); } + if (strncmp(argv[1], "-d", 2) == 0) { + seg_fault_on_exit = 1; + argc--; + argv++; + } + + if (argc < 2) { + usage(); + } + /* Use ptty instead of socketpair so that STDOUT is not buffered */ parent_ptty = open("/dev/ptmx", O_RDWR); if (parent_ptty < 0) { @@ -163,7 +179,7 @@ int main(int argc, char* argv[]) { setgid(AID_LOG); setuid(AID_LOG); - parent(argv[1], parent_ptty); + parent(argv[1], seg_fault_on_exit, parent_ptty); } return 0; diff --git a/rootdir/init.rc b/rootdir/init.rc index d4baab4..bee0729 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -120,6 +120,12 @@ loglevel 3 write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_runtime_us 700000 write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_period_us 1000000 +# qtaguid will limit access to specific data based on group memberships. +# net_bw_acct grants impersonation of socket owners. +# net_bw_stats grants access to other apps' detailed tagged-socket stats. + chown root net_bw_acct /proc/net/xt_qtaguid/ctrl + chown root net_bw_stats /proc/net/xt_qtaguid/stats + # Allow everybody to read the xt_qtaguid resource tracking misc dev. # This is needed by any process that uses socket tagging. chmod 0644 /dev/xt_qtaguid |
