diff options
Diffstat (limited to 'gg_trackproc/gg_trackproc.c')
-rw-r--r-- | gg_trackproc/gg_trackproc.c | 491 |
1 files changed, 248 insertions, 243 deletions
diff --git a/gg_trackproc/gg_trackproc.c b/gg_trackproc/gg_trackproc.c index 8706849..7bb995f 100644 --- a/gg_trackproc/gg_trackproc.c +++ b/gg_trackproc/gg_trackproc.c @@ -34,242 +34,246 @@ int loglevel = 0; static char* get_current_date() { - time_t ts; - struct tm *tm; - static char date_buf[64]; - - time(&ts); - tm = localtime(&ts); - strftime(date_buf, 64, "%b %d %X", tm); - return date_buf; + time_t ts; + struct tm *tm; + static char date_buf[64]; + + time(&ts); + tm = localtime(&ts); + strftime(date_buf, 64, "%b %d %X", tm); + return date_buf; } static int get_proc_infos(int pid, char **cmd) { - char path[128]; - char readbuf[1024]; - int size; - FILE *file; - char *comm, *tmpptr; - - //if ((pid = (pid_t) atoi(de->d_name)) == 0) { - snprintf(path, sizeof(path), "%s/%d/stat", PROC_BASE, pid); - if ((file = fopen(path, "r")) == NULL) { - warn("Error: PID %d: cannot open %s\n", pid, path); - return -1; - } - size = fread(readbuf, 1, sizeof(readbuf), file); - if (ferror(file) != 0) { - warn("Error: PID %d: error reading %s", pid, path); - return -1; - } - readbuf[size] = 0; - /* commands may have spaces or ) in them. - * so don't trust anything from the ( to the last ) */ - if (!(comm = strchr(readbuf, '(')) - || !(tmpptr = strrchr(comm, ')'))) { - warn("Error: PID %d: could not parse %s", pid, path); - return -1; - } - ++comm; - *tmpptr = 0; - /* We now have readbuf with pid and cmd, and tmpptr+2 - * with the rest */ - fclose(file); - - *cmd = comm; - return 0; + char path[128]; + char readbuf[1024]; + int size; + FILE *file; + char *comm, *tmpptr; + + //if ((pid = (pid_t) atoi(de->d_name)) == 0) { + snprintf(path, sizeof(path), "%s/%d/stat", PROC_BASE, pid); + if ((file = fopen(path, "r")) == NULL) { + warn("Error: PID %d: cannot open %s\n", pid, path); + return -1; + } + size = fread(readbuf, 1, sizeof(readbuf), file); + if (ferror(file) != 0) { + warn("Error: PID %d: error reading %s", pid, path); + return -1; + } + readbuf[size] = 0; + /* commands may have spaces or ) in them. + * so don't trust anything from the ( to the last ) */ + if (!(comm = strchr(readbuf, '(')) + || !(tmpptr = strrchr(comm, ')'))) { + warn("Error: PID %d: could not parse %s", pid, path); + return -1; + } + ++comm; + *tmpptr = 0; + /* We now have readbuf with pid and cmd, and tmpptr+2 + * with the rest */ + fclose(file); + + *cmd = comm; + return 0; } /* * connect to netlink * returns netlink socket, or -1 on error */ -static int nl_connect() +static int +nl_connect() { - int rc; - int nl_sock; - struct sockaddr_nl sa_nl; - - nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); - if (nl_sock == -1) { - perror("socket"); - return -1; - } - - sa_nl.nl_family = AF_NETLINK; - sa_nl.nl_groups = CN_IDX_PROC; - sa_nl.nl_pid = getpid(); - - rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl)); - if (rc == -1) { - perror("bind"); - close(nl_sock); - return -1; - } - - return nl_sock; + int rc; + int nl_sock; + struct sockaddr_nl sa_nl; + + nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); + if (nl_sock == -1) { + perror("socket"); + return -1; + } + + sa_nl.nl_family = AF_NETLINK; + sa_nl.nl_groups = CN_IDX_PROC; + sa_nl.nl_pid = getpid(); + + rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl)); + if (rc == -1) { + perror("bind"); + close(nl_sock); + return -1; + } + + return nl_sock; } /* * subscribe on proc events (process notifications) */ -static int set_proc_ev_listen(int nl_sock, bool enable) +static int +set_proc_ev_listen(int nl_sock, bool enable) { - int rc; - struct __attribute__ ((aligned(NLMSG_ALIGNTO))) { - struct nlmsghdr nl_hdr; - struct __attribute__ ((__packed__)) { - struct cn_msg cn_msg; - enum proc_cn_mcast_op cn_mcast; - }; - } nlcn_msg; - - memset(&nlcn_msg, 0, sizeof(nlcn_msg)); - nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg); - nlcn_msg.nl_hdr.nlmsg_pid = getpid(); - nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE; - - nlcn_msg.cn_msg.id.idx = CN_IDX_PROC; - nlcn_msg.cn_msg.id.val = CN_VAL_PROC; - nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op); - - nlcn_msg.cn_mcast = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE; - - rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0); - if (rc == -1) { - perror("netlink send"); - return -1; - } - - return 0; + int rc; + struct __attribute__ ((aligned(NLMSG_ALIGNTO))) { + struct nlmsghdr nl_hdr; + struct __attribute__ ((__packed__)) { + struct cn_msg cn_msg; + enum proc_cn_mcast_op cn_mcast; + }; + } nlcn_msg; + + memset(&nlcn_msg, 0, sizeof(nlcn_msg)); + nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg); + nlcn_msg.nl_hdr.nlmsg_pid = getpid(); + nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE; + + nlcn_msg.cn_msg.id.idx = CN_IDX_PROC; + nlcn_msg.cn_msg.id.val = CN_VAL_PROC; + nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op); + + nlcn_msg.cn_mcast = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE; + + rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0); + if (rc == -1) { + perror("netlink send"); + return -1; + } + + return 0; } -void cb_nl(evutil_socket_t fd, short what, void *arg) +void +cb_nl(evutil_socket_t fd, short what, void *arg) { - int rc; - struct __attribute__ ((aligned(NLMSG_ALIGNTO))) { - struct nlmsghdr nl_hdr; - struct __attribute__ ((__packed__)) { - struct cn_msg cn_msg; - struct proc_event proc_ev; - }; - } nlcn_msg; - static char *cmd; - struct gg_packet pkt; - - rc = recv(fd, &nlcn_msg, sizeof(nlcn_msg), 0); - if (rc == 0) { - /* shutdown? */ - if (loglevel) - printf("%s: stop listening to netlink events\n", - get_current_date()); - event_base_loopexit(ev_base, NULL); - return; - } else if (rc == -1) { - if (errno == EINTR) - return; - perror("netlink recv"); - event_base_loopexit(ev_base, NULL); - return; - } - - pkt.type = 0; - pkt.ver = PACKET_VERSION; - /* see /usr/include/linux/cn_proc.h for struct proc_event */ - switch (nlcn_msg.proc_ev.what) { - case PROC_EVENT_NONE: - /* XXX what is this event for ? - * if (loglevel) - * printf("%s: start listening to netlink events...\n", - * get_current_date()); */ - break; - - case PROC_EVENT_FORK: - get_proc_infos(nlcn_msg.proc_ev.event_data.fork.parent_pid, - &cmd); - if ((nlcn_msg.proc_ev.event_data.fork.child_tgid - != nlcn_msg.proc_ev.event_data.fork.child_pid)) { - if (loglevel) - printf("%s: fork %s %d -> %d tid %d\n", - get_current_date(), - cmd, - nlcn_msg.proc_ev.event_data.fork.parent_pid, - nlcn_msg.proc_ev.event_data.fork.child_pid, - nlcn_msg.proc_ev.event_data.fork.child_tgid); - } else { - if (loglevel) - printf("%s: fork %s %d -> %d\n", - get_current_date(), - cmd, - nlcn_msg.proc_ev.event_data.fork.parent_pid, - nlcn_msg.proc_ev.event_data.fork.child_pid); - } - pkt.type = PACKET_FORK; - pkt.fork_pid = nlcn_msg.proc_ev.event_data.fork.parent_pid; - pkt.fork_ppid = nlcn_msg.proc_ev.event_data.fork.parent_pid; - pkt.fork_cpid = nlcn_msg.proc_ev.event_data.fork.child_pid; - pkt.fork_tgid = nlcn_msg.proc_ev.event_data.fork.child_tgid; - break; - - case PROC_EVENT_EXEC: - get_proc_infos(nlcn_msg.proc_ev.event_data.exec.process_pid, - &cmd); - if (loglevel) - printf("%s: exec %d -> %s\n", - get_current_date(), - nlcn_msg.proc_ev.event_data.exec.process_pid, - cmd); - pkt.type = PACKET_EXEC; - pkt.exec_pid = nlcn_msg.proc_ev.event_data.fork.parent_pid; - pkt.exec_cmdlen = strnlen(cmd, GG_PKTARG_MAX); - strncpy((char *)pkt.exec_cmd, cmd, GG_PKTARG_MAX); - break; + int rc; + struct __attribute__ ((aligned(NLMSG_ALIGNTO))) { + struct nlmsghdr nl_hdr; + struct __attribute__ ((__packed__)) { + struct cn_msg cn_msg; + struct proc_event proc_ev; + }; + } nlcn_msg; + static char *cmd; + struct gg_packet pkt; + + rc = recv(fd, &nlcn_msg, sizeof(nlcn_msg), 0); + if (rc == 0) { + /* shutdown? */ + if (loglevel) + printf("%s: stop listening to netlink events\n", + get_current_date()); + event_base_loopexit(ev_base, NULL); + return; + } else if (rc == -1) { + if (errno == EINTR) + return; + perror("netlink recv"); + event_base_loopexit(ev_base, NULL); + return; + } + + pkt.type = 0; + pkt.ver = PACKET_VERSION; + /* see /usr/include/linux/cn_proc.h for struct proc_event */ + switch (nlcn_msg.proc_ev.what) { + case PROC_EVENT_NONE: + /* XXX what is this event for ? + * if (loglevel) + * printf("%s: start listening to netlink events...\n", + * get_current_date()); */ + break; + + case PROC_EVENT_FORK: + get_proc_infos(nlcn_msg.proc_ev.event_data.fork.parent_pid, + &cmd); + if ((nlcn_msg.proc_ev.event_data.fork.child_tgid + != nlcn_msg.proc_ev.event_data.fork.child_pid)) { + if (loglevel) + printf("%s: fork %s %d -> %d tid %d\n", + get_current_date(), + cmd, + nlcn_msg.proc_ev.event_data.fork.parent_pid, + nlcn_msg.proc_ev.event_data.fork.child_pid, + nlcn_msg.proc_ev.event_data.fork.child_tgid); + } else { + if (loglevel) + printf("%s: fork %s %d -> %d\n", + get_current_date(), + cmd, + nlcn_msg.proc_ev.event_data.fork.parent_pid, + nlcn_msg.proc_ev.event_data.fork.child_pid); + } + pkt.type = PACKET_FORK; + pkt.fork_pid = nlcn_msg.proc_ev.event_data.fork.parent_pid; + pkt.fork_ppid = nlcn_msg.proc_ev.event_data.fork.parent_pid; + pkt.fork_cpid = nlcn_msg.proc_ev.event_data.fork.child_pid; + pkt.fork_tgid = nlcn_msg.proc_ev.event_data.fork.child_tgid; + break; + + case PROC_EVENT_EXEC: + get_proc_infos(nlcn_msg.proc_ev.event_data.exec.process_pid, + &cmd); + if (loglevel) + printf("%s: exec %d -> %s\n", + get_current_date(), + nlcn_msg.proc_ev.event_data.exec.process_pid, + cmd); + pkt.type = PACKET_EXEC; + pkt.exec_pid = nlcn_msg.proc_ev.event_data.fork.parent_pid; + pkt.exec_cmdlen = strnlen(cmd, GG_PKTARG_MAX); + strncpy((char *)pkt.exec_cmd, cmd, GG_PKTARG_MAX); + break; #if 0 - case PROC_EVENT_UID: - if (loglevel) - printf("uid change: tid=%d pid=%d from %d to %d\n", - nlcn_msg.proc_ev.event_data.id.process_pid, - nlcn_msg.proc_ev.event_data.id.process_tgid, - nlcn_msg.proc_ev.event_data.id.r.ruid, - nlcn_msg.proc_ev.event_data.id.e.euid); - break; - - case PROC_EVENT_GID: - if (loglevel) - printf("gid change: tid=%d pid=%d from %d to %d\n", - nlcn_msg.proc_ev.event_data.id.process_pid, - nlcn_msg.proc_ev.event_data.id.process_tgid, - nlcn_msg.proc_ev.event_data.id.r.rgid, - nlcn_msg.proc_ev.event_data.id.e.egid); - break; + case PROC_EVENT_UID: + if (loglevel) + printf("uid change: tid=%d pid=%d from %d to %d\n", + nlcn_msg.proc_ev.event_data.id.process_pid, + nlcn_msg.proc_ev.event_data.id.process_tgid, + nlcn_msg.proc_ev.event_data.id.r.ruid, + nlcn_msg.proc_ev.event_data.id.e.euid); + break; + + case PROC_EVENT_GID: + if (loglevel) + printf("gid change: tid=%d pid=%d from %d to %d\n", + nlcn_msg.proc_ev.event_data.id.process_pid, + nlcn_msg.proc_ev.event_data.id.process_tgid, + nlcn_msg.proc_ev.event_data.id.r.rgid, + nlcn_msg.proc_ev.event_data.id.e.egid); + break; #endif - case PROC_EVENT_EXIT: - if (loglevel) - printf("exit: tid=%d pid=%d exit_code=%d\n", - nlcn_msg.proc_ev.event_data.exit.process_pid, - nlcn_msg.proc_ev.event_data.exit.process_tgid, - nlcn_msg.proc_ev.event_data.exit.exit_code); - pkt.type = PACKET_EXIT; - pkt.exit_pid = nlcn_msg.proc_ev.event_data.exit.process_pid; - pkt.exit_tgid = nlcn_msg.proc_ev.event_data.exit.process_tgid; - pkt.exit_ecode = nlcn_msg.proc_ev.event_data.exit.exit_code; - break; - - default: - if (loglevel) - printf("unhandled proc event\n"); - break; - } - - if (pkt.type != 0) - gg_client_send(ggcli, &pkt); + case PROC_EVENT_EXIT: + if (loglevel) + printf("exit: tid=%d pid=%d exit_code=%d\n", + nlcn_msg.proc_ev.event_data.exit.process_pid, + nlcn_msg.proc_ev.event_data.exit.process_tgid, + nlcn_msg.proc_ev.event_data.exit.exit_code); + pkt.type = PACKET_EXIT; + pkt.exit_pid = nlcn_msg.proc_ev.event_data.exit.process_pid; + pkt.exit_tgid = nlcn_msg.proc_ev.event_data.exit.process_tgid; + pkt.exit_ecode = nlcn_msg.proc_ev.event_data.exit.exit_code; + break; + + default: + if (loglevel) + printf("unhandled proc event\n"); + break; + } + + if (pkt.type != 0) + gg_client_send(ggcli, &pkt); } -static void on_sigint(int unused) +static void +on_sigint(int unused) { - event_base_loopexit(ev_base, NULL); + event_base_loopexit(ev_base, NULL); } #if defined(__OPENBSD__) @@ -279,17 +283,18 @@ void #endif usage(void) { - extern char *__progname; + extern char *__progname; - fprintf(stderr, "usage: %s [-vi]", __progname); - exit(1); + fprintf(stderr, "usage: %s [-vi]", __progname); + exit(1); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { - struct event *ev_nl; - int nl_sock; - int rc = EXIT_SUCCESS; + struct event *ev_nl; + int nl_sock; + int rc = EXIT_SUCCESS; int op; while ((op = getopt(argc, argv, "hv")) != -1) { @@ -309,38 +314,38 @@ int main(int argc, char **argv) if (geteuid() != 0) errx(1, "must be root"); - signal(SIGINT, &on_sigint); - siginterrupt(SIGINT, true); + signal(SIGINT, &on_sigint); + siginterrupt(SIGINT, true); - gg_verbosity_set(loglevel); + gg_verbosity_set(loglevel); - ev_base = event_base_new(); - ggcli = gg_client_connect(ev_base, "127.0.0.1", GLOUGLOU_PROBE_DEFAULT_PORT, - NULL, NULL, NULL); + ev_base = event_base_new(); + ggcli = gg_client_connect(ev_base, "127.0.0.1", GLOUGLOU_PROBE_DEFAULT_PORT, + NULL, NULL, NULL); - nl_sock = nl_connect(); - if (nl_sock == -1) - exit(EXIT_FAILURE); - rc = set_proc_ev_listen(nl_sock, true); - if (rc == -1) { - rc = EXIT_FAILURE; - goto out; - } - rc = set_proc_ev_listen(nl_sock, true); - if (rc == -1) { - rc = EXIT_FAILURE; - goto out; - } - ev_nl = event_new(ev_base, nl_sock, EV_READ|EV_PERSIST, cb_nl, NULL); - event_add(ev_nl, NULL); + nl_sock = nl_connect(); + if (nl_sock == -1) + exit(EXIT_FAILURE); + rc = set_proc_ev_listen(nl_sock, true); + if (rc == -1) { + rc = EXIT_FAILURE; + goto out; + } + rc = set_proc_ev_listen(nl_sock, true); + if (rc == -1) { + rc = EXIT_FAILURE; + goto out; + } + ev_nl = event_new(ev_base, nl_sock, EV_READ|EV_PERSIST, cb_nl, NULL); + event_add(ev_nl, NULL); - droppriv(GG_TRACKPROC_USER, 1, CHROOT_PATH); + droppriv(GG_TRACKPROC_USER, 1, CHROOT_PATH); - event_base_dispatch(ev_base); + event_base_dispatch(ev_base); - set_proc_ev_listen(nl_sock, false); + set_proc_ev_listen(nl_sock, false); out: - close(nl_sock); - exit(rc); + close(nl_sock); + exit(rc); } |