aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2015-03-13 14:57:42 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-15 22:02:28 -0400
commit9bac3d6d548e5cc925570b263f35b70a00a00ffd (patch)
tree00ae5c37fb877d7c2b4fdf5ee0b8fe4837b1d476 /kernel/bpf
parenta498cfe990f569dd3766bfc9bfd2a5ee04468cd2 (diff)
bpf: allow extended BPF programs access skb fields
introduce user accessible mirror of in-kernel 'struct sk_buff': struct __sk_buff { __u32 len; __u32 pkt_type; __u32 mark; __u32 queue_mapping; }; bpf programs can do: int bpf_prog(struct __sk_buff *skb) { __u32 var = skb->pkt_type; which will be compiled to bpf assembler as: dst_reg = *(u32 *)(src_reg + 4) // 4 == offsetof(struct __sk_buff, pkt_type) bpf verifier will check validity of access and will convert it to: dst_reg = *(u8 *)(src_reg + offsetof(struct sk_buff, __pkt_type_offset)) dst_reg &= 7 since skb->pkt_type is a bitfield. Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/syscall.c2
-rw-r--r--kernel/bpf/verifier.c152
2 files changed, 137 insertions, 17 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 669719ccc9ee..ea75c654af1b 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -519,7 +519,7 @@ static int bpf_prog_load(union bpf_attr *attr)
519 goto free_prog; 519 goto free_prog;
520 520
521 /* run eBPF verifier */ 521 /* run eBPF verifier */
522 err = bpf_check(prog, attr); 522 err = bpf_check(&prog, attr);
523 if (err < 0) 523 if (err < 0)
524 goto free_used_maps; 524 goto free_used_maps;
525 525
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e6b522496250..c22ebd36fa4b 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1620,11 +1620,10 @@ static int do_check(struct verifier_env *env)
1620 return err; 1620 return err;
1621 1621
1622 } else if (class == BPF_LDX) { 1622 } else if (class == BPF_LDX) {
1623 if (BPF_MODE(insn->code) != BPF_MEM || 1623 enum bpf_reg_type src_reg_type;
1624 insn->imm != 0) { 1624
1625 verbose("BPF_LDX uses reserved fields\n"); 1625 /* check for reserved fields is already done */
1626 return -EINVAL; 1626
1627 }
1628 /* check src operand */ 1627 /* check src operand */
1629 err = check_reg_arg(regs, insn->src_reg, SRC_OP); 1628 err = check_reg_arg(regs, insn->src_reg, SRC_OP);
1630 if (err) 1629 if (err)
@@ -1643,6 +1642,29 @@ static int do_check(struct verifier_env *env)
1643 if (err) 1642 if (err)
1644 return err; 1643 return err;
1645 1644
1645 src_reg_type = regs[insn->src_reg].type;
1646
1647 if (insn->imm == 0 && BPF_SIZE(insn->code) == BPF_W) {
1648 /* saw a valid insn
1649 * dst_reg = *(u32 *)(src_reg + off)
1650 * use reserved 'imm' field to mark this insn
1651 */
1652 insn->imm = src_reg_type;
1653
1654 } else if (src_reg_type != insn->imm &&
1655 (src_reg_type == PTR_TO_CTX ||
1656 insn->imm == PTR_TO_CTX)) {
1657 /* ABuser program is trying to use the same insn
1658 * dst_reg = *(u32*) (src_reg + off)
1659 * with different pointer types:
1660 * src_reg == ctx in one branch and
1661 * src_reg == stack|map in some other branch.
1662 * Reject it.
1663 */
1664 verbose("same insn cannot be used with different pointers\n");
1665 return -EINVAL;
1666 }
1667
1646 } else if (class == BPF_STX) { 1668 } else if (class == BPF_STX) {
1647 if (BPF_MODE(insn->code) == BPF_XADD) { 1669 if (BPF_MODE(insn->code) == BPF_XADD) {
1648 err = check_xadd(env, insn); 1670 err = check_xadd(env, insn);
@@ -1790,6 +1812,13 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env)
1790 int i, j; 1812 int i, j;
1791 1813
1792 for (i = 0; i < insn_cnt; i++, insn++) { 1814 for (i = 0; i < insn_cnt; i++, insn++) {
1815 if (BPF_CLASS(insn->code) == BPF_LDX &&
1816 (BPF_MODE(insn->code) != BPF_MEM ||
1817 insn->imm != 0)) {
1818 verbose("BPF_LDX uses reserved fields\n");
1819 return -EINVAL;
1820 }
1821
1793 if (insn[0].code == (BPF_LD | BPF_IMM | BPF_DW)) { 1822 if (insn[0].code == (BPF_LD | BPF_IMM | BPF_DW)) {
1794 struct bpf_map *map; 1823 struct bpf_map *map;
1795 struct fd f; 1824 struct fd f;
@@ -1881,6 +1910,92 @@ static void convert_pseudo_ld_imm64(struct verifier_env *env)
1881 insn->src_reg = 0; 1910 insn->src_reg = 0;
1882} 1911}
1883 1912
1913static void adjust_branches(struct bpf_prog *prog, int pos, int delta)
1914{
1915 struct bpf_insn *insn = prog->insnsi;
1916 int insn_cnt = prog->len;
1917 int i;
1918
1919 for (i = 0; i < insn_cnt; i++, insn++) {
1920 if (BPF_CLASS(insn->code) != BPF_JMP ||
1921 BPF_OP(insn->code) == BPF_CALL ||
1922 BPF_OP(insn->code) == BPF_EXIT)
1923 continue;
1924
1925 /* adjust offset of jmps if necessary */
1926 if (i < pos && i + insn->off + 1 > pos)
1927 insn->off += delta;
1928 else if (i > pos && i + insn->off + 1 < pos)
1929 insn->off -= delta;
1930 }
1931}
1932
1933/* convert load instructions that access fields of 'struct __sk_buff'
1934 * into sequence of instructions that access fields of 'struct sk_buff'
1935 */
1936static int convert_ctx_accesses(struct verifier_env *env)
1937{
1938 struct bpf_insn *insn = env->prog->insnsi;
1939 int insn_cnt = env->prog->len;
1940 struct bpf_insn insn_buf[16];
1941 struct bpf_prog *new_prog;
1942 u32 cnt;
1943 int i;
1944
1945 if (!env->prog->aux->ops->convert_ctx_access)
1946 return 0;
1947
1948 for (i = 0; i < insn_cnt; i++, insn++) {
1949 if (insn->code != (BPF_LDX | BPF_MEM | BPF_W))
1950 continue;
1951
1952 if (insn->imm != PTR_TO_CTX) {
1953 /* clear internal mark */
1954 insn->imm = 0;
1955 continue;
1956 }
1957
1958 cnt = env->prog->aux->ops->
1959 convert_ctx_access(insn->dst_reg, insn->src_reg,
1960 insn->off, insn_buf);
1961 if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) {
1962 verbose("bpf verifier is misconfigured\n");
1963 return -EINVAL;
1964 }
1965
1966 if (cnt == 1) {
1967 memcpy(insn, insn_buf, sizeof(*insn));
1968 continue;
1969 }
1970
1971 /* several new insns need to be inserted. Make room for them */
1972 insn_cnt += cnt - 1;
1973 new_prog = bpf_prog_realloc(env->prog,
1974 bpf_prog_size(insn_cnt),
1975 GFP_USER);
1976 if (!new_prog)
1977 return -ENOMEM;
1978
1979 new_prog->len = insn_cnt;
1980
1981 memmove(new_prog->insnsi + i + cnt, new_prog->insns + i + 1,
1982 sizeof(*insn) * (insn_cnt - i - cnt));
1983
1984 /* copy substitute insns in place of load instruction */
1985 memcpy(new_prog->insnsi + i, insn_buf, sizeof(*insn) * cnt);
1986
1987 /* adjust branches in the whole program */
1988 adjust_branches(new_prog, i, cnt - 1);
1989
1990 /* keep walking new program and skip insns we just inserted */
1991 env->prog = new_prog;
1992 insn = new_prog->insnsi + i + cnt - 1;
1993 i += cnt - 1;
1994 }
1995
1996 return 0;
1997}
1998
1884static void free_states(struct verifier_env *env) 1999static void free_states(struct verifier_env *env)
1885{ 2000{
1886 struct verifier_state_list *sl, *sln; 2001 struct verifier_state_list *sl, *sln;
@@ -1903,13 +2018,13 @@ static void free_states(struct verifier_env *env)
1903 kfree(env->explored_states); 2018 kfree(env->explored_states);
1904} 2019}
1905 2020
1906int bpf_check(struct bpf_prog *prog, union bpf_attr *attr) 2021int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
1907{ 2022{
1908 char __user *log_ubuf = NULL; 2023 char __user *log_ubuf = NULL;
1909 struct verifier_env *env; 2024 struct verifier_env *env;
1910 int ret = -EINVAL; 2025 int ret = -EINVAL;