OSDN Git Service

require that --daemon is uid/gid 0
authorKoushik Dutta <koushd@gmail.com>
Thu, 14 Nov 2013 16:07:27 +0000 (17:07 +0100)
committerKoushik Dutta <koushd@gmail.com>
Fri, 15 Nov 2013 16:38:56 +0000 (17:38 +0100)
execv invocation fixes

Change-Id: I80e7100a834b7eca2d9c8560c221cffd41492f03

.gitignore
Superuser/AndroidManifest.xml
Superuser/assets/update-binary [changed mode: 0644->0755]
Superuser/jni/Application.mk
Superuser/jni/su/activity.c
Superuser/jni/su/daemon.c
Superuser/jni/su/su.h
Superuser/project.properties
Superuser/src/com/koushikdutta/superuser/util/SuHelper.java

index db9a20b..8fbf940 100644 (file)
@@ -5,4 +5,5 @@ obj
 local.properties
 gen
 .DS_Store
-.settings
\ No newline at end of file
+.settings
+libs
index 128d01e..97cae54 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.koushikdutta.superuser"
-    android:versionCode="1022"
-    android:versionName="1.0.2.2" >
+    android:versionCode="1023"
+    android:versionName="1.0.2.3" >
 
     <uses-sdk
         android:minSdkVersion="8"
old mode 100644 (file)
new mode 100755 (executable)
index eefa617..bef27a6 100644 (file)
@@ -1,3 +1,3 @@
 APP_ABI := x86 armeabi mips
-NDK_TOOLCHAIN_VERSION=4.7
+NDK_TOOLCHAIN_VERSION=4.8
 APP_PIE = false
\ No newline at end of file
index 9bda4f9..eb18759 100644 (file)
 
 #include "su.h"
 
+/* intent actions */
+#define ACTION_REQUEST "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".RequestActivity"
+#define ACTION_NOTIFY "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".NotifyActivity"
+#define ACTION_RESULT "broadcast", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".SuReceiver"
+
+#define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am"
+
 // TODO: leverage this with exec_log?
