bpf_jit_filter * bpf_jitter(struct bpf_insn *fp, int nins) { bpf_jit_filter *filter; /* Allocate the filter structure. */ #ifdef _KERNEL filter = (struct bpf_jit_filter *)malloc(sizeof(*filter), M_BPFJIT, M_NOWAIT); #else filter = (struct bpf_jit_filter *)malloc(sizeof(*filter)); #endif if (filter == NULL) return (NULL); /* No filter means accept all. */ if (fp == NULL || nins == 0) { filter->func = bpf_jit_accept_all; return (filter); } /* Create the binary. */ if ((filter->func = bpf_jit_compile(fp, nins, &filter->size)) == NULL) { #ifdef _KERNEL free(filter, M_BPFJIT); #else free(filter); #endif return (NULL); } return (filter); }
/** * sk_attach_filter - attach a socket filter * @fprog: the filter program * @sk: the socket to use * * Attach the user's filter code. We first run some sanity checks on * it to make sure it does not explode on us later. If an error * occurs or there is insufficient memory for the filter a negative * errno code is returned. On success the return is zero. */ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) { struct sk_filter *fp, *old_fp; unsigned int fsize = sizeof(struct sock_filter) * fprog->len; int err; /* Make sure new filter is there and in the right amounts. */ if (fprog->filter == NULL) return -EINVAL; fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL); if (!fp) return -ENOMEM; if (copy_from_user(fp->insns, fprog->filter, fsize)) { sock_kfree_s(sk, fp, fsize+sizeof(*fp)); return -EFAULT; } atomic_set(&fp->refcnt, 1); fp->len = fprog->len; fp->bpf_func = sk_run_filter; err = sk_chk_filter(fp->insns, fp->len); if (err) { sk_filter_uncharge(sk, fp); return err; } bpf_jit_compile(fp); rcu_read_lock_bh(); old_fp = rcu_dereference_bh(sk->sk_filter); rcu_assign_pointer(sk->sk_filter, fp); rcu_read_unlock_bh(); if (old_fp) sk_filter_delayed_uncharge(sk, old_fp); return 0; }