#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();
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;
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);
}
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) {
}
}
- 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);
}