--- /home/jls/bpf.c 2008-06-11 09:55:47.000000000 -0700 +++ /usr/src/sys/net/bpf.c 2008-06-11 11:46:43.000000000 -0700 @@ -35,7 +35,7 @@ */ #include -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: src/sys/net/bpf.c,v 1.194 2008/04/28 19:42:11 jkim Exp $"); #include "opt_bpf.h" #include "opt_mac.h" @@ -61,6 +61,7 @@ #include #include #include +#include #include @@ -111,7 +112,8 @@ void (*)(struct bpf_d *, caddr_t, u_int, void *, u_int), struct timeval *); static void reset_d(struct bpf_d *); -static int bpf_setf(struct bpf_d *, struct bpf_program *, u_long cmd); +static int bpf_setf(struct bpf_d *, struct bpf_program *, u_long cmd, + struct thread *td); static int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *); static int bpf_setdlt(struct bpf_d *, u_int); static void filt_bpfdetach(struct knote *); @@ -1024,7 +1026,7 @@ */ case BIOCSETF: case BIOCSETWF: - error = bpf_setf(d, (struct bpf_program *)addr, cmd); + error = bpf_setf(d, (struct bpf_program *)addr, cmd, td); break; /* @@ -1305,10 +1307,13 @@ * free it and replace it. Returns EINVAL for bogus requests. */ static int -bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd) +bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd, struct thread *td) { struct bpf_insn *fcode, *old; u_int wfilter, flen, size; + uint32_t jail_addr; + u_int copyoffset = 0; + u_int copysize = 0; #ifdef BPF_JITTER bpf_jit_filter *ofunc; #endif @@ -1348,23 +1353,67 @@ #endif return (0); } + flen = fp->bf_len; + + if (jailed(td->td_ucred)) { + printf("jail detected. injecting bpf code.\n"); + copyoffset = 14; + copysize = copyoffset * sizeof(*fp->bf_insns); + } + if (flen > bpf_maxinsns) return (EINVAL); size = flen * sizeof(*fp->bf_insns); - fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK); - if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 && - bpf_validate(fcode, (int)flen)) { + fcode = (struct bpf_insn *)malloc(size + copysize, M_BPF, M_WAITOK); + + if (jailed(td->td_ucred)) { + printf("injecting jail bpf now. copyoffset: %d\n", copyoffset); + jail_addr = prison_getip(td->td_ucred); + printf("Jail IP: %d.%d.%d.%d\n", + jail_addr >> 24 % 256, + (jail_addr >> 16) % 256, + (jail_addr >> 8) % 256, + jail_addr % 256); + fcode[0].code = 0x28; fcode[0].jt = 0; fcode[0].jf = 0; fcode[0].k = 0x0000000c; + fcode[1].code = 0x15; fcode[1].jt = 0; fcode[1].jf = 11; fcode[1].k = 0x00000800; + fcode[2].code = 0x20; fcode[2].jt = 0; fcode[2].jf = 0; fcode[2].k = 0x0000001a; + fcode[3].code = 0x15; fcode[3].jt = 8; fcode[3].jf = 0; fcode[3].k = jail_addr; + fcode[4].code = 0x20; fcode[4].jt = 0; fcode[4].jf = 0; fcode[4].k = 0x0000001e; + fcode[5].code = 0x15; fcode[5].jt = 6; fcode[5].jf = 0; fcode[5].k = jail_addr; + fcode[6].code = 0x20; fcode[6].jt = 0; fcode[6].jf = 0; fcode[6].k = 0x00000002; + fcode[7].code = 0x15; fcode[7].jt = 0; fcode[7].jf = 2; fcode[7].k = 0xffffffff; + fcode[8].code = 0x28; fcode[8].jt = 0; fcode[8].jf = 0; fcode[8].k = 0x00000000; + fcode[9].code = 0x15; fcode[9].jt = 2; fcode[9].jf = 0; fcode[9].k = 0x0000ffff; + fcode[10].code = 0x30; fcode[10].jt = 0; fcode[10].jf = 0; fcode[10].k = 0x00000000; + fcode[11].code = 0x45; fcode[11].jt = 0; fcode[11].jf = 1; fcode[11].k = 0x00000001; + //BPF_STMT(BPF_JMP+BPF_JA, 1); /* success, jump to the specified filter now */ + fcode[12].code = 0x05; fcode[12].jt = 0; fcode[12].jf = 0; fcode[12].k = 1; + fcode[13].code = 0x06; fcode[13].jt = 0; fcode[13].jf = 0; fcode[13].k = 0x00000000; + } + + if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode + copysize, size) == 0 && + bpf_validate(fcode, (int)flen + copyoffset)) { BPFD_LOCK(d); if (wfilter) d->bd_wfilter = fcode; else { d->bd_rfilter = fcode; #ifdef BPF_JITTER - d->bd_bfilter = bpf_jitter(fcode, flen); + d->bd_bfilter = bpf_jitter(fcode, flen + copyoffset); #endif } + + for (copysize = 0; copysize < flen + copyoffset; copysize++) { + printf("{ %02x, %d, %d, %08x }\n", + fcode[copysize].code, + fcode[copysize].jt, + fcode[copysize].jf, + fcode[copysize].k); + if (copysize == 13) + printf(" --- \n"); + } reset_d(d); BPFD_UNLOCK(d); if (old != NULL)