All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Daniel Borkmann <daniel@iogearbox.net>,
	Alexei Starovoitov <ast@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Jiri Slaby <jslaby@suse.cz>
Subject: [PATCH 4.4 63/87] bpf: add bpf_patch_insn_single helper
Date: Mon, 15 Jan 2018 13:35:02 +0100	[thread overview]
Message-ID: <20180115123356.110622090@linuxfoundation.org> (raw)
In-Reply-To: <20180115123349.252309699@linuxfoundation.org>

4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Daniel Borkmann <daniel@iogearbox.net>

commit c237ee5eb33bf19fe0591c04ff8db19da7323a83 upstream.

Move the functionality to patch instructions out of the verifier
code and into the core as the new bpf_patch_insn_single() helper
will be needed later on for blinding as well. No changes in
functionality.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


---
 include/linux/filter.h |    3 ++
 kernel/bpf/core.c      |   71 +++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/bpf/verifier.c  |   53 ++++++------------------------------
 3 files changed, 83 insertions(+), 44 deletions(-)

--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -466,6 +466,9 @@ u64 __bpf_call_base(u64 r1, u64 r2, u64
 void bpf_int_jit_compile(struct bpf_prog *fp);
 bool bpf_helper_changes_skb_data(void *func);
 
+struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
+				       const struct bpf_insn *patch, u32 len);
+
 #ifdef CONFIG_BPF_JIT
 typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
 
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -137,6 +137,77 @@ void __bpf_prog_free(struct bpf_prog *fp
 }
 EXPORT_SYMBOL_GPL(__bpf_prog_free);
 
+static bool bpf_is_jmp_and_has_target(const struct bpf_insn *insn)
+{
+	return BPF_CLASS(insn->code) == BPF_JMP  &&
+	       /* Call and Exit are both special jumps with no
+		* target inside the BPF instruction image.
+		*/
+	       BPF_OP(insn->code) != BPF_CALL &&
+	       BPF_OP(insn->code) != BPF_EXIT;
+}
+
+static void bpf_adj_branches(struct bpf_prog *prog, u32 pos, u32 delta)
+{
+	struct bpf_insn *insn = prog->insnsi;
+	u32 i, insn_cnt = prog->len;
+
+	for (i = 0; i < insn_cnt; i++, insn++) {
+		if (!bpf_is_jmp_and_has_target(insn))
+			continue;
+
+		/* Adjust offset of jmps if we cross boundaries. */
+		if (i < pos && i + insn->off + 1 > pos)
+			insn->off += delta;
+		else if (i > pos + delta && i + insn->off + 1 <= pos + delta)
+			insn->off -= delta;
+	}
+}
+
+struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
+				       const struct bpf_insn *patch, u32 len)
+{
+	u32 insn_adj_cnt, insn_rest, insn_delta = len - 1;
+	struct bpf_prog *prog_adj;
+
+	/* Since our patchlet doesn't expand the image, we're done. */
+	if (insn_delta == 0) {
+		memcpy(prog->insnsi + off, patch, sizeof(*patch));
+		return prog;
+	}
+
+	insn_adj_cnt = prog->len + insn_delta;
+
+	/* Several new instructions need to be inserted. Make room
+	 * for them. Likely, there's no need for a new allocation as
+	 * last page could have large enough tailroom.
+	 */
+	prog_adj = bpf_prog_realloc(prog, bpf_prog_size(insn_adj_cnt),
+				    GFP_USER);
+	if (!prog_adj)
+		return NULL;
+
+	prog_adj->len = insn_adj_cnt;
+
+	/* Patching happens in 3 steps:
+	 *
+	 * 1) Move over tail of insnsi from next instruction onwards,
+	 *    so we can patch the single target insn with one or more
+	 *    new ones (patching is always from 1 to n insns, n > 0).
+	 * 2) Inject new instructions at the target location.
+	 * 3) Adjust branch offsets if necessary.
+	 */
+	insn_rest = insn_adj_cnt - off - len;
+
+	memmove(prog_adj->insnsi + off + len, prog_adj->insnsi + off + 1,
+		sizeof(*patch) * insn_rest);
+	memcpy(prog_adj->insnsi + off, patch, sizeof(*patch) * len);
+
+	bpf_adj_branches(prog_adj, off, insn_delta);
+
+	return prog_adj;
+}
+
 #ifdef CONFIG_BPF_JIT
 struct bpf_binary_header *
 bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2098,26 +2098,6 @@ static void convert_pseudo_ld_imm64(stru
 			insn->src_reg = 0;
 }
 
