Skip to content

Commit 9f32bfe

Browse files
mannkafaiAlexei Starovoitov
authored andcommitted
selftests/bpf: Add test for conditional jumps on same scalar register
Add test cases to verify the correctness of the BPF verifier's branch analysis when conditional jumps are performed on the same scalar register. And make sure that JGT does not trigger verifier BUG. Signed-off-by: KaFai Wan <[email protected]> Acked-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent d43ad9d commit 9f32bfe

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

tools/testing/selftests/bpf/progs/verifier_bounds.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,4 +1709,158 @@ __naked void jeq_disagreeing_tnums(void *ctx)
17091709
: __clobber_all);
17101710
}
17111711

1712+
SEC("socket")
1713+
__description("conditional jump on same register, branch taken")
1714+
__not_msg("20: (b7) r0 = 1 {{.*}} R0=1")
1715+
__success __log_level(2)
1716+
__retval(0) __flag(BPF_F_TEST_REG_INVARIANTS)
1717+
__naked void condition_jump_on_same_register(void *ctx)
1718+
{
1719+
asm volatile(" \
1720+
call %[bpf_get_prandom_u32]; \
1721+
w8 = 0x80000000; \
1722+
r0 &= r8; \
1723+
if r0 == r0 goto +1; \
1724+
goto l1_%=; \
1725+
if r0 >= r0 goto +1; \
1726+
goto l1_%=; \
1727+
if r0 s>= r0 goto +1; \
1728+
goto l1_%=; \
1729+
if r0 <= r0 goto +1; \
1730+
goto l1_%=; \
1731+
if r0 s<= r0 goto +1; \
1732+
goto l1_%=; \
1733+
if r0 != r0 goto l1_%=; \
1734+
if r0 > r0 goto l1_%=; \
1735+
if r0 s> r0 goto l1_%=; \
1736+
if r0 < r0 goto l1_%=; \
1737+
if r0 s< r0 goto l1_%=; \
1738+
l0_%=: r0 = 0; \
1739+
exit; \
1740+
l1_%=: r0 = 1; \
1741+
exit; \
1742+
" :
1743+
: __imm(bpf_get_prandom_u32)
1744+
: __clobber_all);
1745+
}
1746+
1747+
SEC("socket")
1748+
__description("jset on same register, constant value branch taken")
1749+
__not_msg("7: (b7) r0 = 1 {{.*}} R0=1")
1750+
__success __log_level(2)
1751+
__retval(0) __flag(BPF_F_TEST_REG_INVARIANTS)
1752+
__naked void jset_on_same_register_1(void *ctx)
1753+
{
1754+
asm volatile(" \
1755+
r0 = 0; \
1756+
if r0 & r0 goto l1_%=; \
1757+
r0 = 1; \
1758+
if r0 & r0 goto +1; \
1759+
goto l1_%=; \
1760+
l0_%=: r0 = 0; \
1761+
exit; \
1762+
l1_%=: r0 = 1; \
1763+
exit; \
1764+
" :
1765+
: __imm(bpf_get_prandom_u32)
1766+
: __clobber_all);
1767+
}
1768+
1769+
SEC("socket")
1770+
__description("jset on same register, scalar value branch taken")
1771+
__not_msg("12: (b7) r0 = 1 {{.*}} R0=1")
1772+
__success __log_level(2)
1773+
__retval(0) __flag(BPF_F_TEST_REG_INVARIANTS)
1774+
__naked void jset_on_same_register_2(void *ctx)
1775+
{
1776+
asm volatile(" \
1777+
/* range [1;2] */ \
1778+
call %[bpf_get_prandom_u32]; \
1779+
r0 &= 0x1; \
1780+
r0 += 1; \
1781+
if r0 & r0 goto +1; \
1782+
goto l1_%=; \
1783+
/* range [-2;-1] */ \
1784+
call %[bpf_get_prandom_u32]; \
1785+
r0 &= 0x1; \
1786+
r0 -= 2; \
1787+
if r0 & r0 goto +1; \
1788+
goto l1_%=; \
1789+
l0_%=: r0 = 0; \
1790+
exit; \
1791+
l1_%=: r0 = 1; \
1792+
exit; \
1793+
" :
1794+
: __imm(bpf_get_prandom_u32)
1795+
: __clobber_all);
1796+
}
1797+
1798+
SEC("socket")
1799+
__description("jset on same register, scalar value unknown branch 1")
1800+
__msg("3: (b7) r0 = 0 {{.*}} R0=0")
1801+
__msg("5: (b7) r0 = 1 {{.*}} R0=1")
1802+
__success __log_level(2)
1803+
__flag(BPF_F_TEST_REG_INVARIANTS)
1804+
__naked void jset_on_same_register_3(void *ctx)
1805+
{
1806+
asm volatile(" \
1807+
/* range [0;1] */ \
1808+
call %[bpf_get_prandom_u32]; \
1809+
r0 &= 0x1; \
1810+
if r0 & r0 goto l1_%=; \
1811+
l0_%=: r0 = 0; \
1812+
exit; \
1813+
l1_%=: r0 = 1; \
1814+
exit; \
1815+
" :
1816+
: __imm(bpf_get_prandom_u32)
1817+
: __clobber_all);
1818+
}
1819+
1820+
SEC("socket")
1821+
__description("jset on same register, scalar value unknown branch 2")
1822+
__msg("4: (b7) r0 = 0 {{.*}} R0=0")
1823+
__msg("6: (b7) r0 = 1 {{.*}} R0=1")
1824+
__success __log_level(2)
1825+
__flag(BPF_F_TEST_REG_INVARIANTS)
1826+
__naked void jset_on_same_register_4(void *ctx)
1827+
{
1828+
asm volatile(" \
1829+
/* range [-1;0] */ \
1830+
call %[bpf_get_prandom_u32]; \
1831+
r0 &= 0x1; \
1832+
r0 -= 1; \
1833+
if r0 & r0 goto l1_%=; \
1834+
l0_%=: r0 = 0; \
1835+
exit; \
1836+
l1_%=: r0 = 1; \
1837+
exit; \
1838+
" :
1839+
: __imm(bpf_get_prandom_u32)
1840+
: __clobber_all);
1841+
}
1842+
1843+
SEC("socket")
1844+
__description("jset on same register, scalar value unknown branch 3")
1845+
__msg("4: (b7) r0 = 0 {{.*}} R0=0")
1846+
__msg("6: (b7) r0 = 1 {{.*}} R0=1")
1847+
__success __log_level(2)
1848+
__flag(BPF_F_TEST_REG_INVARIANTS)
1849+
__naked void jset_on_same_register_5(void *ctx)
1850+
{
1851+
asm volatile(" \
1852+
/* range [-1;1] */ \
1853+
call %[bpf_get_prandom_u32]; \
1854+
r0 &= 0x2; \
1855+
r0 -= 1; \
1856+
if r0 & r0 goto l1_%=; \
1857+
l0_%=: r0 = 0; \
1858+
exit; \
1859+
l1_%=: r0 = 1; \
1860+
exit; \
1861+
" :
1862+
: __imm(bpf_get_prandom_u32)
1863+
: __clobber_all);
1864+
}
1865+
17121866
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)