• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vbpf / prevail / 30762301447
86%

Build:
DEFAULT BRANCH: main
Ran 02 Aug 2026 07:07PM UTC
Jobs 2
Files 79
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

02 Aug 2026 06:57PM UTC coverage: 86.872% (+0.05%) from 86.826%
30762301447

push

github

web-flow
Check the divisor a 32-bit division actually uses (fixes #1205) (#1217)

* Check the divisor a 32-bit division actually uses (fixes #1205)

A 32-bit DIV/MOD divides by the low half of the divisor register, but the
divide-by-zero check tested the full 64-bit value:

    const auto v = s.is_signed ? reg.svalue : reg.uvalue;
    require_value(dom.state, v != 0, "Possible division by zero");

So a divisor that is a nonzero multiple of 2^32 passed the check while the
runtime divides by zero:

    r1 = 1
    r1 <<= 32          ; uvalue = 0x1_0000_0000, entails uvalue != 0
    w0 /= w1           ; the CPU's divisor is (u32)r1 == 0

With allow_division_by_zero=false the verifier accepted a program it exists to
reject. This is not a memory-safety hole -- eBPF defines /0 as 0 and %0 as the
dividend, and the transformer models that -- but the checker and the transformer
disagreed about what the divisor is: the transformer already reads it as
eval_interval(z, 32) while the checker read all 64 bits.

ValidDivisor carried no width, so the checker could not tell the two cases
apart. Give it the is64 of the division that produced it, and on the 32-bit path
test the same 32-bit view of the divisor the transformer divides by. The 64-bit
path keeps the existing entailment check, which is more precise than an interval
test on a relational domain.

The assertion now prints as "w2 != 0" for a 32-bit division, matching the
llvm-objdump register-naming convention already used for instruction operands,
so the message says which half was checked. Its reg_name helper moves to file
scope in printing.cpp to be shared with the assertion printer.

Regression tests in udivmod.yaml and sdivmod.yaml divide and take the modulo,
signed and unsigned, by a register holding 2^32; all four are accepted without
the fix. Two further tests pin precision: a 32-bit division by 2^32 + 5 is still
accepted (it divides by 5), and a 64-bit division by 2^32 is still accepted,
since there the divisor i... (continued)

11 of 11 new or added lines in 3 files covered. (100.0%)

9357 of 10771 relevant lines covered (86.87%)

6270727.46 hits per line

Jobs
ID Job ID Ran Files Coverage
1 run-Debug - 30762301447.1 02 Aug 2026 08:05PM UTC 77
85.15
GitHub Action Run
2 run-Release - 30762301447.2 02 Aug 2026 07:07PM UTC 79
85.99
GitHub Action Run
Source Files on build 30762301447
  • Tree
  • List 79
  • Changed 7
  • Source Changed 4
  • Coverage Changed 6
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #30762301447
  • afee9dfa on github
  • Prev Build on main (#30757948978)
  • Next Build on main (#30764999553)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc