Merge "Revert "add IP checking for adb over TCP""
diff --git a/adb/Android.mk b/adb/Android.mk
index 248208a..1a25106 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -95,16 +95,6 @@
# adbd device daemon
# =========================================================
-BUILD_ADBD := true
-
-# build adbd for the Linux simulator build
-# so we can use it to test the adb USB gadget driver on x86
-#ifeq ($(HOST_OS),linux)
-# BUILD_ADBD := true
-#endif
-
-
-ifeq ($(BUILD_ADBD),true)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
@@ -127,12 +117,6 @@
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-# TODO: This should probably be board specific, whether or not the kernel has
-# the gadget driver; rather than relying on the architecture type.
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_CFLAGS += -DANDROID_GADGET=1
-endif
-
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endif
@@ -146,8 +130,6 @@
LOCAL_STATIC_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
-endif
-
# adb host tool for device-as-host
# =========================================================
diff --git a/adb/adb.h b/adb/adb.h
index 85922bf..03a7393 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -86,6 +86,11 @@
*/
int closing;
+ /* flag: quit adbd when both ends close the
+ ** local service socket
+ */
+ int exit_on_close;
+
/* the asocket we are connected to
*/
diff --git a/adb/commandline.c b/adb/commandline.c
index 5b2aa88..7af8163 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -1575,7 +1575,7 @@
err = do_sync_push(apk_file, apk_dest, 1 /* verify APK */);
if (err) {
- return err;
+ goto cleanup_apk;
} else {
argv[file_arg] = apk_dest; /* destination name, not source location */
}
@@ -1591,11 +1591,11 @@
pm_command(transport, serial, argc, argv);
+cleanup_apk:
if (verification_file != NULL) {
delete_file(transport, serial, verification_dest);
}
-cleanup_apk:
delete_file(transport, serial, apk_dest);
return err;
diff --git a/adb/services.c b/adb/services.c
index 6940be8..495a083 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -125,12 +125,10 @@
return;
}
+ property_set("service.adb.root", "1");
snprintf(buf, sizeof(buf), "restarting adbd as root\n");
writex(fd, buf, strlen(buf));
adb_close(fd);
-
- // This will cause a property trigger in init.rc to restart us
- property_set("service.adb.root", "1");
}
}
@@ -152,10 +150,6 @@
snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
writex(fd, buf, strlen(buf));
adb_close(fd);
-
- // quit, and init will restart us in TCP mode
- sleep(1);
- exit(1);
}
void restart_usb_service(int fd, void *cookie)
@@ -166,10 +160,6 @@
snprintf(buf, sizeof(buf), "restarting in USB mode\n");
writex(fd, buf, strlen(buf));
adb_close(fd);
-
- // quit, and init will restart us in USB mode
- sleep(1);
- exit(1);
}
void reboot_service(int fd, void *arg)
@@ -369,7 +359,6 @@
break;
}
}
- usleep(100000); // poll every 0.1 sec
}
D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno);
if (SHELL_EXIT_NOTIFY_FD >=0) {
diff --git a/adb/sockets.c b/adb/sockets.c
index df223b1..ce3c65e 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -199,6 +199,8 @@
static void local_socket_destroy(asocket *s)
{
apacket *p, *n;
+ int exit_on_close = s->exit_on_close;
+
D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd);
/* IMPORTANT: the remove closes the fd
@@ -214,6 +216,11 @@
}
remove_socket(s);
free(s);
+
+ if (exit_on_close) {
+ D("local_socket_destroy: exiting\n");
+ exit(1);
+ }
}
@@ -418,6 +425,13 @@
s = create_local_socket(fd);
D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
+
+ if (!strcmp(name, "root:") || !strcmp(name, "usb:") ||
+ !strcmp(name, "tcpip:")) {
+ D("LS(%d): enabling exit_on_close\n", s->id);
+ s->exit_on_close = 1;
+ }
+
return s;
}
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 5d8a831..a477e4e 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -117,8 +117,6 @@
#define VENDOR_ID_FUJITSU 0x04C5
// Lumigon's USB Vendor ID
#define VENDOR_ID_LUMIGON 0x25E3
-//Intel's USB Vendor ID
-#define VENDOR_ID_INTEL 0x8087
// Quanta's USB Vendor ID
#define VENDOR_ID_QUANTA 0x0408
// INQ Mobile's USB Vendor ID
@@ -169,7 +167,6 @@
VENDOR_ID_POSITIVO,
VENDOR_ID_FUJITSU,
VENDOR_ID_LUMIGON,
- VENDOR_ID_INTEL,
VENDOR_ID_QUANTA,
VENDOR_ID_INQ_MOBILE,
VENDOR_ID_SONY,
diff --git a/include/arch/darwin-x86/AndroidConfig.h b/include/arch/darwin-x86/AndroidConfig.h
index f79f364..48f8d9a 100644
--- a/include/arch/darwin-x86/AndroidConfig.h
+++ b/include/arch/darwin-x86/AndroidConfig.h
@@ -305,4 +305,14 @@
*/
#define HAVE_PRINTF_ZD 1
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 1
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
#endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/freebsd-x86/AndroidConfig.h b/include/arch/freebsd-x86/AndroidConfig.h
index a8176f4..4bc5559 100644
--- a/include/arch/freebsd-x86/AndroidConfig.h
+++ b/include/arch/freebsd-x86/AndroidConfig.h
@@ -363,4 +363,14 @@
*/
#define HAVE_PRINTF_ZD 1
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 1
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
#endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/linux-arm/AndroidConfig.h b/include/arch/linux-arm/AndroidConfig.h
index b8e8713..233752b 100644
--- a/include/arch/linux-arm/AndroidConfig.h
+++ b/include/arch/linux-arm/AndroidConfig.h
@@ -361,4 +361,14 @@
*/
#define HAVE_PRINTF_ZD 1
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
#endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/linux-ppc/AndroidConfig.h b/include/arch/linux-ppc/AndroidConfig.h
index 774c458..ae2569b 100644
--- a/include/arch/linux-ppc/AndroidConfig.h
+++ b/include/arch/linux-ppc/AndroidConfig.h
@@ -323,4 +323,14 @@
*/
#define HAVE_PREAD 1
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 1
+
#endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/linux-sh/AndroidConfig.h b/include/arch/linux-sh/AndroidConfig.h
index cdfa2ac..818b628 100644
--- a/include/arch/linux-sh/AndroidConfig.h
+++ b/include/arch/linux-sh/AndroidConfig.h
@@ -366,4 +366,14 @@
*/
#define HAVE_PRINTF_ZD 1
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
#endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/linux-x86/AndroidConfig.h b/include/arch/linux-x86/AndroidConfig.h
index 6521699..431a54b 100644
--- a/include/arch/linux-x86/AndroidConfig.h
+++ b/include/arch/linux-x86/AndroidConfig.h
@@ -333,4 +333,18 @@
*/
#define HAVE_PRINTF_ZD 1
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+#define HAVE_GNU_QSORT_R 1
+#else
+#define HAVE_GNU_QSORT_R 0
+#endif
+
#endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/target_linux-x86/AndroidConfig.h b/include/arch/target_linux-x86/AndroidConfig.h
index 9efb81a..ab53892 100644
--- a/include/arch/target_linux-x86/AndroidConfig.h
+++ b/include/arch/target_linux-x86/AndroidConfig.h
@@ -350,4 +350,14 @@
*/
#define HAVE_PRINTF_ZD 1
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
#endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/windows/AndroidConfig.h b/include/arch/windows/AndroidConfig.h
index 445e754..0274da5 100644
--- a/include/arch/windows/AndroidConfig.h
+++ b/include/arch/windows/AndroidConfig.h
@@ -338,4 +338,14 @@
*/
/* #define HAVE_PRINTF_ZD 1 */
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
#endif /*_ANDROID_CONFIG_H*/
diff --git a/include/cutils/list.h b/include/cutils/list.h
index eb5a3c8..3881fc9 100644
--- a/include/cutils/list.h
+++ b/include/cutils/list.h
@@ -19,6 +19,10 @@
#include <stddef.h>
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
struct listnode
{
struct listnode *next;
@@ -48,4 +52,8 @@
#define list_head(list) ((list)->next)
#define list_tail(list) ((list)->prev)
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
#endif
diff --git a/include/cutils/logger.h b/include/cutils/logger.h
index b60f7ad..04f3fb0 100644
--- a/include/cutils/logger.h
+++ b/include/cutils/logger.h
@@ -12,6 +12,11 @@
#include <stdint.h>
+/*
+ * The userspace structure for version 1 of the logger_entry ABI.
+ * This structure is returned to userspace by the kernel logger
+ * driver unless an upgrade to a newer ABI version is requested.
+ */
struct logger_entry {
uint16_t len; /* length of the payload */
uint16_t __pad; /* no matter what, we get 2 bytes of padding */
@@ -22,14 +27,41 @@
char msg[0]; /* the entry's payload */
};
+/*
+ * The userspace structure for version 2 of the logger_entry ABI.
+ * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
+ * is called with version==2
+ */
+struct logger_entry_v2 {
+ uint16_t len; /* length of the payload */
+ uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
+ int32_t pid; /* generating process's pid */
+ int32_t tid; /* generating process's tid */
+ int32_t sec; /* seconds since Epoch */
+ int32_t nsec; /* nanoseconds */
+ uint32_t euid; /* effective UID of logger */
+ char msg[0]; /* the entry's payload */
+};
+
#define LOGGER_LOG_MAIN "log/main"
#define LOGGER_LOG_RADIO "log/radio"
#define LOGGER_LOG_EVENTS "log/events"
#define LOGGER_LOG_SYSTEM "log/system"
-#define LOGGER_ENTRY_MAX_LEN (4*1024)
-#define LOGGER_ENTRY_MAX_PAYLOAD \
- (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
+/*
+ * The maximum size of the log entry payload that can be
+ * written to the kernel logger driver. An attempt to write
+ * more than this amount to /dev/log/* will result in a
+ * truncated log entry.
+ */
+#define LOGGER_ENTRY_MAX_PAYLOAD 4076
+
+/*
+ * The maximum size of a log entry which can be read from the
+ * kernel logger driver. An attempt to read less than this amount
+ * may result in read() returning EINVAL.
+ */
+#define LOGGER_ENTRY_MAX_LEN (5*1024)
#ifdef HAVE_IOCTL
@@ -41,6 +73,8 @@
#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */
#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */
#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */
+#define LOGGER_GET_VERSION _IO(__LOGGERIO, 5) /* abi version */
+#define LOGGER_SET_VERSION _IO(__LOGGERIO, 6) /* abi version */
#endif // HAVE_IOCTL
diff --git a/include/cutils/qsort_r_compat.h b/include/cutils/qsort_r_compat.h
new file mode 100644
index 0000000..479a1ab
--- /dev/null
+++ b/include/cutils/qsort_r_compat.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Provides a portable version of qsort_r, called qsort_r_compat, which is a
+ * reentrant variant of qsort that passes a user data pointer to its comparator.
+ * This implementation follows the BSD parameter convention.
+ */
+
+#ifndef _LIBS_CUTILS_QSORT_R_COMPAT_H
+#define _LIBS_CUTILS_QSORT_R_COMPAT_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+ int (*compar)(void*, const void* , const void* ));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBS_CUTILS_QSORT_R_COMPAT_H
diff --git a/include/cutils/sched_policy.h b/include/cutils/sched_policy.h
index eaf3993..753a08c 100644
--- a/include/cutils/sched_policy.h
+++ b/include/cutils/sched_policy.h
@@ -24,11 +24,28 @@
typedef enum {
SP_BACKGROUND = 0,
SP_FOREGROUND = 1,
+ SP_CNT,
+ SP_MAX = SP_CNT - 1,
} SchedPolicy;
+/* Assign thread tid to the cgroup associated with the specified policy.
+ * If the thread is a thread group leader, that is it's gettid() == getpid(),
+ * then the other threads in the same thread group are _not_ affected.
+ * Return value: 0 for success, or -errno for error.
+ */
extern int set_sched_policy(int tid, SchedPolicy policy);
+
+/* Return the policy associated with the cgroup of thread tid via policy pointer.
+ * Return value: 0 for success, or -1 for error and set errno.
+ */
extern int get_sched_policy(int tid, SchedPolicy *policy);
+/* Return a displayable string corresponding to policy.
+ * Return value: non-NULL NUL-terminated name of unspecified length;
+ * the caller is responsible for displaying the useful part of the string.
+ */
+extern const char *get_sched_policy_name(SchedPolicy policy);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/system/audio.h b/include/system/audio.h
index 0980319..0276231 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -384,7 +384,7 @@
return false;
}
-/* Derive a channel mask from a channel count.
+/* Derive an output channel mask from a channel count.
* This is to be used when the content channel mask is unknown. The 1, 2, 4, 5, 6, 7 and 8 channel
* cases are mapped to the standard game/home-theater layouts, but note that 4 is mapped to quad,
* and not stereo + FC + mono surround. A channel count of 3 is arbitrarily mapped to stereo + FC
@@ -392,7 +392,7 @@
* Returns the matching channel mask, or 0 if the number of channels exceeds that of the
* configurations for which a default channel mask is defined.
*/
-static inline audio_channel_mask_t audio_channel_mask_from_count(uint32_t channel_count)
+static inline audio_channel_mask_t audio_channel_out_mask_from_count(uint32_t channel_count)
{
switch(channel_count) {
case 1:
@@ -416,6 +416,19 @@
}
}
+/* Similar to above, but for input. Currently handles only mono and stereo. */
+static inline audio_channel_mask_t audio_channel_in_mask_from_count(uint32_t channel_count)
+{
+ switch (channel_count) {
+ case 1:
+ return AUDIO_CHANNEL_IN_MONO;
+ case 2:
+ return AUDIO_CHANNEL_IN_STEREO;
+ default:
+ return 0;
+ }
+}
+
static inline bool audio_is_valid_format(audio_format_t format)
{
switch (format & AUDIO_FORMAT_MAIN_MASK) {
@@ -447,18 +460,18 @@
size_t size = 0;
switch (format) {
- case AUDIO_FORMAT_PCM_32_BIT:
- case AUDIO_FORMAT_PCM_8_24_BIT:
- size = sizeof(int32_t);
- break;
- case AUDIO_FORMAT_PCM_16_BIT:
- size = sizeof(int16_t);
- break;
- case AUDIO_FORMAT_PCM_8_BIT:
- size = sizeof(uint8_t);
- break;
- default:
- break;
+ case AUDIO_FORMAT_PCM_32_BIT:
+ case AUDIO_FORMAT_PCM_8_24_BIT:
+ size = sizeof(int32_t);
+ break;
+ case AUDIO_FORMAT_PCM_16_BIT:
+ size = sizeof(int16_t);
+ break;
+ case AUDIO_FORMAT_PCM_8_BIT:
+ size = sizeof(uint8_t);
+ break;
+ default:
+ break;
}
return size;
}
diff --git a/include/system/audio_policy.h b/include/system/audio_policy.h
index 70fc534..641b177 100644
--- a/include/system/audio_policy.h
+++ b/include/system/audio_policy.h
@@ -43,10 +43,11 @@
AUDIO_POLICY_OUTPUT_FLAG_NONE = 0x0, // no attributes
AUDIO_POLICY_OUTPUT_FLAG_DIRECT = 0x1, // this output directly connects a track to one output
// stream (no software mixer)
- AUDIO_POLICY_OUTPUT_FLAG_PRIMARY = 0x2 // this output is the primary output of the device.
+ AUDIO_POLICY_OUTPUT_FLAG_PRIMARY = 0x2, // this output is the primary output of the device.
// it is unique and must be present. it is opened by
// default and receives routing, audio mode and
// volume controls related to voice calls.
+ AUDIO_POLICY_OUTPUT_FLAG_FAST = 0x4, // output supports "fast tracks", defined elsewhere
} audio_policy_output_flags_t;
/* device categories used for audio_policy->set_force_use() */
diff --git a/include/system/camera.h b/include/system/camera.h
index 62167cf..b8389b1 100644
--- a/include/system/camera.h
+++ b/include/system/camera.h
@@ -151,11 +151,30 @@
* arg1 = 0 will disable, while passing arg1 = 1 will enable the callback.
*/
CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG = 8,
+
+ /**
+ * Ping camera service to see if camera hardware is released.
+ *
+ * When any camera method returns error, the client can use ping command
+ * to see if the camera has been taken away by other clients. If the result
+ * is NO_ERROR, it means the camera hardware is not released. If the result
+ * is not NO_ERROR, the camera has been released and the existing client
+ * can silently finish itself or show a dialog.
+ */
+ CAMERA_CMD_PING = 9,
};
/** camera fatal errors */
enum {
CAMERA_ERROR_UNKNOWN = 1,
+ /**
+ * Camera was released because another client has connected to the camera.
+ * The original client should call Camera::disconnect immediately after
+ * getting this notification. Otherwise, the camera will be released by
+ * camera service in a short time. The client should not call any method
+ * (except disconnect and sending CAMERA_CMD_PING) after getting this.
+ */
+ CAMERA_ERROR_RELEASED = 2,
CAMERA_ERROR_SERVER_DIED = 100
};
diff --git a/init/builtins.c b/init/builtins.c
index 9aa2345..adad353 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -75,6 +75,52 @@
}
}
+static int _chown(const char *path, unsigned int uid, unsigned int gid)
+{
+ int fd;
+ int ret;
+
+ fd = open(path, O_RDONLY | O_NOFOLLOW);
+ if (fd < 0) {
+ return -1;
+ }
+
+ ret = fchown(fd, uid, gid);
+ if (ret < 0) {
+ int errno_copy = errno;
+ close(fd);
+ errno = errno_copy;
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
+static int _chmod(const char *path, mode_t mode)
+{
+ int fd;
+ int ret;
+
+ fd = open(path, O_RDONLY | O_NOFOLLOW);
+ if (fd < 0) {
+ return -1;
+ }
+
+ ret = fchmod(fd, mode);
+ if (ret < 0) {
+ int errno_copy = errno;
+ close(fd);
+ errno = errno_copy;
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
static int insmod(const char *filename, char *options)
{
void *module;
@@ -246,7 +292,7 @@
ret = mkdir(args[1], mode);
/* chmod in case the directory already exists */
if (ret == -1 && errno == EEXIST) {
- ret = chmod(args[1], mode);
+ ret = _chmod(args[1], mode);
}
if (ret == -1) {
return -errno;
@@ -260,7 +306,7 @@
gid = decode_uid(args[4]);
}
- if (chown(args[1], uid, gid)) {
+ if (_chown(args[1], uid, gid) < 0) {
return -errno;
}
}
@@ -644,10 +690,10 @@
int do_chown(int nargs, char **args) {
/* GID is optional. */
if (nargs == 3) {
- if (chown(args[2], decode_uid(args[1]), -1) < 0)
+ if (_chown(args[2], decode_uid(args[1]), -1) < 0)
return -errno;
} else if (nargs == 4) {
- if (chown(args[3], decode_uid(args[1]), decode_uid(args[2])))
+ if (_chown(args[3], decode_uid(args[1]), decode_uid(args[2])) < 0)
return -errno;
} else {
return -1;
@@ -670,7 +716,7 @@
int do_chmod(int nargs, char **args) {
mode_t mode = get_mode(args[1]);
- if (chmod(args[2], mode) < 0) {
+ if (_chmod(args[2], mode) < 0) {
return -errno;
}
return 0;
diff --git a/init/devices.c b/init/devices.c
index 3b4d369..125f981 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -63,6 +63,7 @@
const char *subsystem;
const char *firmware;
const char *partition_name;
+ const char *device_name;
int partition_num;
int major;
int minor;
@@ -335,6 +336,7 @@
uevent->minor = -1;
uevent->partition_name = NULL;
uevent->partition_num = -1;
+ uevent->device_name = NULL;
/* currently ignoring SEQNUM */
while(*msg) {
@@ -362,9 +364,12 @@
} else if(!strncmp(msg, "PARTNAME=", 9)) {
msg += 9;
uevent->partition_name = msg;
+ } else if(!strncmp(msg, "DEVNAME=", 8)) {
+ msg += 8;
+ uevent->device_name = msg;
}
- /* advance to after the next \0 */
+ /* advance to after the next \0 */
while(*msg++)
;
}
@@ -579,18 +584,39 @@
if (!strncmp(uevent->subsystem, "usb", 3)) {
if (!strcmp(uevent->subsystem, "usb")) {
- /* This imitates the file system that would be created
- * if we were using devfs instead.
- * Minors are broken up into groups of 128, starting at "001"
- */
- int bus_id = uevent->minor / 128 + 1;
- int device_id = uevent->minor % 128 + 1;
- /* build directories */
- make_dir("/dev/bus", 0755);
- make_dir("/dev/bus/usb", 0755);
- snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
- make_dir(devpath, 0755);
- snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
+ if (uevent->device_name) {
+ /*
+ * create device node provided by kernel if present
+ * see drivers/base/core.c
+ */
+ char *p = devpath;
+ snprintf(devpath, sizeof(devpath), "/dev/%s", uevent->device_name);
+ /* skip leading /dev/ */
+ p += 5;
+ /* build directories */
+ while (*p) {
+ if (*p == '/') {
+ *p = 0;
+ make_dir(devpath, 0755);
+ *p = '/';
+ }
+ p++;
+ }
+ }
+ else {
+ /* This imitates the file system that would be created
+ * if we were using devfs instead.
+ * Minors are broken up into groups of 128, starting at "001"
+ */
+ int bus_id = uevent->minor / 128 + 1;
+ int device_id = uevent->minor % 128 + 1;
+ /* build directories */
+ make_dir("/dev/bus", 0755);
+ make_dir("/dev/bus/usb", 0755);
+ snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
+ make_dir(devpath, 0755);
+ snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
+ }
} else {
/* ignore other USB events */
return;
diff --git a/init/init.c b/init/init.c
index 1ee88a7..5458e34 100755
--- a/init/init.c
+++ b/init/init.c
@@ -134,6 +134,7 @@
if ((fd = open(console_name, O_RDWR)) < 0) {
fd = open("/dev/null", O_RDWR);
}
+ ioctl(fd, TIOCSCTTY, 0);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 3809733..0d49165 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -46,6 +46,7 @@
record_stream.c \
process_name.c \
properties.c \
+ qsort_r_compat.c \
threads.c \
sched_policy.c \
iosched_policy.c \
diff --git a/libcutils/process_name.c b/libcutils/process_name.c
index b235429..bda9d08 100644
--- a/libcutils/process_name.c
+++ b/libcutils/process_name.c
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <stdlib.h>
#include <string.h>
#include <cutils/process_name.h>
#include <cutils/properties.h>
diff --git a/libcutils/qsort_r_compat.c b/libcutils/qsort_r_compat.c
new file mode 100644
index 0000000..8971cb5
--- /dev/null
+++ b/libcutils/qsort_r_compat.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 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 <stdlib.h>
+#include <cutils/qsort_r_compat.h>
+
+#if HAVE_BSD_QSORT_R
+
+/*
+ * BSD qsort_r parameter order is as we have defined here.
+ */
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+ int (*compar)(void*, const void* , const void*)) {
+ qsort_r(base, nel, width, thunk, compar);
+}
+
+#elif HAVE_GNU_QSORT_R
+
+/*
+ * GNU qsort_r parameter order places the thunk parameter last.
+ */
+
+struct compar_data {
+ void* thunk;
+ int (*compar)(void*, const void* , const void*);
+};
+
+static int compar_wrapper(const void* a, const void* b, void* data) {
+ struct compar_data* compar_data = (struct compar_data*)data;
+ return compar_data->compar(compar_data->thunk, a, b);
+}
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+ int (*compar)(void*, const void* , const void*)) {
+ struct compar_data compar_data;
+ compar_data.thunk = thunk;
+ compar_data.compar = compar;
+ qsort_r(base, nel, width, compar_wrapper, &compar_data);
+}
+
+#else
+
+/*
+ * Emulate qsort_r using thread local storage to access the thunk data.
+ */
+
+#include <cutils/threads.h>
+
+static thread_store_t compar_data_key = THREAD_STORE_INITIALIZER;
+
+struct compar_data {
+ void* thunk;
+ int (*compar)(void*, const void* , const void*);
+};
+
+static int compar_wrapper(const void* a, const void* b) {
+ struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key);
+ return compar_data->compar(compar_data->thunk, a, b);
+}
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+ int (*compar)(void*, const void* , const void*)) {
+ struct compar_data compar_data;
+ compar_data.thunk = thunk;
+ compar_data.compar = compar;
+ thread_store_set(&compar_data_key, &compar_data, NULL);
+ qsort(base, nel, width, compar_wrapper);
+}
+
+#endif
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index f9c111e..35d362a 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -273,5 +273,17 @@
return 0;
}
+const char *get_sched_policy_name(SchedPolicy policy)
+{
+ static const char * const strings[SP_CNT] = {
+ [SP_BACKGROUND] = "bg",
+ [SP_FOREGROUND] = "fg",
+ };
+ if ((policy < SP_CNT) && (strings[policy] != NULL))
+ return strings[policy];
+ else
+ return "error";
+}
+
#endif /* HAVE_PTHREADS */
#endif /* HAVE_SCHED_H */
diff --git a/libcutils/str_parms.c b/libcutils/str_parms.c
index 16138f6..9e1d2dc 100644
--- a/libcutils/str_parms.c
+++ b/libcutils/str_parms.c
@@ -70,19 +70,57 @@
return NULL;
}
+struct remove_ctxt {
+ struct str_parms *str_parms;
+ const char *key;
+};
+
static bool remove_pair(void *key, void *value, void *context)
{
- struct str_parms *str_parms = context;
+ struct remove_ctxt *ctxt = context;
+ bool should_continue;
- hashmapRemove(str_parms->map, key);
+ /*
+ * - if key is not supplied, then we are removing all entries,
+ * so remove key and continue (i.e. return true)
+ * - if key is supplied and matches, then remove it and don't
+ * continue (return false). Otherwise, return true and keep searching
+ * for key.
+ *
+ */
+ if (!ctxt->key) {
+ should_continue = true;
+ goto do_remove;
+ } else if (!strcmp(ctxt->key, key)) {
+ should_continue = false;
+ goto do_remove;
+ }
+
+ return true;
+
+do_remove:
+ hashmapRemove(ctxt->str_parms->map, key);
free(key);
free(value);
- return true;
+ return should_continue;
+}
+
+void str_parms_del(struct str_parms *str_parms, const char *key)
+{
+ struct remove_ctxt ctxt = {
+ .str_parms = str_parms,
+ .key = key,
+ };
+ hashmapForEach(str_parms->map, remove_pair, &ctxt);
}
void str_parms_destroy(struct str_parms *str_parms)
{
- hashmapForEach(str_parms->map, remove_pair, str_parms);
+ struct remove_ctxt ctxt = {
+ .str_parms = str_parms,
+ };
+
+ hashmapForEach(str_parms->map, remove_pair, &ctxt);
hashmapFree(str_parms->map);
free(str_parms);
}
@@ -128,8 +166,10 @@
/* if we replaced a value, free it */
old_val = hashmapPut(str_parms->map, key, value);
- if (old_val)
+ if (old_val) {
free(old_val);
+ free(key);
+ }
items++;
next_pair:
@@ -149,11 +189,6 @@
return NULL;
}
-void str_parms_del(struct str_parms *str_parms, const char *key)
-{
- hashmapRemove(str_parms->map, (void *)key);
-}
-
int str_parms_add_str(struct str_parms *str_parms, const char *key,
const char *value)
{
@@ -167,6 +202,7 @@
if (old_val) {
free(old_val);
+ free(tmp_key);
} else if (errno == ENOMEM) {
free(tmp_key);
free(tmp_val);
@@ -302,6 +338,8 @@
str_parms = str_parms_create_str(str);
str_parms_add_str(str_parms, "dude", "woah");
+ str_parms_add_str(str_parms, "dude", "woah");
+ str_parms_del(str_parms, "dude");
str_parms_dump(str_parms);
out_str = str_parms_to_str(str_parms);
str_parms_destroy(str_parms);
@@ -327,6 +365,7 @@
test_str_parms_str("foo=bar;baz=");
test_str_parms_str("foo=bar;baz=bat");
test_str_parms_str("foo=bar;baz=bat;");
+ test_str_parms_str("foo=bar;baz=bat;foo=bar");
return 0;
}
diff --git a/libcutils/tzstrftime.c b/libcutils/tzstrftime.c
index e37d79a..e4f54df 100644
--- a/libcutils/tzstrftime.c
+++ b/libcutils/tzstrftime.c
@@ -8,6 +8,7 @@
#endif /* !defined NOID */
#endif /* !defined lint */
+#include <stdio.h>
#include <time.h>
#include <tzfile.h>
#include <limits.h>
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2e8f7d2..71ec3fa 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -1,3 +1,9 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# IMPORTANT: Do not create world writable files or directories.
+# This is a common source of Android security bugs.
+#
+
import /init.${ro.hardware}.rc
on early-init
@@ -24,7 +30,7 @@
export ANDROID_DATA /data
export ASEC_MOUNTPOINT /mnt/asec
export LOOP_MOUNTPOINT /mnt/obb
- export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/filterfw.jar
+ export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar
# Backward compatibility
symlink /system/etc /etc
@@ -163,11 +169,16 @@
mkdir /data/misc/wifi 0770 wifi wifi
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
mkdir /data/local 0751 root root
+
+ # For security reasons, /data/local/tmp should always be empty.
+ # Do not place files or directories in /data/local/tmp
mkdir /data/local/tmp 0771 shell shell
mkdir /data/data 0771 system system
mkdir /data/app-private 0771 system system
mkdir /data/app 0771 system system
mkdir /data/property 0700 root root
+ mkdir /data/ssh 0750 root shell
+ mkdir /data/ssh/empty 0700 root root
# create dalvik-cache, so as to enforce our permissions
mkdir /data/dalvik-cache 0771 system system
@@ -224,7 +235,8 @@
chown radio system /sys/android_power/acquire_full_wake_lock
chown radio system /sys/android_power/acquire_partial_wake_lock
chown radio system /sys/android_power/release_wake_lock
- chown radio system /sys/power/state
+ chown system system /sys/power/state
+ chown system system /sys/power/wakeup_count
chown radio system /sys/power/wake_lock
chown radio system /sys/power/wake_unlock
chmod 0660 /sys/power/state
@@ -367,18 +379,6 @@
on property:ro.kernel.qemu=1
start adbd
-# This property trigger has added to imitiate the previous behavior of "adb root".
-# The adb gadget driver used to reset the USB bus when the adbd daemon exited,
-# and the host side adb relied on this behavior to force it to reconnect with the
-# new adbd instance after init relaunches it. So now we force the USB bus to reset
-# here when adbd sets the service.adb.root property to 1. We also restart adbd here
-# rather than waiting for init to notice its death and restarting it so the timing
-# of USB resetting and adb restarting more closely matches the previous behavior.
-on property:service.adb.root=1
- write /sys/class/android_usb/android0/enable 0
- restart adbd
- write /sys/class/android_usb/android0/enable 1
-
service servicemanager /system/bin/servicemanager
class core
user system
@@ -426,7 +426,7 @@
service drm /system/bin/drmserver
class main
user drm
- group system inet drmrpc
+ group drm system inet drmrpc
service media /system/bin/mediaserver
class main
@@ -483,7 +483,7 @@
service keystore /system/bin/keystore /data/misc/keystore
class main
user keystore
- group keystore
+ group keystore drmrpc
socket keystore stream 666
service dumpstate /system/bin/dumpstate -s
@@ -491,3 +491,7 @@
socket dumpstate stream 0660 shell log
disabled
oneshot
+
+service sshd /system/bin/start-ssh
+ class main
+ disabled
diff --git a/toolbox/ps.c b/toolbox/ps.c
index 7c3de4a..7c35ccb 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -167,14 +167,8 @@
SchedPolicy p;
if (get_sched_policy(pid, &p) < 0)
printf(" un ");
- else {
- if (p == SP_BACKGROUND)
- printf(" bg ");
- else if (p == SP_FOREGROUND)
- printf(" fg ");
- else
- printf(" er ");
- }
+ else
+ printf(" %.2s ", get_sched_policy_name(p));
}
printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name);
if(display_flags&SHOW_TIME)
diff --git a/toolbox/top.c b/toolbox/top.c
index 999c8e1..7642522 100644
--- a/toolbox/top.c
+++ b/toolbox/top.c
@@ -48,6 +48,7 @@
#define PROC_NAME_LEN 64
#define THREAD_NAME_LEN 32
+#define POLICY_NAME_LEN 4
struct proc_info {
struct proc_info *next;
@@ -67,7 +68,7 @@
long rss;
int prs;
int num_threads;
- char policy[32];
+ char policy[POLICY_NAME_LEN];
};
struct proc_list {
@@ -381,14 +382,10 @@
static void read_policy(int pid, struct proc_info *proc) {
SchedPolicy p;
if (get_sched_policy(pid, &p) < 0)
- strcpy(proc->policy, "unk");
+ strlcpy(proc->policy, "unk", POLICY_NAME_LEN);
else {
- if (p == SP_BACKGROUND)
- strcpy(proc->policy, "bg");
- else if (p == SP_FOREGROUND)
- strcpy(proc->policy, "fg");
- else
- strcpy(proc->policy, "er");
+ strlcpy(proc->policy, get_sched_policy_name(p), POLICY_NAME_LEN);
+ proc->policy[2] = '\0';
}
}