diff options
Diffstat (limited to 'kernel/bpf/verifier.c')
| -rw-r--r-- | kernel/bpf/verifier.c | 145 |
1 files changed, 120 insertions, 25 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c5b56c92f8e2..1eddb713b815 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -140,7 +140,7 @@ struct bpf_verifier_stack_elem { | |||
| 140 | struct bpf_verifier_stack_elem *next; | 140 | struct bpf_verifier_stack_elem *next; |
| 141 | }; | 141 | }; |
| 142 | 142 | ||
| 143 | #define BPF_COMPLEXITY_LIMIT_INSNS 65536 | 143 | #define BPF_COMPLEXITY_LIMIT_INSNS 98304 |
| 144 | #define BPF_COMPLEXITY_LIMIT_STACK 1024 | 144 | #define BPF_COMPLEXITY_LIMIT_STACK 1024 |
| 145 | 145 | ||
| 146 | #define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA) | 146 | #define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA) |
| @@ -241,6 +241,12 @@ static void print_verifier_state(struct bpf_verifier_state *state) | |||
| 241 | if (reg->max_value != BPF_REGISTER_MAX_RANGE) | 241 | if (reg->max_value != BPF_REGISTER_MAX_RANGE) |
| 242 | verbose(",max_value=%llu", | 242 | verbose(",max_value=%llu", |
| 243 | (unsigned long long)reg->max_value); | 243 | (unsigned long long)reg->max_value); |
| 244 | if (reg->min_align) | ||
| 245 | verbose(",min_align=%u", reg->min_align); | ||
| 246 | if (reg->aux_off) | ||
| 247 | verbose(",aux_off=%u", reg->aux_off); | ||
| 248 | if (reg->aux_off_align) | ||
| 249 | verbose(",aux_off_align=%u", reg->aux_off_align); | ||
| 244 | } | 250 | } |
| 245 | for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { | 251 | for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { |
| 246 | if (state->stack_slot_type[i] == STACK_SPILL) | 252 | if (state->stack_slot_type[i] == STACK_SPILL) |
| @@ -466,6 +472,9 @@ static void init_reg_state(struct bpf_reg_state *regs) | |||
| 466 | regs[i].imm = 0; | 472 | regs[i].imm = 0; |
| 467 | regs[i].min_value = BPF_REGISTER_MIN_RANGE; | 473 | regs[i].min_value = BPF_REGISTER_MIN_RANGE; |
| 468 | regs[i].max_value = BPF_REGISTER_MAX_RANGE; | 474 | regs[i].max_value = BPF_REGISTER_MAX_RANGE; |
| 475 | regs[i].min_align = 0; | ||
| 476 | regs[i].aux_off = 0; | ||
| 477 | regs[i].aux_off_align = 0; | ||
| 469 | } | 478 | } |
| 470 | 479 | ||
| 471 | /* frame pointer */ | 480 | /* frame pointer */ |
| @@ -492,6 +501,7 @@ static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno) | |||
| 492 | { | 501 | { |
| 493 | regs[regno].min_value = BPF_REGISTER_MIN_RANGE; | 502 | regs[regno].min_value = BPF_REGISTER_MIN_RANGE; |
| 494 | regs[regno].max_value = BPF_REGISTER_MAX_RANGE; | 503 | regs[regno].max_value = BPF_REGISTER_MAX_RANGE; |
| 504 | regs[regno].min_align = 0; | ||
| 495 | } | 505 | } |
| 496 | 506 | ||
| 497 | static void mark_reg_unknown_value_and_range(struct bpf_reg_state *regs, | 507 | static void mark_reg_unknown_value_and_range(struct bpf_reg_state *regs, |
| @@ -779,17 +789,33 @@ static bool is_pointer_value(struct bpf_verifier_env *env, int regno) | |||
| 779 | } | 789 | } |
| 780 | 790 | ||
| 781 | static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, | 791 | static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, |
| 782 | int off, int size) | 792 | int off, int size, bool strict) |
| 783 | { | 793 | { |
| 784 | if (reg->id && size != 1) { | 794 | int ip_align; |
| 785 | verbose("Unknown alignment. Only byte-sized access allowed in packet access.\n"); | 795 | int reg_off; |
| 786 | return -EACCES; | 796 | |
| 797 | /* Byte size accesses are always allowed. */ | ||
| 798 | if (!strict || size == 1) | ||
| 799 | return 0; | ||
| 800 | |||
| 801 | reg_off = reg->off; | ||
| 802 | if (reg->id) { | ||
| 803 | if (reg->aux_off_align % size) { | ||
| 804 | verbose("Packet access is only %u byte aligned, %d byte access not allowed\n", | ||
| 805 | reg->aux_off_align, size); | ||
| 806 | return -EACCES; | ||
| 807 | } | ||
| 808 | reg_off += reg->aux_off; | ||
| 787 | } | 809 | } |
| 788 | 810 | ||
| 789 | /* skb->data is NET_IP_ALIGN-ed */ | 811 | /* skb->data is NET_IP_ALIGN-ed, but for strict alignment checking |
| 790 | if ((NET_IP_ALIGN + reg->off + off) % size != 0) { | 812 | * we force this to 2 which is universally what architectures use |
| 813 | * when they don't set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS. | ||
| 814 | */ | ||
| 815 | ip_align = strict ? 2 : NET_IP_ALIGN; | ||
| 816 | if ((ip_align + reg_off + off) % size != 0) { | ||
| 791 | verbose("misaligned packet access off %d+%d+%d size %d\n", | 817 | verbose("misaligned packet access off %d+%d+%d size %d\n", |
| 792 | NET_IP_ALIGN, reg->off, off, size); | 818 | ip_align, reg_off, off, size); |
| 793 | return -EACCES; | 819 | return -EACCES; |
| 794 | } | 820 | } |
| 795 | 821 | ||
| @@ -797,9 +823,9 @@ static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, | |||
| 797 | } | 823 | } |
| 798 | 824 | ||
| 799 | static int check_val_ptr_alignment(const struct bpf_reg_state *reg, | 825 | static int check_val_ptr_alignment(const struct bpf_reg_state *reg, |
| 800 | int size) | 826 | int size, bool strict) |
| 801 | { | 827 | { |
| 802 | if (size != 1) { | 828 | if (strict && size != 1) { |
| 803 | verbose("Unknown alignment. Only byte-sized access allowed in value access.\n"); | 829 | verbose("Unknown alignment. Only byte-sized access allowed in value access.\n"); |
| 804 | return -EACCES; | 830 | return -EACCES; |
| 805 | } | 831 | } |
| @@ -807,16 +833,20 @@ static int check_val_ptr_alignment(const struct bpf_reg_state *reg, | |||
| 807 | return 0; | 833 | return 0; |
| 808 | } | 834 | } |
| 809 | 835 | ||
| 810 | static int check_ptr_alignment(const struct bpf_reg_state *reg, | 836 | static int check_ptr_alignment(struct bpf_verifier_env *env, |
| 837 | const struct bpf_reg_state *reg, | ||
| 811 | int off, int size) | 838 | int off, int size) |
| 812 | { | 839 | { |
| 840 | bool strict = env->strict_alignment; | ||
| 841 | |||
| 842 | if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) | ||
| 843 | strict = true; | ||
| 844 | |||
| 813 | switch (reg->type) { | 845 | switch (reg->type) { |
| 814 | case PTR_TO_PACKET: | 846 | case PTR_TO_PACKET: |
| 815 | return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ? 0 : | 847 | return check_pkt_ptr_alignment(reg, off, size, strict); |
| 816 | check_pkt_ptr_alignment(reg, off, size); | ||
| 817 | case PTR_TO_MAP_VALUE_ADJ: | 848 | case PTR_TO_MAP_VALUE_ADJ: |
| 818 | return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ? 0 : | 849 | return check_val_ptr_alignment(reg, size, strict); |
| 819 | check_val_ptr_alignment(reg, size); | ||
| 820 | default: | 850 | default: |
| 821 | if (off % size != 0) { | 851 | if (off % size != 0) { |
| 822 | verbose("misaligned access off %d size %d\n", | 852 | verbose("misaligned access off %d size %d\n", |
| @@ -849,7 +879,7 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off, | |||
| 849 | if (size < 0) | 879 | if (size < 0) |
| 850 | return size; | 880 | return size; |
| 851 | 881 | ||
| 852 | err = check_ptr_alignment(reg, off, size); | 882 | err = check_ptr_alignment(env, reg, off, size); |
| 853 | if (err) | 883 | if (err) |
| 854 | return err; | 884 | return err; |
| 855 | 885 | ||
| @@ -883,6 +913,8 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off, | |||
| 883 | value_regno); | 913 | value_regno); |
| 884 | /* note that reg.[id|off|range] == 0 */ | 914 | /* note that reg.[id|off|range] == 0 */ |
| 885 | state->regs[value_regno].type = reg_type; | 915 | state->regs[value_regno].type = reg_type; |
| 916 | state->regs[value_regno].aux_off = 0; | ||
| 917 | state->regs[value_regno].aux_off_align = 0; | ||
| 886 | } | 918 | } |
| 887 | 919 | ||
| 888 | } else if (reg->type == FRAME_PTR || reg->type == PTR_TO_STACK) { | 920 | } else if (reg->type == FRAME_PTR || reg->type == PTR_TO_STACK) { |
| @@ -1455,6 +1487,8 @@ add_imm: | |||
| 1455 | */ | 1487 | */ |
| 1456 | dst_reg->off += imm; | 1488 | dst_reg->off += imm; |
| 1457 | } else { | 1489 | } else { |
| 1490 | bool had_id; | ||
| 1491 | |||
| 1458 | if (src_reg->type == PTR_TO_PACKET) { | 1492 | if (src_reg->type == PTR_TO_PACKET) { |
| 1459 | /* R6=pkt(id=0,off=0,r=62) R7=imm22; r7 += r6 */ | 1493 | /* R6=pkt(id=0,off=0,r=62) R7=imm22; r7 += r6 */ |
| 1460 | tmp_reg = *dst_reg; /* save r7 state */ | 1494 | tmp_reg = *dst_reg; /* save r7 state */ |
| @@ -1488,14 +1522,23 @@ add_imm: | |||
| 1488 | src_reg->imm); | 1522 | src_reg->imm); |
| 1489 | return -EACCES; | 1523 | return -EACCES; |
| 1490 | } | 1524 | } |
| 1525 | |||
| 1526 | had_id = (dst_reg->id != 0); | ||
| 1527 | |||
| 1491 | /* dst_reg stays as pkt_ptr type and since some positive | 1528 | /* dst_reg stays as pkt_ptr type and since some positive |
| 1492 | * integer value was added to the pointer, increment its 'id' | 1529 | * integer value was added to the pointer, increment its 'id' |
| 1493 | */ | 1530 | */ |
| 1494 | dst_reg->id = ++env->id_gen; | 1531 | dst_reg->id = ++env->id_gen; |
| 1495 | 1532 | ||
| 1496 | /* something was added to pkt_ptr, set range and off to zero */ | 1533 | /* something was added to pkt_ptr, set range to zero */ |
| 1534 | dst_reg->aux_off += dst_reg->off; | ||
| 1497 | dst_reg->off = 0; | 1535 | dst_reg->off = 0; |
| 1498 | dst_reg->range = 0; | 1536 | dst_reg->range = 0; |
| 1537 | if (had_id) | ||
| 1538 | dst_reg->aux_off_align = min(dst_reg->aux_off_align, | ||
| 1539 | src_reg->min_align); | ||
| 1540 | else | ||
| 1541 | dst_reg->aux_off_align = src_reg->min_align; | ||
| 1499 | } | 1542 | } |
| 1500 | return 0; | 1543 | return 0; |
| 1501 | } | 1544 | } |
| @@ -1669,6 +1712,13 @@ static void check_reg_overflow(struct bpf_reg_state *reg) | |||
| 1669 | reg->min_value = BPF_REGISTER_MIN_RANGE; | 1712 | reg->min_value = BPF_REGISTER_MIN_RANGE; |
| 1670 | } | 1713 | } |
| 1671 | 1714 | ||
| 1715 | static u32 calc_align(u32 imm) | ||
| 1716 | { | ||
| 1717 | if (!imm) | ||
| 1718 | return 1U << 31; | ||
| 1719 | return imm - ((imm - 1) & imm); | ||
| 1720 | } | ||
| 1721 | |||
| 1672 | static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, | 1722 | static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, |
| 1673 | struct bpf_insn *insn) | 1723 | struct bpf_insn *insn) |
| 1674 | { | 1724 | { |
| @@ -1676,8 +1726,10 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, | |||
| 1676 | s64 min_val = BPF_REGISTER_MIN_RANGE; | 1726 | s64 min_val = BPF_REGISTER_MIN_RANGE; |
| 1677 | u64 max_val = BPF_REGISTER_MAX_RANGE; | 1727 | u64 max_val = BPF_REGISTER_MAX_RANGE; |
| 1678 | u8 opcode = BPF_OP(insn->code); | 1728 | u8 opcode = BPF_OP(insn->code); |
| 1729 | u32 dst_align, src_align; | ||
| 1679 | 1730 | ||
| 1680 | dst_reg = ®s[insn->dst_reg]; | 1731 | dst_reg = ®s[insn->dst_reg]; |
| 1732 | src_align = 0; | ||
| 1681 | if (BPF_SRC(insn->code) == BPF_X) { | 1733 | if (BPF_SRC(insn->code) == BPF_X) { |
| 1682 | check_reg_overflow(®s[insn->src_reg]); | 1734 | check_reg_overflow(®s[insn->src_reg]); |
| 1683 | min_val = regs[insn->src_reg].min_value; | 1735 | min_val = regs[insn->src_reg].min_value; |
| @@ -1693,12 +1745,18 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, | |||
| 1693 | regs[insn->src_reg].type != UNKNOWN_VALUE) { | 1745 | regs[insn->src_reg].type != UNKNOWN_VALUE) { |
| 1694 | min_val = BPF_REGISTER_MIN_RANGE; | 1746 | min_val = BPF_REGISTER_MIN_RANGE; |
| 1695 | max_val = BPF_REGISTER_MAX_RANGE; | 1747 | max_val = BPF_REGISTER_MAX_RANGE; |
| 1748 | src_align = 0; | ||
| 1749 | } else { | ||
| 1750 | src_align = regs[insn->src_reg].min_align; | ||
| 1696 | } | 1751 | } |
| 1697 | } else if (insn->imm < BPF_REGISTER_MAX_RANGE && | 1752 | } else if (insn->imm < BPF_REGISTER_MAX_RANGE && |
| 1698 | (s64)insn->imm > BPF_REGISTER_MIN_RANGE) { | 1753 | (s64)insn->imm > BPF_REGISTER_MIN_RANGE) { |
| 1699 | min_val = max_val = insn->imm; | 1754 | min_val = max_val = insn->imm; |
| 1755 | src_align = calc_align(insn->imm); | ||
| 1700 | } | 1756 | } |
| 1701 | 1757 | ||
| 1758 | dst_align = dst_reg->min_align; | ||
| 1759 | |||
| 1702 | /* We don't know anything about what was done to this register, mark it | 1760 | /* We don't know anything about what was done to this register, mark it |
| 1703 | * as unknown. | 1761 | * as unknown. |
| 1704 | */ | 1762 | */ |
| @@ -1723,18 +1781,21 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, | |||
| 1723 | dst_reg->min_value += min_val; | 1781 | dst_reg->min_value += min_val; |
| 1724 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | 1782 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) |
| 1725 | dst_reg->max_value += max_val; | 1783 | dst_reg->max_value += max_val; |
| 1784 | dst_reg->min_align = min(src_align, dst_align); | ||
| 1726 | break; | 1785 | break; |
| 1727 | case BPF_SUB: | 1786 | case BPF_SUB: |
| 1728 | if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | 1787 | if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) |
| 1729 | dst_reg->min_value -= min_val; | 1788 | dst_reg->min_value -= min_val; |
| 1730 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | 1789 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) |
| 1731 | dst_reg->max_value -= max_val; | 1790 | dst_reg->max_value -= max_val; |
| 1791 | dst_reg->min_align = min(src_align, dst_align); | ||
| 1732 | break; | 1792 | break; |
| 1733 | case BPF_MUL: | 1793 | case BPF_MUL: |
| 1734 | if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | 1794 | if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) |
| 1735 | dst_reg->min_value *= min_val; | 1795 | dst_reg->min_value *= min_val; |
| 1736 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | 1796 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) |
| 1737 | dst_reg->max_value *= max_val; | 1797 | dst_reg->max_value *= max_val; |
| 1798 | dst_reg->min_align = max(src_align, dst_align); | ||
| 1738 | break; | 1799 | break; |
| 1739 | case BPF_AND: | 1800 | case BPF_AND: |
| 1740 | /* Disallow AND'ing of negative numbers, ain't nobody got time | 1801 | /* Disallow AND'ing of negative numbers, ain't nobody got time |
| @@ -1746,17 +1807,23 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, | |||
| 1746 | else | 1807 | else |
| 1747 | dst_reg->min_value = 0; | 1808 | dst_reg->min_value = 0; |
| 1748 | dst_reg->max_value = max_val; | 1809 | dst_reg->max_value = max_val; |
| 1810 | dst_reg->min_align = max(src_align, dst_align); | ||
| 1749 | break; | 1811 | break; |
| 1750 | case BPF_LSH: | 1812 | case BPF_LSH: |
| 1751 | /* Gotta have special overflow logic here, if we're shifting | 1813 | /* Gotta have special overflow logic here, if we're shifting |
| 1752 | * more than MAX_RANGE then just assume we have an invalid | 1814 | * more than MAX_RANGE then just assume we have an invalid |
| 1753 | * range. | 1815 | * range. |
| 1754 | */ | 1816 | */ |
| 1755 | if (min_val > ilog2(BPF_REGISTER_MAX_RANGE)) | 1817 | if (min_val > ilog2(BPF_REGISTER_MAX_RANGE)) { |
| 1756 | dst_reg->min_value = BPF_REGISTER_MIN_RANGE; | 1818 | dst_reg->min_value = BPF_REGISTER_MIN_RANGE; |
| 1757 | else if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | 1819 | dst_reg->min_align = 1; |
| 1758 | dst_reg->min_value <<= min_val; | 1820 | } else { |
| 1759 | 1821 | if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | |
| 1822 | dst_reg->min_value <<= min_val; | ||
| 1823 | if (!dst_reg->min_align) | ||
| 1824 | dst_reg->min_align = 1; | ||
| 1825 | dst_reg->min_align <<= min_val; | ||
| 1826 | } | ||
| 1760 | if (max_val > ilog2(BPF_REGISTER_MAX_RANGE)) | 1827 | if (max_val > ilog2(BPF_REGISTER_MAX_RANGE)) |
| 1761 | dst_reg->max_value = BPF_REGISTER_MAX_RANGE; | 1828 | dst_reg->max_value = BPF_REGISTER_MAX_RANGE; |
| 1762 | else if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | 1829 | else if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) |
| @@ -1766,11 +1833,19 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, | |||
| 1766 | /* RSH by a negative number is undefined, and the BPF_RSH is an | 1833 | /* RSH by a negative number is undefined, and the BPF_RSH is an |
| 1767 | * unsigned shift, so make the appropriate casts. | 1834 | * unsigned shift, so make the appropriate casts. |
| 1768 | */ | 1835 | */ |
| 1769 | if (min_val < 0 || dst_reg->min_value < 0) | 1836 | if (min_val < 0 || dst_reg->min_value < 0) { |
| 1770 | dst_reg->min_value = BPF_REGISTER_MIN_RANGE; | 1837 | dst_reg->min_value = BPF_REGISTER_MIN_RANGE; |
| 1771 | else | 1838 | } else { |
| 1772 | dst_reg->min_value = | 1839 | dst_reg->min_value = |
| 1773 | (u64)(dst_reg->min_value) >> min_val; | 1840 | (u64)(dst_reg->min_value) >> min_val; |
| 1841 | } | ||
| 1842 | if (min_val < 0) { | ||
| 1843 | dst_reg->min_align = 1; | ||
| 1844 | } else { | ||
| 1845 | dst_reg->min_align >>= (u64) min_val; | ||
| 1846 | if (!dst_reg->min_align) | ||
| 1847 | dst_reg->min_align = 1; | ||
| 1848 | } | ||
| 1774 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | 1849 | if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) |
| 1775 | dst_reg->max_value >>= max_val; | 1850 | dst_reg->max_value >>= max_val; |
| 1776 | break; | 1851 | break; |
| @@ -1872,6 +1947,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) | |||
| 1872 | regs[insn->dst_reg].imm = insn->imm; | 1947 | regs[insn->dst_reg].imm = insn->imm; |
| 1873 | regs[insn->dst_reg].max_value = insn->imm; | 1948 | regs[insn->dst_reg].max_value = insn->imm; |
| 1874 | regs[insn->dst_reg].min_value = insn->imm; | 1949 | regs[insn->dst_reg].min_value = insn->imm; |
| 1950 | regs[insn->dst_reg].min_align = calc_align(insn->imm); | ||
| 1875 | } | 1951 | } |
| 1876 | 1952 | ||
| 1877 | } else if (opcode > BPF_END) { | 1953 | } else if (opcode > BPF_END) { |
| @@ -2564,6 +2640,7 @@ peek_stack: | |||
| 2564 | env->explored_states[t + 1] = STATE_LIST_MARK; | 2640 | env->explored_states[t + 1] = STATE_LIST_MARK; |
| 2565 | } else { | 2641 | } else { |
| 2566 | /* conditional jump with two edges */ | 2642 | /* conditional jump with two edges */ |
| 2643 | env->explored_states[t] = STATE_LIST_MARK; | ||
| 2567 | ret = push_insn(t, t + 1, FALLTHROUGH, env); | 2644 | ret = push_insn(t, t + 1, FALLTHROUGH, env); |
| 2568 | if (ret == 1) | 2645 | if (ret == 1) |
| 2569 | goto peek_stack; | 2646 | goto peek_stack; |
| @@ -2722,6 +2799,12 @@ static bool states_equal(struct bpf_verifier_env *env, | |||
| 2722 | rcur->type != NOT_INIT)) | 2799 | rcur->type != NOT_INIT)) |
| 2723 | continue; | 2800 | continue; |
| 2724 | 2801 | ||
| 2802 | /* Don't care about the reg->id in this case. */ | ||
| 2803 | if (rold->type == PTR_TO_MAP_VALUE_OR_NULL && | ||
| 2804 | rcur->type == PTR_TO_MAP_VALUE_OR_NULL && | ||
| 2805 | rold->map_ptr == rcur->map_ptr) | ||
| 2806 | continue; | ||
| 2807 | |||
| 2725 | if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET && | 2808 | if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET && |
| 2726 | compare_ptrs_to_packet(rold, rcur)) | 2809 | compare_ptrs_to_packet(rold, rcur)) |
| 2727 | continue; | 2810 | continue; |
| @@ -2856,8 +2939,15 @@ static int do_check(struct bpf_verifier_env *env) | |||
| 2856 | goto process_bpf_exit; | 2939 | goto process_bpf_exit; |
| 2857 | } | 2940 | } |
| 2858 | 2941 | ||
| 2859 | if (log_level && do_print_state) { | 2942 | if (need_resched()) |
| 2860 | verbose("\nfrom %d to %d:", prev_insn_idx, insn_idx); | 2943 | cond_resched(); |
| 2944 | |||
| 2945 | if (log_level > 1 || (log_level && do_print_state)) { | ||
| 2946 | if (log_level > 1) | ||
| 2947 | verbose("%d:", insn_idx); | ||
| 2948 | else | ||
| 2949 | verbose("\nfrom %d to %d:", | ||
| 2950 | prev_insn_idx, insn_idx); | ||
| 2861 | print_verifier_state(&env->cur_state); | 2951 | print_verifier_state(&env->cur_state); |
| 2862 | do_print_state = false; | 2952 | do_print_state = false; |
| 2863 | } | 2953 | } |
| @@ -3494,6 +3584,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) | |||
| 3494 | } else { | 3584 | } else { |
| 3495 | log_level = 0; | 3585 | log_level = 0; |
| 3496 | } | 3586 | } |
| 3587 | if (attr->prog_flags & BPF_F_STRICT_ALIGNMENT) | ||
| 3588 | env->strict_alignment = true; | ||
| 3589 | else | ||
| 3590 | env->strict_alignment = false; | ||
| 3497 | 3591 | ||
| 3498 | ret = replace_map_fd_with_map_ptr(env); | 3592 | ret = replace_map_fd_with_map_ptr(env); |
| 3499 | if (ret < 0) | 3593 | if (ret < 0) |
| @@ -3599,6 +3693,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops, | |||
| 3599 | mutex_lock(&bpf_verifier_lock); | 3693 | mutex_lock(&bpf_verifier_lock); |
| 3600 | 3694 | ||
| 3601 | log_level = 0; | 3695 | log_level = 0; |
| 3696 | env->strict_alignment = false; | ||
| 3602 | 3697 | ||
| 3603 | env->explored_states = kcalloc(env->prog->len, | 3698 | env->explored_states = kcalloc(env->prog->len, |
| 3604 | sizeof(struct bpf_verifier_state_list *), | 3699 | sizeof(struct bpf_verifier_state_list *), |
