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 *), |