Earlier quoted context omitted.
I don't know how they define `MAX`, but I'm guessing it's a typical "a>b?a:b". In function `elf_read_pintable` the `npins` is defined as signed int and `sysno` as unsigned int. So this comparison will be unsigned and will allow to set `npins` to any value, even negative: npins = MAX(npins, syscalls[i].sysno) Then `SYS_kbind` seems to be a signed int. So this comparison will be signed and "fix" the negative `npins` to…
> I don't know how they define `MAX`, but I'm guessing it's a typical "a>b?a:b" Indeed: https://github.com/openbsd/src/blob/master/sys/sys/param.h#L... > Then `SYS_kbind` seems to be a signed int. It's an untyped #define: https://github.com/openbsd/src/blob/master/sys/sys/syscall.h... I believe your whole analysis is correct, that running an elf file with an openbsd.syscalls entry with .sysno > INT_MAX will allow an…
Pure decimal integer literals (like 86) are typed as "int" in C, rather than being typeless and triggering type inference. This is a pain when you accidentally write something like this:
uint64_t n = 1
On modern desktop platforms, an int is 32 bits, so 1 Regardless, it's not relevant here, because if an integer and an unsigned integer of the same size are compared the integer is implicitly cast to unsigned integer, and 86 is fine for both signed and unsigned integers (so "MAX(npins, SYS_kbind)" is safe).