History

Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Pull bpf fixes from Alexei Starovoitov: - Fix how linked registers track zero extension of subregisters (Daniel Borkmann) - Fix unsound scalar fork for OR instructions (Daniel Wade) - Fix exception exit lock check for subprogs (Ihor Solodrai) - Fix undefined behavior in interpreter for SDIV/SMOD instructions (Jenny Guanni Qu) - Release module's BTF when module is unloaded (Kumar Kartikeya Dwivedi) - Fix constant blinding for PROBE_MEM32 instructions (Sachin Kumar) - Reset register ID for END instructions to prevent incorrect value tracking (Yazhou Tang) * tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: selftests/bpf: Add a test cases for sync_linked_regs regarding zext propagation bpf: Fix sync_linked_regs regarding BPF_ADD_CONST32 zext propagation selftests/bpf: Add tests for maybe_fork_scalars() OR vs AND handling bpf: Fix unsound scalar forking in maybe_fork_scalars() for BPF_OR selftests/bpf: Add tests for sdiv32/smod32 with INT_MIN dividend bpf: Fix undefined behavior in interpreter sdiv/smod for INT_MIN selftests/bpf: Add tests for bpf_throw lock leak from subprogs bpf: Fix exception exit lock checking for subprogs bpf: Release module BTF IDR before module unload selftests/bpf: Fix pkg-config call on static builds bpf: Fix constant blinding for PROBE_MEM32 stores selftests/bpf: Add test for BPF_END register ID reset bpf: Reset register ID for BPF_END value tracking

Linus Torvalds committed 7 months ago

Commit d5273fd2 parents ac57fa9 4a04d139 files · +416 −24Browse files

Showing the changes to kernel (3 of 9 files). Show all

Unified · Split

3 files
  1. kernel/bpf/btf.c +20 −4
  2. kernel/bpf/core.c +35 −8
  3. kernel/bpf/verifier.c +25 −8