-int silent_run(char* command) {
-    char *args[] = { "sh", "-c", command, NULL, };
+int silent_run(char* const args[]) {
     set_identity(0);
     pid_t pid;
     pid = fork();
@@ -45,7 +51,8 @@ int silent_run(char* command) {
     int null = open("/dev/null", O_WRONLY | O_CLOEXEC);
     dup2(null, 1);
     dup2(null, 2);
-    execv(_PATH_BSHELL, args);
+    setenv("CLASSPATH", "/system/framework/am.jar", 1);
+    execv(args[0], args);
     PLOGE("exec am");
     _exit(EXIT_FAILURE);
     return -1;
@@ -58,39 +65,97 @@ int get_owner_login_user_args(struct su_context *ctx, char* user, int user_len)
         if (0 != ctx->user.android_user_id) {
             needs_owner_login_prompt = 1;
         }
-        snprintf(user, user_len, "--user 0");
+        snprintf(user, user_len, "0");
     }
     else if (ctx->user.multiuser_mode == MULTIUSER_MODE_USER) {
-        snprintf(user, user_len, "--user %d", ctx->user.android_user_id);
+        snprintf(user, user_len, "%d", ctx->user.android_user_id);
     }
     else if (ctx->user.multiuser_mode == MULTIUSER_MODE_NONE) {
         user[0] = '\0';
     }
     else {
-        snprintf(user, user_len, "--user 0");
+        snprintf(user, user_len, "0");
     }
     
     return needs_owner_login_prompt;
 }
 
 int send_result(struct su_context *ctx, policy_t policy) {
-    char user[64];
-    get_owner_login_user_args(ctx, user, sizeof(user));
-    
+    char binary_version[256];
+    sprintf(binary_version, "%d", VERSION_CODE);
+
+    char uid[256];
+    sprintf(uid, "%d", ctx->from.uid);
+
+    char desired_uid[256];
+    sprintf(desired_uid, "%d", ctx->to.uid);
+
     if (0 != ctx->user.android_user_id) {
-        char user_result_command[ARG_MAX];
-        snprintf(user_result_command, sizeof(user_result_command), "exec /system/bin/am " ACTION_RESULT " --ei binary_version %d --es from_name '%s' --es desired_name '%s' --ei uid %d --ei desired_uid %d --es command '%s' --es action %s --user %d",
-            VERSION_CODE,
-            ctx->from.name, ctx->to.name,
-            ctx->from.uid, ctx->to.uid, get_command(&ctx->to), policy == ALLOW ? "allow" : "deny", ctx->user.android_user_id);
+        char android_user_id[256];
+        sprintf(android_user_id, "%d", ctx->user.android_user_id);
+
+        char *user_result_command[] = {
+            AM_PATH,
+            ACTION_RESULT,
+            "--ei",
+            "binary_version",
+            binary_version,
+            "--es",
+            "from_name",
+            ctx->from.name,
+            "--es",
+            "desired_name",
+            ctx->to.name,
+            "--ei",
+            "uid",
+            uid,
+            "--ei",
+            "desired_uid",
+            desired_uid,
+            "--es",
+            "command",
+            get_command(&ctx->to),
+            "--es",
+            "action",
+            policy == ALLOW ? "allow" : "deny",
+            "--user",
+            android_user_id,
+            NULL
+        };
         silent_run(user_result_command);
     }
 
-    char result_command[ARG_MAX];
-    snprintf(result_command, sizeof(result_command), "exec /system/bin/am " ACTION_RESULT " --ei binary_version %d --es from_name '%s' --es desired_name '%s' --ei uid %d --ei desired_uid %d --es command '%s' --es action %s %s",
-        VERSION_CODE,
-        ctx->from.name, ctx->to.name,
-        ctx->from.uid, ctx->to.uid, get_command(&ctx->to), policy == ALLOW ? "allow" : "deny", user);
+    char user[64];
+    get_owner_login_user_args(ctx, user, sizeof(user));
+
+    char *result_command[] = {
+        AM_PATH,
+        ACTION_RESULT,
+        "--ei",
+        "binary_version",
+        binary_version,
+        "--es",
+        "from_name",
+        ctx->from.name,
+        "--es",
+        "desired_name",
+        ctx->to.name,
+        "--ei",
+        "uid",
+        uid,
+        "--ei",
+        "desired_uid",
+        desired_uid,
+        "--es",
+        "command",
+        get_command(&ctx->to),
+        "--es",
+        "action",
+        policy == ALLOW ? "allow" : "deny",
+        "--user",
+        user,
+        NULL
+    };
     return silent_run(result_command);
 }
 
@@ -104,13 +169,23 @@ int send_request(struct su_context *ctx) {
 
     int ret;
     if (needs_owner_login_prompt) {
-        // in multiuser mode, the owner gets the su prompt
-        char notify_command[ARG_MAX];
+        char uid[256];
+        sprintf(uid, "%d", ctx->from.uid);
+
+        char android_user_id[256];
+        sprintf(android_user_id, "%d", ctx->user.android_user_id);
 
-        // start the activity that confirms the request
-        snprintf(notify_command, sizeof(notify_command),
-            "exec /system/bin/am " ACTION_NOTIFY " --ei caller_uid %d --user %d",
-            ctx->from.uid, ctx->user.android_user_id);
+        // in multiuser mode, the owner gets the su prompt
+        char *notify_command[] = {
+            AM_PATH,
+            ACTION_NOTIFY,
+            "--ei",
+            "caller_uid",
+            uid,
+            "--user",
+            android_user_id,
+            NULL
+        };
 
         int ret = silent_run(notify_command);
         if (ret) {
@@ -118,12 +193,16 @@ int send_request(struct su_context *ctx) {
         }
     }
 
-    char request_command[ARG_MAX];
-
-    // start the activity that confirms the request
-    snprintf(request_command, sizeof(request_command),
-        "exec /system/bin/am " ACTION_REQUEST " --es socket '%s' %s",
-        ctx->sock_path, user);
+    char *request_command[] = {
+        AM_PATH,
+        ACTION_REQUEST,
+        "--es",
+        "socket",
+        ctx->sock_path,
+        "--user",
+        user,
+        NULL
+    };
 
     return silent_run(request_command);
 }
index 38b20ed..e688149 100644 (file)
@@ -375,6 +375,11 @@ done:
 }
 
 int run_daemon() {
+    if (getuid() != 0 || getgid() != 0) {
+        PLOGE("daemon requires root. uid/gid not root");
+        return -1;
+    }
+
     int fd;
     struct sockaddr_un sun;
 
index 3508e3d..c3957df 100644 (file)
 #define REQUESTOR_DATABASE_PATH REQUESTOR "/databases/su.sqlite"
 #define REQUESTOR_MULTIUSER_MODE REQUESTOR_FILES_PATH "/multiuser_mode"
 
-/* intent actions */
-#define ACTION_REQUEST "start -n " REQUESTOR "/" REQUESTOR_PREFIX ".RequestActivity"
-#define ACTION_NOTIFY "start -n " REQUESTOR "/" REQUESTOR_PREFIX ".NotifyActivity"
-#define ACTION_RESULT "broadcast -n " REQUESTOR "/" REQUESTOR_PREFIX ".SuReceiver"
-
 #define DEFAULT_SHELL "/system/bin/sh"
 
 #define xstr(a) str(a)
 #define str(a) #a
 
 #ifndef VERSION_CODE
-#define VERSION_CODE 13
+#define VERSION_CODE 14
 #endif
 #define VERSION xstr(VERSION_CODE) " " REQUESTOR
 
@@ -160,7 +155,6 @@ extern policy_t database_check(struct su_context *ctx);
 extern void set_identity(unsigned int uid);
 extern int send_request(struct su_context *ctx);
 extern int send_result(struct su_context *ctx, policy_t policy);
-extern int silent_run(char* command);
 
 static inline char *get_command(const struct su_request *to)
 {
index e7b10fe..5c38eca 100644 (file)
@@ -11,6 +11,6 @@
 #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 
 # Project target.
-target=android-18
+target=android-19
 android.library.reference.1=../../Widgets/Widgets
 ndk.executable=ndk-build
index f6b4098..93083b4 100644 (file)
@@ -4,7 +4,7 @@ import android.content.Context;
 import android.util.Log;
 
 public class SuHelper {
-    public static String CURRENT_VERSION = "13";
+    public static String CURRENT_VERSION = "14";
     public static void checkSu(Context context) throws Exception {
         Process p = Runtime.getRuntime().exec("su -v");
         String result = Settings.readToEnd(p.getInputStream());