Add a logger socket for printing errors 32/200832/2
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 5 Mar 2019 01:07:57 +0000 (10:07 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 5 Mar 2019 01:13:00 +0000 (10:13 +0900)
If execv() call is failed, the child process sends messages to
launchpad. And then, launchpad prints the messages by secure dlog.

Change-Id: I55be076dd095efb9d7addfa36b84dc2362d9daf7
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
inc/launchpad_common.h
src/launchpad.c
src/launchpad_common.c
src/launchpad_loader.c

index 4776a44..c4eefbc 100644 (file)
@@ -105,6 +105,7 @@ typedef struct {
 
 void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *menu_info, int cmd);
 
+int _send_message_to_logger(const char *tag, const char *format, ...);
 int _send_cmd_to_amd(int cmd);
 int _create_server_sock(const char *name);
 app_pkt_t *_recv_pkt_raw(int fd);
index f6d5301..bcb331f 100755 (executable)
@@ -53,6 +53,7 @@
 #define DIFF(a, b) (((a) > (b)) ? (a) - (b) : (b) - (a))
 #define CANDIDATE_NONE 0
 #define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock"
+#define LAUNCHPAD_LOGGER_SOCK ".launchpad-logger-sock"
 #define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader"
 #define LOADER_INFO_PATH       "/usr/share/aul"
 #define LAUNCHER_INFO_PATH     LOADER_INFO_PATH
@@ -577,15 +578,19 @@ static int __fork_app_process(int (*child_fn)(void *), void *arg)
 static int __exec_loader_process(void *arg)
 {
        char **argv = arg;
+       char err_buf[1024];
 
        _signal_unblock_sigchld();
        _close_all_fds();
        _setup_stdio(basename(argv[LOADER_ARG_PATH]));
 
-       if (execv(argv[LOADER_ARG_PATH], argv) < 0)
-               _E("Failed to prepare candidate_process");
-       else
+       if (execv(argv[LOADER_ARG_PATH], argv) < 0) {
+               _send_message_to_logger(argv[LOADER_ARG_PATH],
+                       "Failed to prepare candidate process. error(%d:%s)",
+                       errno, strerror_r(errno, err_buf, sizeof(err_buf)));
+       } else {
                _D("Succeeded to prepare candidate_process");
+       }
 
        return -1;
 }
@@ -739,6 +744,7 @@ static int __send_launchpad_loader(candidate_process_context_t *cpc,
 static int __normal_fork_exec(int argc, char **argv, const char *app_path)
 {
        char *libdir;
+       char err_buf[1024];
 
        _D("start real fork and exec");
 
@@ -751,13 +757,9 @@ static int __normal_fork_exec(int argc, char **argv, const char *app_path)
        _close_all_fds();
 
        if (execv(argv[LOADER_ARG_PATH], argv) < 0) { /* Flawfinder: ignore */
-               if (errno == EACCES) {
-                       _E("such a file is no executable - %s",
-                                       argv[LOADER_ARG_PATH]);
-               } else {
-                       _E("unknown executable error - %s",
-                                       argv[LOADER_ARG_PATH]);
-               }
+               _send_message_to_logger(argv[LOADER_ARG_PATH],
+                       "Failed to execute a file. error(%d:%s)",
+                       errno, strerror_r(errno, err_buf, sizeof(err_buf)));
                return -1;
        }
        /* never reach*/
@@ -2263,6 +2265,61 @@ static int __register_vconf_events(void)
        return 0;
 }
 
+static gboolean __handle_logger(gpointer data)
+{
+       loader_context_t *lc = (loader_context_t *)data;
+       int fd = lc->gpollfd->fd;
+       app_pkt_t *pkt = NULL;
+       struct ucred cr;
+       int clifd = -1;
+
+       pkt = _accept_recv_pkt_raw(fd, &clifd, &cr);
+       if (!pkt) {
+               _E("Failed to receive the packet");
+               return G_SOURCE_CONTINUE;
+       }
+
+       if (getuid() != cr.uid) {
+               _E("Invalid caller");
+               goto end;
+       }
+
+       if (pkt->len <= 0) {
+               _E("Invalid message");
+               goto end;
+       }
+
+       SECURE_LOGE("[%d] %s", cr.pid, (const char *)pkt->data);
+
+end:
+       if (clifd != -1)
+               close(clifd);
+       if (pkt)
+               free(pkt);
+
+       return G_SOURCE_CONTINUE;
+}
+
+static int __init_logger_fd(void)
+{
+       int fd;
+       guint pollfd;
+
+       fd = _create_server_sock(LAUNCHPAD_LOGGER_SOCK);
+       if (fd < 0) {
+               _E("Failed to create logger socker");
+               return -1;
+       }
+
+       pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_logger, 0, 0);
+       if (pollfd == 0) {
+               close(fd);
+               return -1;
+       }
+
+       return 0;
+}
+
 static int __before_loop(int argc, char **argv)
 {
        int ret;
@@ -2285,6 +2342,12 @@ static int __before_loop(int argc, char **argv)
                return -1;
        }
 
+       ret = __init_logger_fd();
+       if (ret != 0) {
+               _E("__init_logger_fd() failed");
+               return -1;
+       }
+
        ret = __init_label_monitor_fd();
        if (ret != 0)
                _W("Failed to initialize label monitor");
index 21cb409..13055e2 100644 (file)
@@ -265,43 +265,46 @@ static int __parse_app_path(const char *arg, char *out, int out_size)
        return -2;
 }
 
