* Set d's packet filter program to fp. If this file already has a filter, * free it and replace it. Returns EINVAL for bogus requests. * * Note we use global lock here to serialize bpf_setf() and bpf_setif() * calls. */
| 1911 | * calls. |
| 1912 | */ |
| 1913 | static int |
| 1914 | bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd) |
| 1915 | { |
| 1916 | #ifdef COMPAT_FREEBSD32 |
| 1917 | struct bpf_program fp_swab; |
| 1918 | struct bpf_program32 *fp32; |
| 1919 | #endif |
| 1920 | struct bpf_program_buffer *fcode; |
| 1921 | struct bpf_insn *filter; |
| 1922 | #ifdef BPF_JITTER |
| 1923 | bpf_jit_filter *jfunc; |
| 1924 | #endif |
| 1925 | size_t size; |
| 1926 | u_int flen; |
| 1927 | bool track_event; |
| 1928 | |
| 1929 | #ifdef COMPAT_FREEBSD32 |
| 1930 | switch (cmd) { |
| 1931 | case BIOCSETF32: |
| 1932 | case BIOCSETWF32: |
| 1933 | case BIOCSETFNR32: |
| 1934 | fp32 = (struct bpf_program32 *)fp; |
| 1935 | fp_swab.bf_len = fp32->bf_len; |
| 1936 | fp_swab.bf_insns = |
| 1937 | (struct bpf_insn *)(uintptr_t)fp32->bf_insns; |
| 1938 | fp = &fp_swab; |
| 1939 | switch (cmd) { |
| 1940 | case BIOCSETF32: |
| 1941 | cmd = BIOCSETF; |
| 1942 | break; |
| 1943 | case BIOCSETWF32: |
| 1944 | cmd = BIOCSETWF; |
| 1945 | break; |
| 1946 | } |
| 1947 | break; |
| 1948 | } |
| 1949 | #endif |
| 1950 | |
| 1951 | filter = NULL; |
| 1952 | #ifdef BPF_JITTER |
| 1953 | jfunc = NULL; |
| 1954 | #endif |
| 1955 | /* |
| 1956 | * Check new filter validness before acquiring any locks. |
| 1957 | * Allocate memory for new filter, if needed. |
| 1958 | */ |
| 1959 | flen = fp->bf_len; |
| 1960 | if (flen > bpf_maxinsns || (fp->bf_insns == NULL && flen != 0)) |
| 1961 | return (EINVAL); |
| 1962 | size = flen * sizeof(*fp->bf_insns); |
| 1963 | if (size > 0) { |
| 1964 | /* We're setting up new filter. Copy and check actual data. */ |
| 1965 | fcode = bpf_program_buffer_alloc(size, M_WAITOK); |
| 1966 | filter = (struct bpf_insn *)fcode->buffer; |
| 1967 | if (copyin(fp->bf_insns, filter, size) != 0 || |
| 1968 | !bpf_validate(filter, flen)) { |
| 1969 | free(fcode, M_BPF); |
| 1970 | return (EINVAL); |
no test coverage detected