bpf, docs: Fix modulo zero, division by zero, overflow, and underflow
Fix modulo zero, division by zero, overflow, and underflow. Also clarify how a negative immediate value is used in unsigned division. Signed-off-by: Dave Thaler <dthaler@microsoft.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20230124001218.827-1-dthaler1968@googlemail.com
This commit is contained in:
parent
ea403bb7b3
commit
0eb9d19e22
|
@ -99,19 +99,26 @@ code value description
|
||||||
BPF_ADD 0x00 dst += src
|
BPF_ADD 0x00 dst += src
|
||||||
BPF_SUB 0x10 dst -= src
|
BPF_SUB 0x10 dst -= src
|
||||||
BPF_MUL 0x20 dst \*= src
|
BPF_MUL 0x20 dst \*= src
|
||||||
BPF_DIV 0x30 dst /= src
|
BPF_DIV 0x30 dst = (src != 0) ? (dst / src) : 0
|
||||||
BPF_OR 0x40 dst \|= src
|
BPF_OR 0x40 dst \|= src
|
||||||
BPF_AND 0x50 dst &= src
|
BPF_AND 0x50 dst &= src
|
||||||
BPF_LSH 0x60 dst <<= src
|
BPF_LSH 0x60 dst <<= src
|
||||||
BPF_RSH 0x70 dst >>= src
|
BPF_RSH 0x70 dst >>= src
|
||||||
BPF_NEG 0x80 dst = ~src
|
BPF_NEG 0x80 dst = ~src
|
||||||
BPF_MOD 0x90 dst %= src
|
BPF_MOD 0x90 dst = (src != 0) ? (dst % src) : dst
|
||||||
BPF_XOR 0xa0 dst ^= src
|
BPF_XOR 0xa0 dst ^= src
|
||||||
BPF_MOV 0xb0 dst = src
|
BPF_MOV 0xb0 dst = src
|
||||||
BPF_ARSH 0xc0 sign extending shift right
|
BPF_ARSH 0xc0 sign extending shift right
|
||||||
BPF_END 0xd0 byte swap operations (see `Byte swap instructions`_ below)
|
BPF_END 0xd0 byte swap operations (see `Byte swap instructions`_ below)
|
||||||
======== ===== ==========================================================
|
======== ===== ==========================================================
|
||||||
|
|
||||||
|
Underflow and overflow are allowed during arithmetic operations, meaning
|
||||||
|
the 64-bit or 32-bit value will wrap. If eBPF program execution would
|
||||||
|
result in division by zero, the destination register is instead set to zero.
|
||||||
|
If execution would result in modulo by zero, for ``BPF_ALU64`` the value of
|
||||||
|
the destination register is unchanged whereas for ``BPF_ALU`` the upper
|
||||||
|
32 bits of the destination register are zeroed.
|
||||||
|
|
||||||
``BPF_ADD | BPF_X | BPF_ALU`` means::
|
``BPF_ADD | BPF_X | BPF_ALU`` means::
|
||||||
|
|
||||||
dst_reg = (u32) dst_reg + (u32) src_reg;
|
dst_reg = (u32) dst_reg + (u32) src_reg;
|
||||||
|
@ -128,6 +135,11 @@ BPF_END 0xd0 byte swap operations (see `Byte swap instructions`_ below)
|
||||||
|
|
||||||
dst_reg = dst_reg ^ imm32
|
dst_reg = dst_reg ^ imm32
|
||||||
|
|
||||||
|
Also note that the division and modulo operations are unsigned. Thus, for
|
||||||
|
``BPF_ALU``, 'imm' is first interpreted as an unsigned 32-bit value, whereas
|
||||||
|
for ``BPF_ALU64``, 'imm' is first sign extended to 64 bits and the result
|
||||||
|
interpreted as an unsigned 64-bit value. There are no instructions for
|
||||||
|
signed division or modulo.
|
||||||
|
|
||||||
Byte swap instructions
|
Byte swap instructions
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
Loading…
Reference in New Issue