kernel/bpf/btf.c+20−4
@@ -1787,7 +1787,16 @@ static void btf_free_id(struct btf *btf) · 1786 unmodified lines
1787 * of the _bh() version.1787 * of the _bh() version.
1788 */1788 */
1789 spin_lock_irqsave(&btf_idr_lock, flags);1789 spin_lock_irqsave(&btf_idr_lock, flags);
1790 idr_remove(&btf_idr, btf->id);1790 if (btf->id) {
1791 idr_remove(&btf_idr, btf->id);
1792 /*
1793 * Clear the id here to make this function idempotent, since it will get
1794 * called a couple of times for module BTFs: on module unload, and then
1795 * the final btf_put(). btf_alloc_id() starts IDs with 1, so we can use
1796 * 0 as sentinel value.
1797 */
1798 WRITE_ONCE(btf->id, 0);
1799 }
1791 spin_unlock_irqrestore(&btf_idr_lock, flags);1800 spin_unlock_irqrestore(&btf_idr_lock, flags);
1792}1801}
1793 1802
@@ -8115,7 +8124,7 @@ static void bpf_btf_show_fdinfo(struct seq_file *m, struct file *filp) · 6321 unmodified lines
8115{8124{
8116 const struct btf *btf = filp->private_data;8125 const struct btf *btf = filp->private_data;
8117 8126
8118 seq_printf(m, "btf_id:\t%u\n", btf->id);8127 seq_printf(m, "btf_id:\t%u\n", READ_ONCE(btf->id));
8119}8128}
8120#endif8129#endif
8121 8130
@@ -8197,7 +8206,7 @@ int btf_get_info_by_fd(const struct btf *btf, · 75 unmodified lines
8197 if (copy_from_user(&info, uinfo, info_copy))8206 if (copy_from_user(&info, uinfo, info_copy))
8198 return -EFAULT;8207 return -EFAULT;
8199 8208
8200 info.id = btf->id;8209 info.id = READ_ONCE(btf->id);
8201 ubtf = u64_to_user_ptr(info.btf);8210 ubtf = u64_to_user_ptr(info.btf);
8202 btf_copy = min_t(u32, btf->data_size, info.btf_size);8211 btf_copy = min_t(u32, btf->data_size, info.btf_size);
8203 if (copy_to_user(ubtf, btf->data, btf_copy))8212 if (copy_to_user(ubtf, btf->data, btf_copy))
@@ -8260,7 +8269,7 @@ int btf_get_fd_by_id(u32 id) · 56 unmodified lines
8260 8269
8261u32 btf_obj_id(const struct btf *btf)8270u32 btf_obj_id(const struct btf *btf)
8262{8271{
8263 return btf->id;8272 return READ_ONCE(btf->id);
8264}8273}
8265 8274
8266bool btf_is_kernel(const struct btf *btf)8275bool btf_is_kernel(const struct btf *btf)
@@ -8382,6 +8391,13 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, · 115 unmodified lines
8382 if (btf_mod->module != module)8391 if (btf_mod->module != module)
8383 continue;8392 continue;
8384 8393
8394 /*
8395 * For modules, we do the freeing of BTF IDR as soon as
8396 * module goes away to disable BTF discovery, since the
8397 * btf_try_get_module() on such BTFs will fail. This may
8398 * be called again on btf_put(), but it's ok to do so.
8399 */
8400 btf_free_id(btf_mod->btf);
8385 list_del(&btf_mod->list);8401 list_del(&btf_mod->list);
8386 if (btf_mod->sysfs_attr)8402 if (btf_mod->sysfs_attr)
8387 sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr);8403 sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr);
kernel/bpf/core.c+35−8
@@ -1422,6 +1422,27 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from, · 1421 unmodified lines
1422 *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd);1422 *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd);
1423 *to++ = BPF_STX_MEM(from->code, from->dst_reg, BPF_REG_AX, from->off);1423 *to++ = BPF_STX_MEM(from->code, from->dst_reg, BPF_REG_AX, from->off);
1424 break;1424 break;
1425
1426 case BPF_ST | BPF_PROBE_MEM32 | BPF_DW:
1427 case BPF_ST | BPF_PROBE_MEM32 | BPF_W:
1428 case BPF_ST | BPF_PROBE_MEM32 | BPF_H:
1429 case BPF_ST | BPF_PROBE_MEM32 | BPF_B:
1430 *to++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^
1431 from->imm);
1432 *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd);
1433 /*
1434 * Cannot use BPF_STX_MEM() macro here as it
1435 * hardcodes BPF_MEM mode, losing PROBE_MEM32
1436 * and breaking arena addressing in the JIT.
1437 */
1438 *to++ = (struct bpf_insn) {
1439 .code = BPF_STX | BPF_PROBE_MEM32 |
1440 BPF_SIZE(from->code),
1441 .dst_reg = from->dst_reg,
1442 .src_reg = BPF_REG_AX,
1443 .off = from->off,
1444 };
1445 break;
1425 }1446 }
1426out:1447out:
1427 return to - to_buff;1448 return to - to_buff;
@@ -1736,6 +1757,12 @@ bool bpf_opcode_in_insntable(u8 code) · 308 unmodified lines
1736}1757}
1737 1758
1738#ifndef CONFIG_BPF_JIT_ALWAYS_ON1759#ifndef CONFIG_BPF_JIT_ALWAYS_ON
1760/* Absolute value of s32 without undefined behavior for S32_MIN */
1761static u32 abs_s32(s32 x)
1762{
1763 return x >= 0 ? (u32)x : -(u32)x;
1764}
1765
1739/**1766/**
1740 * ___bpf_prog_run - run eBPF program on a given context1767 * ___bpf_prog_run - run eBPF program on a given context
1741 * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers1768 * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers
@@ -1900,8 +1927,8 @@ select_insn: · 158 unmodified lines
1900 DST = do_div(AX, (u32) SRC);1927 DST = do_div(AX, (u32) SRC);
1901 break;1928 break;
1902 case 1:1929 case 1:
1903 AX = abs((s32)DST);1930 AX = abs_s32((s32)DST);
1904 AX = do_div(AX, abs((s32)SRC));1931 AX = do_div(AX, abs_s32((s32)SRC));
1905 if ((s32)DST < 0)1932 if ((s32)DST < 0)
1906 DST = (u32)-AX;1933 DST = (u32)-AX;
1907 else1934 else
@@ -1928,8 +1955,8 @@ select_insn: · 20 unmodified lines
1928 DST = do_div(AX, (u32) IMM);1955 DST = do_div(AX, (u32) IMM);
1929 break;1956 break;
1930 case 1:1957 case 1:
1931 AX = abs((s32)DST);1958 AX = abs_s32((s32)DST);
1932 AX = do_div(AX, abs((s32)IMM));1959 AX = do_div(AX, abs_s32((s32)IMM));
1933 if ((s32)DST < 0)1960 if ((s32)DST < 0)
1934 DST = (u32)-AX;1961 DST = (u32)-AX;
1935 else1962 else
@@ -1955,8 +1982,8 @@ select_insn: · 19 unmodified lines
1955 DST = (u32) AX;1982 DST = (u32) AX;
1956 break;1983 break;
1957 case 1:1984 case 1:
1958 AX = abs((s32)DST);1985 AX = abs_s32((s32)DST);
1959 do_div(AX, abs((s32)SRC));1986 do_div(AX, abs_s32((s32)SRC));
1960 if (((s32)DST < 0) == ((s32)SRC < 0))1987 if (((s32)DST < 0) == ((s32)SRC < 0))
1961 DST = (u32)AX;1988 DST = (u32)AX;
1962 else1989 else
@@ -1982,8 +2009,8 @@ select_insn: · 19 unmodified lines
1982 DST = (u32) AX;2009 DST = (u32) AX;
1983 break;2010 break;
1984 case 1:2011 case 1:
1985 AX = abs((s32)DST);2012 AX = abs_s32((s32)DST);
1986 do_div(AX, abs((s32)IMM));2013 do_div(AX, abs_s32((s32)IMM));
1987 if (((s32)DST < 0) == ((s32)IMM < 0))2014 if (((s32)DST < 0) == ((s32)IMM < 0))
1988 DST = (u32)AX;2015 DST = (u32)AX;
1989 else2016 else
kernel/bpf/verifier.c+25−8
@@ -15910,6 +15910,13 @@ static void scalar_byte_swap(struct bpf_reg_state *dst_reg, struct bpf_insn *ins · 15909 unmodified lines
15910 /* Apply bswap if alu64 or switch between big-endian and little-endian machines */15910 /* Apply bswap if alu64 or switch between big-endian and little-endian machines */
15911 bool need_bswap = alu64 || (to_le == is_big_endian);15911 bool need_bswap = alu64 || (to_le == is_big_endian);
15912 15912
15913 /*
15914 * If the register is mutated, manually reset its scalar ID to break
15915 * any existing ties and avoid incorrect bounds propagation.
15916 */
15917 if (need_bswap || insn->imm == 16 || insn->imm == 32)
15918 dst_reg->id = 0;
15919
15913 if (need_bswap) {15920 if (need_bswap) {
15914 if (insn->imm == 16)15921 if (insn->imm == 16)
15915 dst_reg->var_off = tnum_bswap16(dst_reg->var_off);15922 dst_reg->var_off = tnum_bswap16(dst_reg->var_off);
@@ -15992,7 +15999,7 @@ static int maybe_fork_scalars(struct bpf_verifier_env *env, struct bpf_insn *ins · 76 unmodified lines
15992 else15999 else
15993 return 0;16000 return 0;
15994 16001
15995 branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);16002 branch = push_stack(env, env->insn_idx, env->insn_idx, false);
15996 if (IS_ERR(branch))16003 if (IS_ERR(branch))
15997 return PTR_ERR(branch);16004 return PTR_ERR(branch);
15998 16005
@@ -17408,6 +17415,12 @@ static void sync_linked_regs(struct bpf_verifier_env *env, struct bpf_verifier_s · 1409 unmodified lines
17408 continue;17415 continue;
17409 if ((reg->id & ~BPF_ADD_CONST) != (known_reg->id & ~BPF_ADD_CONST))17416 if ((reg->id & ~BPF_ADD_CONST) != (known_reg->id & ~BPF_ADD_CONST))
17410 continue;17417 continue;
17418 /*
17419 * Skip mixed 32/64-bit links: the delta relationship doesn't
17420 * hold across different ALU widths.
17421 */
17422 if (((reg->id ^ known_reg->id) & BPF_ADD_CONST) == BPF_ADD_CONST)
17423 continue;
17411 if ((!(reg->id & BPF_ADD_CONST) && !(known_reg->id & BPF_ADD_CONST)) ||17424 if ((!(reg->id & BPF_ADD_CONST) && !(known_reg->id & BPF_ADD_CONST)) ||
17412 reg->off == known_reg->off) {17425 reg->off == known_reg->off) {
17413 s32 saved_subreg_def = reg->subreg_def;17426 s32 saved_subreg_def = reg->subreg_def;
@@ -17435,7 +17448,7 @@ static void sync_linked_regs(struct bpf_verifier_env *env, struct bpf_verifier_s · 21 unmodified lines
17435 scalar32_min_max_add(reg, &fake_reg);17448 scalar32_min_max_add(reg, &fake_reg);
17436 scalar_min_max_add(reg, &fake_reg);17449 scalar_min_max_add(reg, &fake_reg);
17437 reg->var_off = tnum_add(reg->var_off, fake_reg.var_off);17450 reg->var_off = tnum_add(reg->var_off, fake_reg.var_off);
17438 if (known_reg->id & BPF_ADD_CONST32)17451 if ((reg->id | known_reg->id) & BPF_ADD_CONST32)
17439 zext_32_to_64(reg);17452 zext_32_to_64(reg);
17440 reg_bounds_sync(reg);17453 reg_bounds_sync(reg);
17441 }17454 }
@@ -19863,11 +19876,14 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, · 2421 unmodified lines
19863 * Also verify that new value satisfies old value range knowledge.19876 * Also verify that new value satisfies old value range knowledge.
19864 */19877 */
19865 19878
19866 /* ADD_CONST mismatch: different linking semantics */19879 /*
19867 if ((rold->id & BPF_ADD_CONST) && !(rcur->id & BPF_ADD_CONST))19880 * ADD_CONST flags must match exactly: BPF_ADD_CONST32 and
19868 return false;19881 * BPF_ADD_CONST64 have different linking semantics in
19869 19882 * sync_linked_regs() (alu32 zero-extends, alu64 does not),
19870 if (rold->id && !(rold->id & BPF_ADD_CONST) && (rcur->id & BPF_ADD_CONST))19883 * so pruning across different flag types is unsafe.
19884 */
19885 if (rold->id &&
19886 (rold->id & BPF_ADD_CONST) != (rcur->id & BPF_ADD_CONST))
19871 return false;19887 return false;
19872 19888
19873 /* Both have offset linkage: offsets must match */19889 /* Both have offset linkage: offsets must match */
@@ -20904,7 +20920,8 @@ static int process_bpf_exit_full(struct bpf_verifier_env *env, · 1030 unmodified lines
20904 * state when it exits.20920 * state when it exits.
20905 */20921 */
20906 int err = check_resource_leak(env, exception_exit,20922 int err = check_resource_leak(env, exception_exit,
20907 !env->cur_state->curframe,20923 exception_exit || !env->cur_state->curframe,
20924 exception_exit ? "bpf_throw" :
20908 "BPF_EXIT instruction in main prog");20925 "BPF_EXIT instruction in main prog");
20909 if (err)20926 if (err)
20910 return err;20927 return err;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t