From d2dc8169c4f2c97e4c6a92505cdb97243e22d9cc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 13 Feb 2010 21:24:45 +0100 Subject: controled config feature and disable auditing feature --- ChangeLog | 4 +++ Makefile | 9 +++++ doc/latrace.txt | 6 ++++ src/Makefile | 3 ++ src/audit-init.c | 33 ++++++++++++++++- src/audit.c | 24 ++++++++++--- src/config.c | 14 +++++++- src/config.h | 13 +++++++ src/ctl.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/latrace.c | 57 +++++++++++++++++++++++++++-- src/run.c | 10 ++++-- 11 files changed, 270 insertions(+), 10 deletions(-) create mode 100644 src/ctl.c diff --git a/ChangeLog b/ChangeLog index 8a3f820..0662f76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-13 Jiri Olsa + * controled config feature + * disable auditing feature + 2010-02-12 Jiri Olsa * refactoring shared config diff --git a/Makefile b/Makefile index e1e713a..e076bf1 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,15 @@ define install fi endef +# install file quietly, arguments: +# 1 - source +# 2 - destination +# 3 - directory to install to +define link + @echo " LN " $(ROOTDIR)$3/$(notdir $2); $(RM) -f $(ROOTDIR)$3/$(notdir $2); \ + ln -s $(ROOTDIR)$3/$(notdir $1) $(ROOTDIR)$3/$(notdir $2) +endef + define remove @echo " CLEAN " $1; $(RM) -rf $1 endef diff --git a/doc/latrace.txt b/doc/latrace.txt index 6e5cb57..492561b 100644 --- a/doc/latrace.txt +++ b/doc/latrace.txt @@ -104,6 +104,12 @@ OPTIONS *-E, --not-follow-exec*:: dont follow exec calls +*-R, --ctl-config*:: + controled config feature + +*-q, --disable*:: + run with disabled auditing (enabled -R) + EXAMPLES -------- diff --git a/src/Makefile b/src/Makefile index 93f01ad..bc625bf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -43,9 +43,11 @@ install:: # latrace binary LATRACE_BIN=latrace +LATRACE_CTL=latrace-ctl LATRACE_LIB=-liberty LATRACE_OBJS=\ src/latrace.o \ + src/ctl.o \ src/config.o \ src/run.o \ src/stats.o \ @@ -64,4 +66,5 @@ $(LATRACE_BIN): $(LATRACE_OBJS) install:: $(call install,$(LATRACE_BIN),$(bindir),755) + $(call link,$(LATRACE_BIN),$(LATRACE_CTL),$(bindir)) diff --git a/src/audit-init.c b/src/audit-init.c index 76e6d21..b5ad366 100644 --- a/src/audit-init.c +++ b/src/audit-init.c @@ -26,11 +26,38 @@ #include #include #include +#include +#include #include "config.h" struct lt_config_audit cfg; +static int init_ctl_config(int fd) +{ + void *sh; + int len; + int page = sysconf(_SC_PAGE_SIZE); + + /* align the shared config length */ + len = sizeof(struct lt_config_shared); + len = (len + page) & ~(page - 1); + + sh = mmap(NULL, len, + PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + + if ((void *) -1 == sh) { + PRINT_VERBOSE(&cfg, 1, + "mmap failed: %s\n", strerror(errno)); + return -1; + } + + /* switching to the mmaped shared config */ + cfg.sh = sh; + return 0; +} + static int read_config(char *dir) { int fd; @@ -42,7 +69,7 @@ static int read_config(char *dir) cfg.dir = dir; sprintf(file, "%s/config", dir); - if (-1 == (fd = open(file, O_RDONLY))) { + if (-1 == (fd = open(file, O_RDWR))) { perror("open failed"); return -1; } @@ -68,6 +95,10 @@ static int read_config(char *dir) } cfg.sh = cfg.sh_storage.sh = &cfg.sh_storage; + + if (lt_sh(&cfg, ctl_config) && init_ctl_config(fd)) + printf("ctl config failed, carring on with standard\n"); + return 0; } diff --git a/src/audit.c b/src/audit.c index 3eaff1d..58b9496 100644 --- a/src/audit.c +++ b/src/audit.c @@ -274,9 +274,17 @@ pltenter(ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, struct link_map *lr = (struct link_map*) *refcook; struct link_map *ld = (struct link_map*) *defcook; - CHECK_PID(sym->st_value); + do { + if (lt_sh(&cfg, disabled)) + break; + + CHECK_PID(sym->st_value); + + sym_entry(symname, lr ? lr->l_name : NULL, + ld ? ld->l_name : NULL, regs); + + } while(0); - sym_entry(symname, lr ? lr->l_name : NULL, ld ? ld->l_name : NULL, regs); *framesizep = lt_sh(&cfg, framesize); return sym->st_value; } @@ -288,8 +296,16 @@ unsigned int pltexit(ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, struct link_map *lr = (struct link_map*) *refcook; struct link_map *ld = (struct link_map*) *defcook; - CHECK_PID(0); + do { + if (lt_sh(&cfg, disabled)) + break; + + CHECK_PID(0); + + sym_exit(symname, lr ? lr->l_name : NULL, + ld ? ld->l_name : NULL, inregs, outregs); + + } while(0); - sym_exit(symname, lr ? lr->l_name : NULL, ld ? ld->l_name : NULL, inregs, outregs); return 0; } diff --git a/src/config.c b/src/config.c index c704183..7cb4672 100644 --- a/src/config.c +++ b/src/config.c @@ -59,6 +59,9 @@ static void usage() printf(" -T, --hide-tid dont display thread id\n"); printf(" -o, --output file store output to file\n"); printf("\n"); + printf(" -R, --ctl-config controled config\n"); + printf(" -q, --disable disable auditing (enables -R)\n"); + printf("\n"); printf(" -v, --verbose verbose output\n"); printf(" -V, --version display version\n"); printf(" -h, --help display help\n"); @@ -140,12 +143,14 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv) {"hide-tid", no_argument, 0, 'T'}, {"not-follow-fork", no_argument, 0, 'F'}, {"not-follow-exec", no_argument, 0, 'E'}, + {"disable", no_argument, 0, 'q'}, + {"ctl-config", no_argument, 0, 'R'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; - c = getopt_long(argc, argv, "+s:l:t:f:vhi:BdISb:cC:y:L:po:a:ADVTFE", + c = getopt_long(argc, argv, "+s:l:t:f:vhi:BdISb:cC:y:L:po:a:ADVTFERq", long_options, &option_index); if (c == -1) @@ -261,6 +266,13 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv) strcpy(lt_sh(cfg, output), optarg); break; + case 'q': + lt_sh(cfg, disabled) = 1; + /* falling through */ + case 'R': + lt_sh(cfg, ctl_config) = 1; + break; + case 'V': version(); break; diff --git a/src/config.h b/src/config.h index 59ddc9b..93e6196 100644 --- a/src/config.h +++ b/src/config.h @@ -101,6 +101,8 @@ struct lt_config_shared { #define LT_ARGS_TAB 10000 struct hsearch_data args_tab; + int disabled; + int ctl_config; int verbose; int timestamp; int debug; @@ -144,6 +146,14 @@ struct lt_config_app { struct lt_thread *iter; }; +struct lt_config_ctl { + struct lt_config_shared *sh; + char *config; + + int set_disabled; + int disabled; +}; + enum { LT_OS_PATH = 1, /* '=' */ LT_OS_PTN, /* '%' */ @@ -345,6 +355,9 @@ struct lt_args_data { int argsd_totlen; }; +/* ctl */ +int main_ctl(int argc, char **argv); + /* global */ int lt_config(struct lt_config_app *cfg, int argc, char **argv); int lt_run(struct lt_config_app *cfg); diff --git a/src/ctl.c b/src/ctl.c new file mode 100644 index 0000000..bbbd7ed --- /dev/null +++ b/src/ctl.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + + +static void usage() NORETURN; +static void usage() +{ + printf("usage: latrace-ctl [-d] config\n\n"); + printf(" -d <0/1> - disable/enable auditing\n"); + printf("\n"); + + exit(1); +} + +static int mmap_config(struct lt_config_ctl *cfg) +{ + struct lt_config_shared* sh; + int page = sysconf(_SC_PAGE_SIZE); + int fd, len; + + if (-1 == (fd = open(cfg->config, O_RDWR))) { + perror("open failed"); + return -1; + } + + /* align the shared config length */ + len = sizeof(struct lt_config_shared); + len = (len + page) & ~(page - 1); + + sh = mmap(NULL, len, + PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + + if ((void *) -1 == sh) { + PRINT_VERBOSE(cfg, 1, + "mmap failed: %s\n", strerror(errno)); + return -1; + } + + cfg->sh = sh; + return 0; +} + +static int config_ctl(struct lt_config_ctl *cfg, int argc, char **argv) +{ + memset(cfg, 0x0, sizeof(*cfg)); + + while (1) { + int c; + int option_index = 0; + static struct option long_options[] = { + {"disable", required_argument, 0, 'd'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "+d:", + long_options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 'd': + cfg->set_disabled = 1; + cfg->disabled = atoi(optarg); + break; + }; /* switch */ + } /* while */ + + if (optind < argc) + cfg->config = argv[optind]; + else { + printf("failed: no config specified\n"); + usage(); + } + + return 0; +} + +int main_ctl(int argc, char **argv) +{ + struct lt_config_ctl cfg; + + if (config_ctl(&cfg, argc, argv)) + return -1; + + if (mmap_config(&cfg)) + return -1; + + printf("controling config %s\n", cfg.config); + + if (cfg.set_disabled) { + printf(" -> disabled = %d\n", cfg.disabled); + lt_sh(&cfg, disabled) = cfg.disabled; + } + + return 0; +} diff --git a/src/latrace.c b/src/latrace.c index 68c36e9..21e1ab8 100644 --- a/src/latrace.c +++ b/src/latrace.c @@ -18,7 +18,7 @@ . */ - +#include #include #include "config.h" @@ -26,8 +26,45 @@ static struct lt_config_app cfg; +enum { + LT_TYPE_UNKNOWN, + LT_TYPE_LATRACE, + LT_TYPE_CTL, +}; -int main(int argc, char **argv) +struct lt_type { + char *name; + int type; +}; + +static struct lt_type types[] = { + { .name = "latrace", .type = LT_TYPE_LATRACE }, + { .name = "latrace-ctl", .type = LT_TYPE_CTL }, +}; + +#define TYPES_COUNT (sizeof(types)/sizeof(struct lt_type)) + +static int get_type(char *name) +{ + int i; + char *cname = strrchr(name, '/'); + + if (!cname) + cname = name; + else + cname++; + + for(i = 0; i < TYPES_COUNT; i++) { + struct lt_type *type = &types[i]; + + if (!strcmp(cname, type->name)) + return type->type; + } + + return LT_TYPE_UNKNOWN; +} + +static int main_latrace(int argc, char **argv) { if (-1 == lt_config(&cfg, argc, argv)) return -1; @@ -43,3 +80,19 @@ int main(int argc, char **argv) return 0; } + +int main(int argc, char **argv) +{ + + switch(get_type(argv[0])) { + + case LT_TYPE_LATRACE: + return main_latrace(argc, argv); + + case LT_TYPE_CTL: + return main_ctl(argc, argv); + } + + printf("wtf..\n"); + return -1; +} diff --git a/src/run.c b/src/run.c index 0a2975e..050a592 100644 --- a/src/run.c +++ b/src/run.c @@ -44,9 +44,14 @@ extern struct timeval tv_program_stop; static int store_config(struct lt_config_app *cfg, char *file) { int fd; + int mode = S_IRUSR; - if (-1 == (fd = open(file, O_CREAT | O_TRUNC | O_RDWR, - S_IRUSR))) { + if (lt_sh(cfg, ctl_config)) { + printf("controled config: %s\n", file); + mode |= S_IWUSR; + } + + if (-1 == (fd = open(file, O_CREAT | O_TRUNC | O_RDWR, mode))) { perror("open failed"); return -1; } @@ -57,6 +62,7 @@ static int store_config(struct lt_config_app *cfg, char *file) } close(fd); + return 0; } -- cgit