#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
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;
}
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");
_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*/
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;
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");
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) {
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
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;
+}