-static void adjust_branches(struct bpf_prog *prog, int pos, int delta)
-{
-	struct bpf_insn *insn = prog->insnsi;
-	int insn_cnt = prog->len;
-	int i;
-
-	for (i = 0; i < insn_cnt; i++, insn++) {
-		if (BPF_CLASS(insn->code) != BPF_JMP ||
-		    BPF_OP(insn->code) == BPF_CALL ||
-		    BPF_OP(insn->code) == BPF_EXIT)
-			continue;
-
-		/* adjust offset of jmps if necessary */
-		if (i < pos && i + insn->off + 1 > pos)
-			insn->off += delta;
-		else if (i > pos + delta && i + insn->off + 1 <= pos + delta)
-			insn->off -= delta;
-	}
-}
-
 /* convert load instructions that access fields of 'struct __sk_buff'
  * into sequence of instructions that access fields of 'struct sk_buff'
  */
@@ -2127,14 +2107,15 @@ static int convert_ctx_accesses(struct v
 	int insn_cnt = env->prog->len;
 	struct bpf_insn insn_buf[16];
 	struct bpf_prog *new_prog;
-	u32 cnt;
-	int i;
 	enum bpf_access_type type;
+	int i;
 
 	if (!env->prog->aux->ops->convert_ctx_access)
 		return 0;
 
 	for (i = 0; i < insn_cnt; i++, insn++) {
+		u32 insn_delta, cnt;
+
 		if (insn->code == (BPF_LDX | BPF_MEM | BPF_W))
 			type = BPF_READ;
 		else if (insn->code == (BPF_STX | BPF_MEM | BPF_W))
@@ -2156,34 +2137,18 @@ static int convert_ctx_accesses(struct v
 			return -EINVAL;
 		}
 
-		if (cnt == 1) {
-			memcpy(insn, insn_buf, sizeof(*insn));
-			continue;
-		}
-
-		/* several new insns need to be inserted. Make room for them */
-		insn_cnt += cnt - 1;
-		new_prog = bpf_prog_realloc(env->prog,
-					    bpf_prog_size(insn_cnt),
-					    GFP_USER);
+		new_prog = bpf_patch_insn_single(env->prog, i, insn_buf, cnt);
 		if (!new_prog)
 			return -ENOMEM;
 
-		new_prog->len = insn_cnt;
-
-		memmove(new_prog->insnsi + i + cnt, new_prog->insns + i + 1,
-			sizeof(*insn) * (insn_cnt - i - cnt));
-
-		/* copy substitute insns in place of load instruction */
-		memcpy(new_prog->insnsi + i, insn_buf, sizeof(*insn) * cnt);
-
-		/* adjust branches in the whole program */
-		adjust_branches(new_prog, i, cnt - 1);
+		insn_delta = cnt - 1;
 
 		/* keep walking new program and skip insns we just inserted */
 		env->prog = new_prog;
-		insn = new_prog->insnsi + i + cnt - 1;
-		i += cnt - 1;
+		insn      = new_prog->insnsi + i + insn_delta;
+
+		insn_cnt += insn_delta;
+		i        += insn_delta;
 	}
 
 	return 0;

  parent reply	other threads:[~2018-01-15 12:40 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-15 12:33 [PATCH 4.4 00/87] 4.4.112-stable review Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 01/87] dm bufio: fix shrinker scans when (nr_to_scan < retain_target) Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 02/87] KVM: Fix stack-out-of-bounds read in write_mmio Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 03/87] can: gs_usb: fix return value of the "set_bittiming" callback Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 04/87] IB/srpt: Disable RDMA access by the initiator Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 05/87] MIPS: Validate PR_SET_FP_MODE prctl(2) requests against the ABI of the task Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 06/87] MIPS: Factor out NT_PRFPREG regset access helpers Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 07/87] MIPS: Guard against any partial write attempt with PTRACE_SETREGSET Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 08/87] MIPS: Consistently handle buffer counter " Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 09/87] MIPS: Fix an FCSR access API regression with NT_PRFPREG and MSA Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 10/87] MIPS: Also verify sizeof `elf_fpreg_t with PTRACE_SETREGSET Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 11/87] MIPS: Disallow outsized PTRACE_SETREGSET NT_PRFPREG regset accesses Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 12/87] net/mac80211/debugfs.c: prevent build failure with CONFIG_UBSAN=y Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 13/87] kvm: vmx: Scrub hardware GPRs at VM-exit Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 14/87] x86/vsdo: Fix build on PARAVIRT_CLOCK=y, KVM_GUEST=n Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 15/87] x86/acpi: Handle SCI interrupts above legacy space gracefully Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 16/87] iommu/arm-smmu-v3: Dont free page table ops twice Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 17/87] ALSA: pcm: Remove incorrect snd_BUG_ON() usages Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 18/87] ALSA: pcm: Add missing error checks in OSS emulation plugin builder Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 19/87] ALSA: pcm: Abort properly at pending signal in OSS read/write loops Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 20/87] ALSA: pcm: Allow aborting mutex lock at " Greg Kroah-Hartman
