On Tue, Jan 2, 2024 at 8:40 AM Eduard Zingerman <eddyz87@xxxxxxxxx> wrote: > > On Fri, 2023-12-29 at 17:31 -0800, Maciej Żenczykowski wrote: > > I have a relatively complex program that fails to load on 6.5.6 with a > > > > if (data + 98 != data_end) return TC_ACT_SHOT; > > > > check, that loads fine if I change the above != to (a you would think > > weaker) > check. > > > > It's not important, hit this while debugging, and I don't know if the > > cause is the verifier treating != differently than > or the compiler > > optimizing != somehow... but my gut feeling is on the former: some > > verifier logic special cases > without doing something similar for the > > stronger != comparison. > > Please note the following comment in verifier.c:find_good_pkt_pointers(): > > /* Examples for register markings: > * > * pkt_data in dst register: > * > * r2 = r3; > * r2 += 8; > * if (r2 > pkt_end) goto <handle exception> > * <access okay> > * > * r2 = r3; > * r2 += 8; > * if (r2 < pkt_end) goto <access okay> > * <handle exception> > * > * Where: > * r2 == dst_reg, pkt_end == src_reg > * r2=pkt(id=n,off=8,r=0) > * r3=pkt(id=n,off=0,r=0) > * > ... a few lines skipped ... > * > * Find register r3 and mark its range as r3=pkt(id=n,off=0,r=8) > * or r3=pkt(id=n,off=0,r=8-1), so that range of bytes [r3, r3 + 8) > * and [r3, r3 + 8-1) respectively is safe to access depending on > * the check. > */ > > In other words, from 'data + 98 > data_end' follows that 'data + 98 <= data_end', > which means that accessible range for 'data' pointer could be incremented by 97 bytes. > However, the 'data + 98 != data_end' is not sufficient to conclude that 98 more bytes > are available, as e.g. the following: 'data + 42 == data_end' could be true at the same time. > Does this makes sense? Nope, you got your logic reversed. The check is: if (data + 98 != data_end) return; so now (after this check) you *know* that 'data + 98 == data_end' and thus you know there are *exactly* 98 valid bytes. > Thanks, > Eduard