char *pts_slave = read_string(fd);
LOGD("remote pts_slave: %s", pts_slave);
daemon_from_uid = read_int(fd);
- LOGV("remote uid: %d", daemon_from_uid);
+ LOGD("remote uid: %d", daemon_from_uid);
daemon_from_pid = read_int(fd);
- LOGV("remote req pid: %d", daemon_from_pid);
+ LOGD("remote req pid: %d", daemon_from_pid);
struct ucred credentials;
- int ucred_length = sizeof(struct ucred);
+ socklen_t ucred_length = sizeof(struct ucred);
/* fill in the user data structure */
if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length)) {
LOGE("could obtain credentials from unix domain socket");
LOGE("unable to allocate args: %d", argc);
exit(-1);
}
- LOGV("remote args: %d", argc);
+ LOGD("remote args: %d", argc);
char** argv = (char**)malloc(sizeof(char*) * (argc + 1));
argv[argc] = NULL;
int i;
errfd = ptsfd;
}
} else {
- // TODO: Check system property, if PTYs are disabled,
- // made infd the CTTY using:
- // ioctl(infd, TIOCSCTTY, 1);
+ // If a TTY was sent directly, make it the CTTY.
+ if (isatty(infd)) {
+ ioctl(infd, TIOCSCTTY, 1);
+ }
}
free(pts_slave);
int previous_umask = umask(027);
mkdir(REQUESTOR_DAEMON_PATH, 0777);
+ memset(sun.sun_path, 0, sizeof(sun.sun_path));
+ memcpy(sun.sun_path, "\0" "SUPERUSER", strlen("SUPERUSER") + 1);
+
if (bind(fd, (struct sockaddr*)&sun, sizeof(sun)) < 0) {
PLOGE("daemon bind");
goto err;
sun.sun_family = AF_LOCAL;
sprintf(sun.sun_path, "%s/server", REQUESTOR_DAEMON_PATH);
+ memset(sun.sun_path, 0, sizeof(sun.sun_path));
+ memcpy(sun.sun_path, "\0" "SUPERUSER", strlen("SUPERUSER") + 1);
+
if (0 != connect(socketfd, (struct sockaddr*)&sun, sizeof(sun))) {
PLOGE("connect");
exit(-1);
}
- LOGV("connecting client %d", getpid());
+ LOGD("connecting client %d", getpid());
int mount_storage = getenv("MOUNT_EMULATED_STORAGE") != NULL;
// Determine which one of our streams are attached to a TTY
int atty = 0;
- // TODO: Check a system property and never use PTYs if
- // the property is set.
- if (isatty(STDIN_FILENO)) atty |= ATTY_IN;
- if (isatty(STDOUT_FILENO)) atty |= ATTY_OUT;
- if (isatty(STDERR_FILENO)) atty |= ATTY_ERR;
+ // Send TTYs directly (instead of proxying with a PTY) if
+ // the SUPERUSER_SEND_TTY environment variable is set.
+ if (getenv("SUPERUSER_SEND_TTY") == NULL) {
+ if (isatty(STDIN_FILENO)) atty |= ATTY_IN;
+ if (isatty(STDOUT_FILENO)) atty |= ATTY_OUT;
+ if (isatty(STDERR_FILENO)) atty |= ATTY_ERR;
+ }
if (atty) {
// We need a PTY. Get one.
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/uio.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <sys/select.h>
}
}
-void exec_log(int priority, const char* fmt, ...) {
- static int log_fd = -1;
- struct iovec vec[3];
+void exec_log(char *priority, char* logline) {
+ int pid;
+ if ((pid = fork()) == 0) {
+ int null = open("/dev/null", O_WRONLY | O_CLOEXEC);
+ dup2(null, STDIN_FILENO);
+ dup2(null, STDOUT_FILENO);
+ dup2(null, STDERR_FILENO);
+ execl("/system/bin/log", "/system/bin/log", "-p", priority, "-t", LOG_TAG, logline, NULL);
+ _exit(0);
+ }
+ int status;
+ waitpid(pid, &status, 0);
+}
+
+void exec_loge(const char* fmt, ...) {
va_list args;
- char msg[PATH_MAX];
- if (log_fd < 0) {
- log_fd = open("/dev/log/main", O_WRONLY);
- if (log_fd < 0) {
- return;
- }
- }
+ char logline[PATH_MAX];
+ va_start(args, fmt);
+ vsnprintf(logline, PATH_MAX, fmt, args);
+ va_end(args);
+ exec_log("e", logline);
+}
+
+void exec_logw(const char* fmt, ...) {
+ va_list args;
+ char logline[PATH_MAX];
va_start(args, fmt);
- vsnprintf(msg, PATH_MAX, fmt, args);
+ vsnprintf(logline, PATH_MAX, fmt, args);
va_end(args);
+ exec_log("w", logline);
+}
- vec[0].iov_base = (unsigned char *) &priority;
- vec[0].iov_len = 1;
- vec[1].iov_base = (void *) LOG_TAG;
- vec[1].iov_len = strlen(LOG_TAG) + 1;
- vec[2].iov_base = (void *) msg;
- vec[2].iov_len = strlen(msg) + 1;
+void exec_logd(const char* fmt, ...) {
+ va_list args;
- writev(log_fd, vec, 3);
+ char logline[PATH_MAX];
+ va_start(args, fmt);
+ vsnprintf(logline, PATH_MAX, fmt, args);
+ va_end(args);
+ exec_log("d", logline);
}
static int from_init(struct su_initiator *from) {
static int socket_receive_result(int fd, char *result, ssize_t result_len) {
ssize_t len;
- LOGV("waiting for user");
+ LOGD("waiting for user");
len = read(fd, result, result_len-1);
if (len < 0) {
PLOGE("read(result)");
return DEFAULT_SHELL;
}
+void exec_loge(const char* fmt, ...);
+void exec_logw(const char* fmt, ...);
+void exec_logd(const char* fmt, ...);
+
int run_daemon();
int connect_daemon(int argc, char *argv[], int ppid);
int su_main(int argc, char *argv[], int need_client);
// deadbeat dad fork.
int fork_zero_fucks();
-// can't use liblog.so because this is a static binary, so we need
-// to implement this ourselves
-#include <android/log.h>
-
-void exec_log(int priority, const char* fmt, ...);
-
-#ifndef LOG_NDEBUG
-#define LOG_NDEBUG 1
-#endif
-
+// fallback to using /system/bin/log.
+// can't use liblog.so because this is a static binary.
#ifndef LOGE
-#define LOGE(fmt,args...) exec_log(ANDROID_LOG_ERROR, fmt, ##args)
-#endif
-#ifndef LOGW
-#define LOGW(fmt,args...) exec_log(ANDROID_LOG_WARN, fmt, ##args)
+#define LOGE exec_loge
#endif
#ifndef LOGD
-#define LOGD(fmt,args...) exec_log(ANDROID_LOG_DEBUG, fmt, ##args)
-#endif
-#ifndef LOGV
-#if LOG_NDEBUG
-#define LOGV(...) ((void)0)
-#else
-#define LOGV(fmt,args...) exec_log(ANDROID_LOG_VERBOSE, fmt, ##args)
+#define LOGD exec_logd
#endif
+#ifndef LOGW
+#define LOGW exec_logw
#endif
#if 0