bool syscallNotification::installPostFork() { // Get existing flags, add post-fork, and set sysset_t exitset; if (!proc->get_exit_syscalls(&exitset)) return false; praddset(&exitset, SYS_fork); praddset(&exitset, SYS_vfork); if (!proc->set_exit_syscalls(&exitset)) return false; postForkInst = SYSCALL_INSTALLED; return true; }
/* * Gather file descriptors to dump. * Return 0 on success, != 0 on any failure. */ int fdlist(char *str, /* string of filedescriptors */ fileset_t *setp) /* set of boolean flags */ { char *name; int exclude = FALSE; int rc = 0; char *lasts; upcase(str); name = strtok_r(str, sepr, &lasts); if (name != NULL && *name == '!') { /* exclude from set */ exclude = TRUE; if (*++name == '\0') name = strtok_r(NULL, sepr, &lasts); } for (; name; name = strtok_r(NULL, sepr, &lasts)) { int fd; char *next; if (*name == '!') { /* exclude remainder from set */ exclude = TRUE; while (*++name == '!') /* empty */; if (*name == '\0') continue; } fd = strtol(name, &next, 0); if (fd >= 0 && fd < NOFILES_MAX && *next == '\0') { fd++; if (exclude) { prdelset(setp, fd); } else { praddset(setp, fd); } } else if (strcmp(name, "ALL") == 0) { if (exclude) { premptyset(setp); } else { prfillset(setp); } } else { (void) fprintf(stderr, "%s: filedescriptor not in range[0..%d]: %s\n", command, NOFILES_MAX-1, name); rc = -1; } } return (rc); }
bool syscallNotification::installPreExit() { // Get existing flags, add pre-exit, and set sysset_t entryset; if (!proc->get_entry_syscalls(&entryset)) return false; praddset(&entryset, SYS_exit); if (!proc->set_entry_syscalls(&entryset)) return false; preExitInst = SYSCALL_INSTALLED; return true; }
bool syscallNotification::installPostExec() { // Get existing flags, add post-exec, and set sysset_t exitset; if (!proc->get_exit_syscalls(&exitset)) return false; //praddset(&exitset, SYS_exec); praddset(&exitset, SYS_execve); if (!proc->set_exit_syscalls(&exitset)) return false; postExecInst = SYSCALL_INSTALLED; return true; }
bool syscallNotification::removePreExec() { if (!preExecInst) return false; if (proc->hasExited()) { preExecInst = NULL; return true; } // Get existing flags, add pre-exec, and set sysset_t entryset; if (!proc->get_entry_syscalls(&entryset)) return false; //praddset(&entryset, SYS_exec); praddset(&entryset, SYS_execve); if (!proc->set_entry_syscalls(&entryset)) return false; preExecInst = NULL; return true; }
/* * Scan list of syscall names. * Return 0 on success, != 0 on any failure. */ int syslist(char *str, /* string of syscall names */ sysset_t *setp, /* syscall set */ int *fp) /* first-time flag */ { char *name; int exclude = FALSE; int rc = 0; char *lasts; name = strtok_r(str, sepr, &lasts); if (name != NULL && *name == '!') { /* exclude from set */ exclude = TRUE; if (*++name == '\0') name = strtok_r(NULL, sepr, &lasts); } else if (!*fp) { /* first time, clear the set */ premptyset(setp); *fp = TRUE; } for (; name; name = strtok_r(NULL, sepr, &lasts)) { int sys; int sysx; int sysxx; int sys64; char *next; if (*name == '!') { /* exclude remainder from set */ exclude = TRUE; while (*++name == '!') /* empty */; if (*name == '\0') continue; } sys = strtol(name, &next, 0); sysx = sysxx = sys64 = 0; if (sys < 0 || sys > PRMAXSYS || *next != '\0') sys = 0; if (sys == 0) { const struct systable *stp = systable; for (; sys == 0 && stp->nargs >= 0; stp++) if (stp->name && strcmp(stp->name, name) == 0) sys = stp-systable; } if (sys == 0) { const struct sysalias *sap = sysalias; for (; sys == 0 && sap->name; sap++) if (strcmp(sap->name, name) == 0) sys = sap->number; } if (sys > 0 && sys <= PRMAXSYS) { switch (sys) { case SYS_fstatat: /* set both if either */ case SYS_fstatat64: sys = SYS_fstatat; sys64 = SYS_fstatat64; goto def; case SYS_stat: /* set all if either */ case SYS_stat64: sys = SYS_stat; sys64 = SYS_stat64; sysx = SYS_fstatat; sysxx = SYS_fstatat64; goto def; case SYS_lstat: /* set all if either */ case SYS_lstat64: sys = SYS_lstat; sys64 = SYS_lstat64; sysx = SYS_fstatat; sysxx = SYS_fstatat64; goto def; case SYS_fstat: /* set all if either */ case SYS_fstat64: sys = SYS_fstat; sys64 = SYS_fstat64; sysx = SYS_fstatat; sysxx = SYS_fstatat64; goto def; case SYS_getdents: /* set both if either */ case SYS_getdents64: sys = SYS_getdents; sys64 = SYS_getdents64; goto def; case SYS_mmap: /* set both if either */ case SYS_mmap64: sys = SYS_mmap; sys64 = SYS_mmap64; goto def; case SYS_statvfs: /* set both if either */ case SYS_statvfs64: sys = SYS_statvfs; sys64 = SYS_statvfs64; goto def; case SYS_fstatvfs: /* set both if either */ case SYS_fstatvfs64: sys = SYS_fstatvfs; sys64 = SYS_fstatvfs64; goto def; case SYS_setrlimit: /* set both if either */ case SYS_setrlimit64: sys = SYS_setrlimit; sys64 = SYS_setrlimit64; goto def; case SYS_getrlimit: /* set both if either */ case SYS_getrlimit64: sys = SYS_getrlimit; sys64 = SYS_getrlimit64; goto def; case SYS_pread: /* set both if either */ case SYS_pread64: sys = SYS_pread; sys64 = SYS_pread64; goto def; case SYS_pwrite: /* set both if either */ case SYS_pwrite64: sys = SYS_pwrite; sys64 = SYS_pwrite64; goto def; case SYS_openat: /* set all if any */ case SYS_openat64: case SYS_open: case SYS_open64: sys = SYS_openat; sys64 = SYS_openat64; sysx = SYS_open; sysxx = SYS_open64; goto def; case SYS_forksys: /* set both if either */ case SYS_vfork: sysx = SYS_forksys; sys = SYS_vfork; goto def; case SYS_sigprocmask: /* set both if either */ case SYS_lwp_sigmask: sysx = SYS_sigprocmask; sys = SYS_lwp_sigmask; goto def; case SYS_lseek: /* set both if either */ case SYS_llseek: sysx = SYS_lseek; sys = SYS_llseek; goto def; case SYS_rename: /* set both */ sysx = SYS_renameat; goto def; case SYS_link: /* set both */ sysx = SYS_linkat; goto def; case SYS_unlink: /* set both */ case SYS_rmdir: /* set both */ sysx = SYS_unlinkat; goto def; case SYS_symlink: /* set both */ sysx = SYS_symlinkat; goto def; case SYS_readlink: /* set both */ sysx = SYS_readlinkat; goto def; case SYS_chmod: /* set both */ case SYS_fchmod: /* set both */ sysx = SYS_fchmodat; goto def; case SYS_chown: /* set both */ case SYS_lchown: /* set both */ case SYS_fchown: /* set both */ sysx = SYS_fchownat; goto def; case SYS_mkdir: /* set both */ sysx = SYS_mkdirat; goto def; case SYS_mknod: /* set both */ sysx = SYS_mknodat; goto def; case SYS_access: /* set both */ sysx = SYS_faccessat; goto def; default: def: if (exclude) { prdelset(setp, sys); if (sysx) prdelset(setp, sysx); if (sysxx) prdelset(setp, sysxx); if (sys64) prdelset(setp, sys64); } else { praddset(setp, sys); if (sysx) praddset(setp, sysx); if (sysxx) praddset(setp, sysxx); if (sys64) praddset(setp, sys64); } break; } } else if (strcmp(name, "all") == 0 || strcmp(name, "ALL") == 0) { if (exclude) { premptyset(setp); } else { prfillset(setp); } } else { (void) fprintf(stderr, "%s: unrecognized syscall: %s\n", command, name); rc = -1; } } return (rc); }
/* * List of faults to trace. * return 0 on success, != 0 on any failure. */ int fltlist(char *str, /* string of fault names */ fltset_t *setp, /* fault set */ int *fp) /* first-time flag */ { char *name; int exclude = FALSE; int rc = 0; char *lasts; upcase(str); name = strtok_r(str, sepr, &lasts); if (name != NULL && *name == '!') { /* exclude from set */ exclude = TRUE; if (*++name == '\0') name = strtok_r(NULL, sepr, &lasts); } else if (!*fp) { /* first time, clear the set */ premptyset(setp); *fp = TRUE; } for (; name; name = strtok_r(NULL, sepr, &lasts)) { int flt; char *next; if (*name == '!') { /* exclude remainder from set */ exclude = TRUE; while (*++name == '!') /* empty */; if (*name == '\0') continue; } flt = strtol(name, &next, 0); if (flt <= 0 || flt > PRMAXFAULT || *next != '\0') { for (flt = 1; flt <= PRMAXFAULT; flt++) { char fname[32]; if (proc_fltname(flt, fname, sizeof (fname)) == NULL) continue; if (strcmp(fname, name) == 0 || strcmp(fname+3, name) == 0) break; } if (flt > PRMAXFAULT) flt = 0; } if (flt > 0 && flt <= PRMAXFAULT) { if (exclude) { prdelset(setp, flt); } else { praddset(setp, flt); } } else if (strcmp(name, "ALL") == 0) { if (exclude) { premptyset(setp); } else { prfillset(setp); } } else { (void) fprintf(stderr, "%s: unrecognized fault name/number: %s\n", command, name); rc = -1; } } return (rc); }
/* * List of signals to trace. * Return 0 on success, != 0 on any failure. */ int siglist(private_t *pri, char *str, /* string of signal names */ sigset_t *setp, /* signal set */ int *fp) /* first-time flag */ { char *name; int exclude = FALSE; int rc = 0; char *lasts; upcase(str); name = strtok_r(str, sepr, &lasts); if (name != NULL && *name == '!') { /* exclude from set */ exclude = TRUE; if (*++name == '\0') name = strtok_r(NULL, sepr, &lasts); } else if (!*fp) { /* first time, clear the set */ premptyset(setp); *fp = TRUE; } for (; name; name = strtok_r(NULL, sepr, &lasts)) { int sig; char *next; if (*name == '!') { /* exclude remainder from set */ exclude = TRUE; while (*++name == '!') /* empty */; if (*name == '\0') continue; } sig = strtol(name, &next, 0); if (sig <= 0 || sig > PRMAXSIG || *next != '\0') { for (sig = 1; sig <= PRMAXSIG; sig++) { const char *sname = rawsigname(pri, sig); if (sname == NULL) continue; if (strcmp(sname, name) == 0 || strcmp(sname+3, name) == 0) break; } if (sig > PRMAXSIG) sig = 0; } if (sig > 0 && sig <= PRMAXSIG) { if (exclude) { prdelset(setp, sig); } else { praddset(setp, sig); } } else if (strcmp(name, "ALL") == 0) { if (exclude) { premptyset(setp); } else { prfillset(setp); } } else { (void) fprintf(stderr, "%s: unrecognized signal name/number: %s\n", command, name); rc = -1; } } return (rc); }
static void init_proc() { int pfd; char procname[PROCSIZE]; sigset_t sigset; fltset_t fltset; sysset_t sysset; long oper, pflags; struct iovec piov[2]; /* * open our own /proc file and set tracing flags */ (void) snprintf(procname, PROCSIZE, "/proc/%d/ctl", EC_SWORD(getpid())); if ((pfd = open(procname, O_WRONLY)) < 0) { (void) fprintf(stderr, "can't open %s\n", procname); exit(1); } /* * inherit on fork, and kill-on-last-close */ oper = PCSET; piov[0].iov_base = (caddr_t)(&oper); piov[0].iov_len = sizeof (oper); pflags = PR_FORK; piov[1].iov_base = (caddr_t)&pflags; piov[1].iov_len = sizeof (pflags); if (writev(pfd, piov, 2) == -1) perr("init_proc: PCSET"); /* * no signal tracing */ oper = PCSTRACE; premptyset(&sigset); piov[1].iov_base = (caddr_t)&sigset; piov[1].iov_len = sizeof (sigset); if (writev(pfd, piov, 2) == -1) perr("PCSTRACE"); /* * no fault tracing */ oper = PCSFAULT; premptyset(&fltset); piov[1].iov_base = (caddr_t)&fltset; piov[1].iov_len = sizeof (fltset); if (writev(pfd, piov, 2) == -1) perr("PCSFAULT"); /* * no syscall tracing */ oper = PCSENTRY; premptyset(&sysset); piov[1].iov_base = (caddr_t)&sysset; piov[1].iov_len = sizeof (sysset); if (writev(pfd, piov, 2) == -1) perr("PSENTRY"); /* * except exit from exec() or execve() */ oper = PCSEXIT; premptyset(&sysset); praddset(&sysset, SYS_execve); if (writev(pfd, piov, 2) == -1) perr("PCSEXIT"); (void) close(pfd); }