2018-01-23 23:35   ` Ben Hutchings
2018-02-12  8:34     ` Takashi Iwai
2018-02-14 16:20       ` Ben Hutchings
2018-02-14 16:43         ` Takashi Iwai
2018-01-15 12:34 ` [PATCH 4.4 21/87] ALSA: aloop: Release cable upon open error path Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 22/87] ALSA: aloop: Fix inconsistent format due to incomplete rule Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 23/87] ALSA: aloop: Fix racy hw constraints adjustment Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 24/87] x86/acpi: Reduce code duplication in mp_override_legacy_irq() Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 25/87] mm/compaction: fix invalid free_pfn and compact_cached_free_pfn Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 26/87] mm/compaction: pass only pageblock aligned range to pageblock_pfn_to_page Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 27/87] mm/page-writeback: fix dirty_ratelimit calculation Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 28/87] mm/zswap: use workqueue to destroy pool Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 29/87] zswap: dont param_set_charp while holding spinlock Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 30/87] locks: dont check for race with close when setting OFD lock Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 31/87] futex: Replace barrier() in unqueue_me() with READ_ONCE() Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 32/87] locking/mutex: Allow next waiter lockless wakeup Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 33/87] [media] usbvision fix overflow of interfaces array Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 34/87] usb: musb: ux500: Fix NULL pointer dereference at system PM Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 35/87] r8152: fix the wake event Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 36/87] r8152: use test_and_clear_bit Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 37/87] r8152: adjust ALDPS function Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 38/87] lan78xx: use skb_cow_head() to deal with cloned skbs Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 39/87] sr9700: " Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 40/87] smsc75xx: " Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 41/87] cx82310_eth: " Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 42/87] x86/mm/pat, /dev/mem: Remove superfluous error message Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 43/87] hwrng: core - sleep interruptible in read Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 44/87] sysrq: Fix warning in sysrq generated crash Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 45/87] xhci: Fix ring leak in failure path of xhci_alloc_virt_device() Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 46/87] Revert "userfaultfd: selftest: vm: allow to build in vm/ directory" Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 47/87] x86/pti/efi: broken conversion from efi to kernel page table Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 48/87] 8021q: fix a memory leak for VLAN 0 device Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 49/87] ip6_tunnel: disable dst caching if tunnel is dual-stack Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 50/87] net: core: fix module type in sock_diag_bind Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 51/87] RDS: Heap OOB write in rds_message_alloc_sgs() Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 52/87] RDS: null pointer dereference in rds_atomic_free_op Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 53/87] sh_eth: fix TSU resource handling Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 54/87] sh_eth: fix SH7757 GEther initialization Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 55/87] net: stmmac: enable EEE in MII, GMII or RGMII only Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 56/87] ipv6: fix possible mem leaks in ipv6_make_skb() Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 57/87] crypto: algapi - fix NULL dereference in crypto_remove_spawns() Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 58/87] rbd: set max_segments to USHRT_MAX Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 59/87] x86/microcode/intel: Extend BDW late-loading with a revision check Greg Kroah-Hartman
2018-01-15 12:34 ` [PATCH 4.4 60/87] KVM: x86: Add memory barrier on vmcs field lookup Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 61/87] drm/vmwgfx: Potential off by one in vmw_view_add() Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 62/87] kaiser: Set _PAGE_NX only if supported Greg Kroah-Hartman
2018-01-15 12:35 ` Greg Kroah-Hartman [this message]
2018-01-15 12:35 ` [PATCH 4.4 64/87] bpf: dont (ab)use instructions to store state Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 65/87] bpf: move fixup_bpf_calls() function Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 66/87] bpf: refactor fixup_bpf_calls() Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 67/87] bpf: adjust insn_aux_data when patching insns Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 68/87] bpf: prevent out-of-bounds speculation Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 69/87] bpf, array: fix overflow in max_entries and undefined behavior in index_mask Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 70/87] iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 71/87] target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 72/87] USB: serial: cp210x: add IDs for LifeScan OneTouch Verio IQ Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 73/87] USB: serial: cp210x: add new device ID ELV ALC 8xxx Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 74/87] usb: misc: usb3503: make sure reset is low for at least 100us Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 75/87] USB: fix usbmon BUG trigger Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 76/87] usbip: remove kernel addresses from usb device and urb debug msgs Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 77/87] staging: android: ashmem: fix a race condition in ASHMEM_SET_SIZE ioctl Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 78/87] Bluetooth: Prevent stack info leak from the EFS element Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 79/87] uas: ignore UAS for Norelsys NS1068(X) chips Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 80/87] e1000e: Fix e1000_check_for_copper_link_ich8lan return value Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 81/87] x86/Documentation: Add PTI description Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 82/87] sysfs/cpu: Add vulnerability folder Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 83/87] x86/cpu: Implement CPU vulnerabilites sysfs functions Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 84/87] sysfs/cpu: Fix typos in vulnerability documentation Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 85/87] x86/alternatives: Fix optimize_nops() checking Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 86/87] x86/alternatives: Add missing \n at end of ALTERNATIVE inline asm Greg Kroah-Hartman
2018-01-15 12:35 ` [PATCH 4.4 87/87] selftests/x86: Add test_vsyscall Greg Kroah-Hartman
2018-01-15 13:01 ` [PATCH 4.4 00/87] 4.4.112-stable review Greg Kroah-Hartman
2018-01-15 13:47 ` Greg Kroah-Hartman
2018-01-15 20:24   ` Christoph Biedl
2018-01-15 20:29     ` Christoph Biedl
2018-01-15 16:28 ` kernelci.org bot
2018-01-15 16:39 ` Nathan Chancellor
2018-01-15 16:39   ` Nathan Chancellor
2018-01-15 18:02   ` Greg Kroah-Hartman
2018-01-15 18:02     ` Greg Kroah-Hartman
2018-01-15 21:59 ` Dan Rue
2018-01-16  5:53   ` Greg Kroah-Hartman
2018-01-16 11:22     ` Naresh Kamboju
2018-01-16 12:15       ` Greg Kroah-Hartman
2018-01-16 14:29 ` Guenter Roeck
2018-01-16 20:24 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180115123356.110622090@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=jslaby@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.