-int _send_cmd_to_amd(int cmd)
+static int __create_client_socket(const char *path)
 {
-       struct sockaddr_un addr = {0,};
-       int fd;
-       int ret;
+       struct sockaddr_un addr = { 0, };
        int retry = CONNECT_RETRY_COUNT;
-       app_pkt_t pkt = {0,};
+       int fd;
 
        fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       /*  support above version 2.6.27*/
        if (fd < 0) {
-               if (errno == EINVAL) {
-                       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-                       if (fd < 0) {
-                               _E("second chance - socket create error");
-                               return -1;
-                       }
-               } else {
-                       _E("socket error");
-                       return -1;
-               }
+               _E("Failed to create socket(%s). errno(%d)", path, errno);
+               return -1;
        }
 
        addr.sun_family = AF_UNIX;
-       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", PATH_AMD_SOCK);
+       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
        while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                if (errno != ETIMEDOUT || retry <= 0) {
-                       _E("Failed to connect error(%d)", errno);
+                       _E("Failed to connect socket(%s). errno(%d)",
+                                       path, errno);
                        close(fd);
                        return -1;
                }
 
                usleep(CONNECT_RETRY_TIME);
-               --retry;
-               _D("re-connect to %s (%d)", addr.sun_path, retry);
+               retry--;
+               _W("Retry(%d) to connect %s", retry, path);
        }
 
