0227-bpf-fix-incorrect-sign-extension-in-check_alu_op.patch 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. From 652c6cabaf30e4c75f7dc2c42a33a8f066d7df2c Mon Sep 17 00:00:00 2001
  2. From: Jann Horn <[email protected]>
  3. Date: Thu, 4 Jan 2018 08:01:22 -0600
  4. Subject: [PATCH 227/232] bpf: fix incorrect sign extension in check_alu_op()
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. [ Upstream commit 95a762e2c8c942780948091f8f2a4f32fce1ac6f ]
  9. Distinguish between
  10. BPF_ALU64|BPF_MOV|BPF_K (load 32-bit immediate, sign-extended to 64-bit)
  11. and BPF_ALU|BPF_MOV|BPF_K (load 32-bit immediate, zero-padded to 64-bit);
  12. only perform sign extension in the first case.
  13. Starting with v4.14, this is exploitable by unprivileged users as long as
  14. the unprivileged_bpf_disabled sysctl isn't set.
  15. Debian assigned CVE-2017-16995 for this issue.
  16. v3:
  17. - add CVE number (Ben Hutchings)
  18. Fixes: 484611357c19 ("bpf: allow access into map value arrays")
  19. Signed-off-by: Jann Horn <[email protected]>
  20. Acked-by: Edward Cree <[email protected]>
  21. Signed-off-by: Alexei Starovoitov <[email protected]>
  22. Signed-off-by: Daniel Borkmann <[email protected]>
  23. CVE-2017-16995
  24. Signed-off-by: Seth Forshee <[email protected]>
  25. Signed-off-by: Andy Whitcroft <[email protected]>
  26. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  27. (cherry picked from commit 868c88129c7567525dbde3cb6989a5acd478bd80)
  28. Signed-off-by: Fabian Grünbichler <[email protected]>
  29. ---
  30. kernel/bpf/verifier.c | 15 +++++++++++----
  31. 1 file changed, 11 insertions(+), 4 deletions(-)
  32. diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
  33. index 4321625fe32a..cdfa07a4ef27 100644
  34. --- a/kernel/bpf/verifier.c
  35. +++ b/kernel/bpf/verifier.c
  36. @@ -2048,12 +2048,19 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
  37. /* case: R = imm
  38. * remember the value we stored into this reg
  39. */
  40. + u64 imm;
  41. +
  42. + if (BPF_CLASS(insn->code) == BPF_ALU64)
  43. + imm = insn->imm;
  44. + else
  45. + imm = (u32)insn->imm;
  46. +
  47. regs[insn->dst_reg].type = CONST_IMM;
  48. - regs[insn->dst_reg].imm = insn->imm;
  49. + regs[insn->dst_reg].imm = imm;
  50. regs[insn->dst_reg].id = 0;
  51. - regs[insn->dst_reg].max_value = insn->imm;
  52. - regs[insn->dst_reg].min_value = insn->imm;
  53. - regs[insn->dst_reg].min_align = calc_align(insn->imm);
  54. + regs[insn->dst_reg].max_value = imm;
  55. + regs[insn->dst_reg].min_value = imm;
  56. + regs[insn->dst_reg].min_align = calc_align(imm);
  57. regs[insn->dst_reg].value_from_signed = false;
  58. }
  59. --
  60. 2.14.2