mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
x86: bpf_jit: fix FROM_BE16 and FROM_LE16/32 instructions
FROM_BE16:
'ror %reg, 8' doesn't clear upper bits of the register,
so use additional 'movzwl' insn to zero extend 16 bits into 64
FROM_LE16:
should zero extend lower 16 bits into 64 bit
FROM_LE32:
should zero extend lower 32 bits into 64 bit
Fixes: 89aa075832
("net: sock: allow eBPF programs to be attached to sockets")
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e3d8ecb70e
commit
343f845b37
1 changed files with 28 additions and 0 deletions
|
@ -559,6 +559,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
if (is_ereg(dst_reg))
|
||||
EMIT1(0x41);
|
||||
EMIT3(0xC1, add_1reg(0xC8, dst_reg), 8);
|
||||
|
||||
/* emit 'movzwl eax, ax' */
|
||||
if (is_ereg(dst_reg))
|
||||
EMIT3(0x45, 0x0F, 0xB7);
|
||||
else
|
||||
EMIT2(0x0F, 0xB7);
|
||||
EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
|
||||
break;
|
||||
case 32:
|
||||
/* emit 'bswap eax' to swap lower 4 bytes */
|
||||
|
@ -577,6 +584,27 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
break;
|
||||
|
||||
case BPF_ALU | BPF_END | BPF_FROM_LE:
|
||||
switch (imm32) {
|
||||
case 16:
|
||||
/* emit 'movzwl eax, ax' to zero extend 16-bit
|
||||
* into 64 bit
|
||||
*/
|
||||
if (is_ereg(dst_reg))
|
||||
EMIT3(0x45, 0x0F, 0xB7);
|
||||
else
|
||||
EMIT2(0x0F, 0xB7);
|
||||
EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
|
||||
break;
|
||||
case 32:
|
||||
/* emit 'mov eax, eax' to clear upper 32-bits */
|
||||
if (is_ereg(dst_reg))
|
||||
EMIT1(0x45);
|
||||
EMIT2(0x89, add_2reg(0xC0, dst_reg, dst_reg));
|
||||
break;
|
||||
case 64:
|
||||
/* nop */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* ST: *(u8*)(dst_reg + off) = imm */
|
||||
|
|
Loading…
Reference in a new issue