| From 664064c004083cca1b44334e0333a03793900bd1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 24 Jan 2023 00:12:18 +0000 |
| Subject: bpf, docs: Fix modulo zero, division by zero, overflow, and underflow |
| |
| From: Dave Thaler <dthaler@microsoft.com> |
| |
| [ Upstream commit 0eb9d19e2201068260e439a5c96dc85f9f3722a2 ] |
| |
| 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 |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| Documentation/bpf/instruction-set.rst | 16 ++++++++++++++-- |
| 1 file changed, 14 insertions(+), 2 deletions(-) |
| |
| diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/instruction-set.rst |
| index 5d798437dad47..3ba6475cfbfc7 100644 |
| --- a/Documentation/bpf/instruction-set.rst |
| +++ b/Documentation/bpf/instruction-set.rst |
| @@ -99,19 +99,26 @@ code value description |
| BPF_ADD 0x00 dst += src |
| BPF_SUB 0x10 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_AND 0x50 dst &= src |
| BPF_LSH 0x60 dst <<= src |
| BPF_RSH 0x70 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_MOV 0xb0 dst = src |
| BPF_ARSH 0xc0 sign extending shift right |
| 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:: |
| |
| dst_reg = (u32) dst_reg + (u32) src_reg; |
| @@ -128,6 +135,11 @@ BPF_END 0xd0 byte swap operations (see `Byte swap instructions`_ below) |
| |
| src_reg = src_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 |
| ~~~~~~~~~~~~~~~~~~~~~~ |
| -- |
| 2.39.2 |
| |