+       return fd;
+}
+
+int _send_cmd_to_amd(int cmd)
+{
+       app_pkt_t pkt = {0,};
+       int ret;
+       int fd;
+
+       fd = __create_client_socket(PATH_AMD_SOCK);
+       if (fd < 0)
+               return -1;
+
        pkt.cmd = cmd;
        ret = send(fd, &pkt, sizeof(app_pkt_t), MSG_NOSIGNAL);
        if (ret <= 0) {
@@ -678,54 +681,31 @@ void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *menu_info, int cmd)
 
 int _connect_to_launchpad(int type, int id)
 {
-       struct sockaddr_un addr;
-       int fd = -1;
-       int retry = CONNECT_RETRY_COUNT;
-       int send_ret = -1;
-       int client_pid = getpid();
+       char path[PATH_MAX];
+       int client_pid;
+       int send_ret;
+       int fd;
 
        _D("[launchpad] enter, type: %d", type);
 
-       fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       if (fd < 0) {
-               _E("socket error");
-               goto error;
-       }
-
-       memset(&addr, 0x00, sizeof(struct sockaddr_un));
-       addr.sun_family = AF_UNIX;
-       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d",
+       snprintf(path, sizeof(path), "%s/daemons/%d/%s%d-%d",
                        SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME,
                        type, id);
+       fd = __create_client_socket(path);
+       if (fd < 0)
+               return -1;
 
-       _D("connect to %s", addr.sun_path);
-       while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-               if (errno != ETIMEDOUT || retry <= 0) {
-                       _E("connect error : %d", errno);
-                       goto error;
-               }
-
-               usleep(CONNECT_RETRY_TIME);
-               --retry;
-               _D("re-connect to %s (%d)", addr.sun_path, retry);
-       }
-
+       client_pid = getpid();
        send_ret = send(fd, &client_pid, sizeof(client_pid), MSG_NOSIGNAL);
        _D("send(%d) : %d", client_pid, send_ret);
-
        if (send_ret == -1) {
                _E("send error");
-               goto error;
+               close(fd);
+               return -1;
        }
 
        SECURE_LOGD("[launchpad] done, connect fd: %d", fd);
        return fd;
-
-error:
-       if (fd != -1)
-               close(fd);
-
-       return -1;
 }
 
 #ifdef TIZEN_FEATURE_SET_PERSONALITY_32
@@ -1370,3 +1350,60 @@ int _prepare_id_file(void)
 
        return 0;
 }
+
+static int __send_raw(int fd, int cmd, unsigned char *data, int datalen)
+{
+       app_pkt_t *pkt;
+       int ret;
+
+       pkt = (app_pkt_t *)calloc(1, sizeof(app_pkt_t) + datalen);
+       if (!pkt) {
+               _E("Out of memory");
+               return -ENOMEM;
+       }
+
+       pkt->cmd = cmd;
+       pkt->len = datalen;
+       if (data)
+               memcpy(pkt->data, data, pkt->len);
+
+       ret = _send_pkt_raw(fd, pkt);
+       if (ret < 0) {
+               free(pkt);
+               return -1;
+       }
+
+       free(pkt);
+
+       return 0;
+}
+
+int _send_message_to_logger(const char *tag, const char *format, ...)
+{
+       char fmt[PATH_MAX];
+       char buf[PATH_MAX];
+       va_list ap;
+       int ret;
+       int fd;
+
+       snprintf(buf, sizeof(buf), "%s/daemons/%u/.launchpad-logger-sock",
+                       SOCKET_PATH, getuid());
+       fd = __create_client_socket(buf);
+       if (fd < 0)
+               return -1;
+
+       va_start(ap, format);
+       vsnprintf(fmt, sizeof(fmt), format, ap);
+       va_end(ap);
+
+       snprintf(buf, sizeof(buf), "%s: %s", tag, fmt);
+       ret = __send_raw(fd, 0, (unsigned char *)buf, strlen(buf) + 1);
+       if (ret < 0) {
+               close(fd);
+               return -1;
+       }
+
+       close(fd);
+
+       return 0;
+}
index ba5e8f7..d9b4202 100644 (file)
@@ -368,8 +368,9 @@ do_exec:
                unsetenv("AUL_LOADER_INIT");
                unsetenv("VC_ELM_INIT");
                if (execv(argv[LOADER_ARG_PATH], argv) < 0) {
-                       SECURE_LOGE("execv() failed for file: \"%s\", " \
-                               "error: %d (%s)", argv[LOADER_ARG_PATH], errno,
+                       _send_message_to_logger(argv[LOADER_ARG_PATH],
+                               "Failed to execute a file. error(%d:%s)",
+                               errno,
                                strerror_r(errno, err_str, sizeof(err_str)));
                }
        }