#define __KERNEL__ #include #undef __KERNEL__ #include #include #include #include #include #include #include #include #include "constable.h" #include "language.h" #include "runtime.h" #include "cmds.h" int print_name(char *s, files_t * f); int conv_err = 0; const int vt_int = VT_INT; const int vt_str = VT_STR; #define PSG_CONS(ttt,kde,co,vtyp) \ var_t *psg_##co(struct med_s *m,var_t *set) \ { static var_t v; \ udata d; \ d=(udata)(m->##kde##co); \ if( set && set->typ==##vtyp ) \ m->##kde##co=(##ttt)(set->d); \ v.typ=##vtyp; v.d=d; \ return(&v); \ } #define PSG_IPCONS(typ,co) PSG_CONS(typ,proc.,co,vt_int) PSG_IPCONS(pid_t, pid) PSG_IPCONS(uid_t, uid) PSG_IPCONS(uid_t, euid) PSG_IPCONS(uid_t, suid) PSG_IPCONS(uid_t, fsuid) PSG_IPCONS(gid_t, gid) PSG_IPCONS(gid_t, egid) PSG_IPCONS(gid_t, sgid) PSG_IPCONS(gid_t, fsgid) PSG_IPCONS(uid_t, luid) /* Read Only */ PSG_CONS(__u32, proc.mp., med_vs, vt_int) PSG_CONS(__u32, proc.mp., med_vs_s, vt_int) PSG_CONS(__u32, proc.mp., med_vs_r, vt_int) PSG_CONS(__u32, proc.mp., med_vs_w, vt_int) PSG_CONS(__u32, proc.mp., med_user, vt_int) PSG_CONS(__u16, proc.mp., med_act, vt_int) PSG_CONS(__u16, proc.mp., med_iact, vt_int) PSG_IPCONS(__u32, cap_effective) PSG_IPCONS(__u32, cap_inheritable) PSG_IPCONS(__u32, cap_permitted) /* PSG_CONS(char*,,redirect,VT_STR) */ PSG_CONS(char *,, data, vt_str) PSG_CONS(int,, answer, vt_int) PSG_CONS(int,, apply_mode, vt_int) PSG_CONS(__u32,, action, vt_int) /* Read Only */ PSG_CONS(__u32,, info1, vt_int) /* Read Only */ PSG_CONS(__u32,, info2, vt_int) /* Read Only */ #define PSG_TRACE(n) \ var_t *psg_trace##n(struct med_s *m,var_t *set) \ { static var_t v; \ udata d; \ d=(udata)(m->trace_arg[##n-1]); \ if( set && set->typ==VT_INT ) \ m->trace_arg[##n-1]=(udata)(set->d); \ v.typ=VT_INT; v.d=d; \ return(&v); \ } PSG_TRACE(1) PSG_TRACE(2) PSG_TRACE(3) PSG_TRACE(4) PSG_TRACE(5) #define PSG_TARG_GCONS(ttt,kde,co,vtyp) \ var_t *psg_target_##co(struct med_s *m,var_t *set) \ { static var_t v; \ udata d; \ if( m->target==NULL ) \ { v.typ=VT_UNDEF; return(&v); }\ d=(udata)(m->target->##kde##co); \ if( set && set->typ==##vtyp ) \ m->target->##kde##co=(##ttt)(set->d); \ v.typ=##vtyp; v.d=d; \ return(&v); \ } #define PSG_TARG_CONS(typ,co) PSG_TARG_GCONS(typ,,co,vt_int) PSG_TARG_CONS(pid_t, pid) PSG_TARG_CONS(uid_t, uid) PSG_TARG_CONS(uid_t, euid) PSG_TARG_CONS(uid_t, suid) PSG_TARG_CONS(uid_t, fsuid) PSG_TARG_CONS(gid_t, gid) PSG_TARG_CONS(gid_t, egid) PSG_TARG_CONS(uid_t, luid) /* Read Only */ PSG_TARG_CONS(__u32, cap_effective) PSG_TARG_CONS(__u32, cap_inheritable) PSG_TARG_CONS(__u32, cap_permitted) PSG_TARG_GCONS(__u32, mp., med_vs, vt_int) PSG_TARG_GCONS(__u32, mp., med_vs_s, vt_int) PSG_TARG_GCONS(__u32, mp., med_vs_r, vt_int) PSG_TARG_GCONS(__u32, mp., med_vs_w, vt_int) PSG_TARG_GCONS(__u32, mp., med_user, vt_int) PSG_TARG_GCONS(__u16, mp., med_act, vt_int) PSG_TARG_GCONS(__u16, mp., med_iact, vt_int) #define PSG_INODE_CONS(ttt,kde,co) \ var_t *psg_inode_##co(struct med_s *m,var_t *set) \ { static var_t v; \ udata d; \ if( m->inode==NULL ) \ { v.typ=VT_UNDEF; return(&v); }\ d=(udata)(m->inode->##kde##co); \ if( set && set->typ==VT_INT ) \ m->inode->##kde##co=(##ttt)(set->d); \ v.typ=VT_INT; v.d=d; \ return(&v); \ } PSG_INODE_CONS(uid_t,, uid); PSG_INODE_CONS(gid_t,, gid); PSG_INODE_CONS(umode_t,, mode); PSG_INODE_CONS(__u32, mi., med_vs); PSG_INODE_CONS(__u16, mi., med_act); PSG_INODE_CONS(u_long, mi., cinfo); var_t *psg_constable_pid(struct med_s *m, var_t * set) { static var_t v; v.d = (udata) getpid(); v.typ = VT_INT; return &v; } /* ----------- commands -------------- */ udata cmd_redirect(struct med_s * m, var_t * arg, int n) { if (n > 0 && arg->typ == VT_STR) m->redirect = (char *) (arg->d); if (m->redirect) return 1; return 0; } #ifdef CONFIG_MEDUSA_SYSCALL udata cmd_trace_on(struct med_s * m, var_t * arg, int n) { while (n > 0) { if (arg->typ == VT_INT) m->proc.mp.med_syscall[(arg->d) >> 5] |= ((__u32) 1 << ((arg->d) & 0x1f)); else if (arg->typ == VT_STR && !strcmp((char *) (arg->d), "all")) { int i; for (i = 0; i < NR_syscalls / 32; i++) m->proc.mp.med_syscall[i] = ~0; } arg++; n--; } return 1; } udata cmd_trace_off(struct med_s * m, var_t * arg, int n) { while (n > 0) { if (arg->typ == VT_INT) m->proc.mp.med_syscall[(arg->d) >> 5] &= ~((__u32) 1 << ((arg->d) & 0x1f)); else if (arg->typ == VT_STR && !strcmp((char *) (arg->d), "all")) { int i; for (i = 0; i < NR_syscalls / 32; i++) m->proc.mp.med_syscall[i] = 0; } arg++; n--; } return 1; } #endif /* lpeek address variable */ udata cmd_lpeek(struct med_s * m, var_t * arg, int n) { int fd; char s[1024]; long l; if (n != 2 || arg[0].typ != VT_INT || (arg[1].typ != VT_INT && arg[1].typ != VT_UNDEF)) return 0; sprintf(s, "/proc/%d/mem", m->proc.pid); if ((fd = open(s, O_RDONLY)) < 0) return 0; //printf("PEEK (0x%.8x)\n",arg[0].d); lseek(fd, arg[0].d, SEEK_SET); if (read(fd, &l, sizeof(long)) != sizeof(long)) { close(fd); return 0; } close(fd); arg[1].typ = VT_INT; arg[1].d = (udata) l; //printf("data=%ld %ld\n",l,arg[1].d); return 1; } /* lpoke address value */ udata cmd_lpoke(struct med_s * m, var_t * arg, int n) { int fd; char s[1024]; long l; if (n != 2 || arg[0].typ != VT_INT || arg[1].typ != VT_INT) return 0; sprintf(s, "/proc/%d/mem", m->proc.pid); if ((fd = open(s, O_WRONLY)) < 0) return 0; lseek(fd, arg[0].d, SEEK_SET); if (write(fd, &l, sizeof(long)) != sizeof(long)) { close(fd); return 0; } close(fd); arg[1].typ = VT_INT; arg[1].d = (udata) l; return 1; } udata cmd_log_iget(struct med_s * m, var_t * arg, int n) { files_t *f; char buf[4096]; if (m->inode == NULL) return 0; f = (files_t *) m->inode->mi.cinfo; print_name(buf, f); printlog("sending info about inode [%04x]:%ld vs=%04x act=%04x %s (%s)", m->inode->dev, m->inode->ino, m->inode->mi.med_vs, m->proc.mp.med_iact, m->data, buf); return 1; } udata cmd_log_iact(struct med_s * m, var_t * arg, int n) { files_t *f; char buf[4096]; if (m->inode == NULL) return 0; f = (files_t *) m->inode->mi.cinfo; print_name(buf, f); printlog("process %d (uid=%d luid=%d vs=%04x ecap=%08x) %s %s (%s)", m->proc.pid, m->proc.uid, m->proc.luid, m->proc.mp.med_vs, m->proc.cap_effective, ((n > 0 && arg->typ == VT_STR) ? (char *) (arg->d) : ""), (m->data != NULL ? m->data : buf), (m->data != NULL ? buf : "")); return 1; } udata cmd_log_proc(struct med_s * m, var_t * arg, int n) { printlog("%s process %d (uid=%d luid=%d vs=%04x vss=%04x vsr=%04x vsw=%04x ecap=%08x)", ((n > 0 && arg->typ == VT_STR) ? (char *) (arg->d) : ""), m->proc.pid, m->proc.uid, m->proc.luid, m->proc.mp.med_vs, m->proc.mp.med_vs_s, m->proc.mp.med_vs_r, m->proc.mp.med_vs_w, m->proc.cap_effective); return 1; } udata cmd_log_print(struct med_s * m, var_t * arg, int n) { char buf[8192]; int i = 0; while (n > 0 && i < 8000) { if (arg->typ == VT_STR) snprintf(buf + i, sizeof(buf) - i, "%s", (char *) (arg->d)); else if (arg->typ == VT_INT) snprintf(buf + i, sizeof(buf) - i, "%ld", arg->d); //else printf("typ=%d data=%d\n",arg->typ,arg->d); i += strlen(buf + i); arg++; n--; } buf[i] = 0; printlog("%s", buf); return 1; }