Browse Source

Filter out unwanted proc events

Use Linux Socket Filtering to let the kernel filter out the events
we are not interested in.
develop
Damien Goutte-Gattat 8 years ago
parent
commit
936cb457fa
  1. 1
      configure.ac
  2. 56
      src/wait4pid.c

1
configure.ac

@ -23,6 +23,7 @@ backend="kill"
AC_CHECK_HEADERS([linux/netlink.h],
[backend=Netlink])
AM_CONDITIONAL([HAVE_NETLINK], [test x$ac_cv_header_linux_netlink_h = xyes])
AC_CHECK_HEADERS([linux/filter.h])
dnl Output files
AC_CONFIG_FILES([Makefile wait4.1 lib/Makefile src/Makefile])

56
src/wait4pid.c

@ -127,6 +127,57 @@ wait4pid_init(void)
return 0;
}
#ifdef HAVE_LINUX_FILTER_H
#include <linux/filter.h>
#include <arpa/inet.h>
static int
set_filter(int sock, pid_t *pids, size_t len)
{
struct sock_fprog flt;
int i, j = 0;
flt.len = 5 + len;
if ( (flt.filter = calloc(sizeof(struct sock_filter), flt.len)) == NULL )
return -1;
/* Block the packet if proc_event.what != PROC_EVENT_EXIT */
flt.filter[j].code = BPF_LD+BPF_W+BPF_ABS;
flt.filter[j++].k = 36; /* proc_event.what */
flt.filter[j].code = BPF_JMP+BPF_JEQ+BPF_K;
flt.filter[j].k = htonl(PROC_EVENT_EXIT);
flt.filter[j].jt = 0; /* continue */
flt.filter[j++].jf = 1 + len; /* jump to the "block" instruction */
/* Get the process identifier */
flt.filter[j].code = BPF_LD+BPF_W+BPF_ABS;
flt.filter[j++].k = 52; /* proc_event.event_data.exit.process_pid */
for ( i = 0; i < len; i++ ) {
/* Accept the packet if its pid matches pids[i]. */
flt.filter[j].code = BPF_JMP+BPF_JEQ+BPF_K;
flt.filter[j].k = htonl(pids[i]);
flt.filter[j].jt = len - i; /* jump to the "accept" instruction */
flt.filter[j++].jf = 0; /* continue */
}
/* No match, block the packet. */
flt.filter[j].code = BPF_RET+BPF_K;
flt.filter[j++].k = 0;
/* Accept the packet. */
flt.filter[j].code = BPF_RET+BPF_K;
flt.filter[j++].k = (uint)-1;
i = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &flt, sizeof(flt));
free(flt.filter);
return i;
}
#endif
int
wait4all(pid_t *pids, size_t len)
{
@ -145,6 +196,11 @@ wait4all(pid_t *pids, size_t len)
return -1;
}
#ifdef HAVE_LINUX_FILTER_H
if ( set_filter(sock, pids, len) == -1 )
return -1;
#endif
nproc = len;
while ( nproc > 0 ) {
if ( do_recv(sock, buf, sizeof(buf), 0) <= 0 )

Loading…
Cancel
Save