From 6f43038466454410817931a2afccbd0154973898 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 18 Jan 2018 05:38:40 +0000 Subject: [PATCH] Update to 4.14.14 Mostly done by Salvatore Bonaccorso. --- debian/changelog | 117 +- ...p-OOB-write-in-rds_message_alloc_sgs.patch | 34 - ...er-dereference-in-rds_atomic_free_op.patch | 32 - ...stack-info-leak-from-the-efs-element.patch | 48 - ...-verifier-log-state-into-a-structure.patch | 201 -- .../all/bpf-fix-integer-overflows.patch | 63 - ...verifier-log-into-verifier-environme.patch | 1667 ----------------- ...for_copper_link_ich8lan-return-value.patch | 60 - ...ack-out-of-bounds-read-in-write_mmio.patch | 153 -- .../bpf-avoid-abi-change-in-4.14.14.patch | 138 ++ debian/patches/series | 9 +- 11 files changed, 253 insertions(+), 2269 deletions(-) delete mode 100644 debian/patches/bugfix/all/RDS-Heap-OOB-write-in-rds_message_alloc_sgs.patch delete mode 100644 debian/patches/bugfix/all/RDS-null-pointer-dereference-in-rds_atomic_free_op.patch delete mode 100644 debian/patches/bugfix/all/bluetooth-prevent-stack-info-leak-from-the-efs-element.patch delete mode 100644 debian/patches/bugfix/all/bpf-encapsulate-verifier-log-state-into-a-structure.patch delete mode 100644 debian/patches/bugfix/all/bpf-fix-integer-overflows.patch delete mode 100644 debian/patches/bugfix/all/bpf-move-global-verifier-log-into-verifier-environme.patch delete mode 100644 debian/patches/bugfix/all/e1000e-fix-e1000_check_for_copper_link_ich8lan-return-value.patch delete mode 100644 debian/patches/bugfix/all/kvm-fix-stack-out-of-bounds-read-in-write_mmio.patch create mode 100644 debian/patches/debian/bpf-avoid-abi-change-in-4.14.14.patch diff --git a/debian/changelog b/debian/changelog index 9c2c7fac0..412c0e2db 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,120 @@ -linux (4.14.13-2) UNRELEASED; urgency=medium +linux (4.14.14-1) UNRELEASED; urgency=medium - * RDS: Heap OOB write in rds_message_alloc_sgs() (CVE-2018-5332) - * RDS: null pointer dereference in rds_atomic_free_op (CVE-2018-5333) + * New upstream stable update: + https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.14.14 + - dm bufio: fix shrinker scans when (nr_to_scan < retain_target) + - can: gs_usb: fix return value of the "set_bittiming" callback + - IB/srpt: Disable RDMA access by the initiator + - IB/srpt: Fix ACL lookup during login + - [mips*] Validate PR_SET_FP_MODE prctl(2) requests against the ABI of the + task + - [mips*] Factor out NT_PRFPREG regset access helpers + - [mips*] Guard against any partial write attempt with PTRACE_SETREGSET + - [mips*] Consistently handle buffer counter with PTRACE_SETREGSET + - [mips*] Fix an FCSR access API regression with NT_PRFPREG and MSA + - [mips*] Also verify sizeof `elf_fpreg_t' with PTRACE_SETREGSET + - [mips*] Disallow outsized PTRACE_SETREGSET NT_PRFPREG regset accesses + - cgroup: fix css_task_iter crash on CSS_TASK_ITER_PROC + - [x86] kvm: vmx: Scrub hardware GPRs at VM-exit (partial mitigation of + CVE-2017-5715, CVE-2017-5753) + - [x86] platform: wmi: Call acpi_wmi_init() later + - iw_cxgb4: only call the cq comp_handler when the cq is armed + - iw_cxgb4: atomically flush the qp + - iw_cxgb4: only clear the ARMED bit if a notification is needed + - iw_cxgb4: reflect the original WR opcode in drain cqes + - iw_cxgb4: when flushing, complete all wrs in a chain + - [x86] acpi: Handle SCI interrupts above legacy space gracefully + - ALSA: pcm: Remove incorrect snd_BUG_ON() usages + - ALSA: pcm: Workaround for weird PulseAudio behavior on rewind error + - ALSA: pcm: Add missing error checks in OSS emulation plugin builder + - ALSA: pcm: Abort properly at pending signal in OSS read/write loops + - ALSA: pcm: Allow aborting mutex lock at OSS read/write loops + - ALSA: aloop: Release cable upon open error path + - ALSA: aloop: Fix inconsistent format due to incomplete rule + - ALSA: aloop: Fix racy hw constraints adjustment + - [x86] acpi: Reduce code duplication in mp_override_legacy_irq() + - 8021q: fix a memory leak for VLAN 0 device + - ip6_tunnel: disable dst caching if tunnel is dual-stack + - net: core: fix module type in sock_diag_bind + - RDS: Heap OOB write in rds_message_alloc_sgs() (CVE-2018-5332) + - RDS: null pointer dereference in rds_atomic_free_op (CVE-2018-5333) + - net: fec: restore dev_id in the cases of probe error + - net: fec: defer probe if regulator is not ready + - net: fec: free/restore resource in related probe error pathes + - sctp: do not retransmit upon FragNeeded if PMTU discovery is disabled + - sctp: fix the handling of ICMP Frag Needed for too small MTUs + - [arm64, armhf] net: stmmac: enable EEE in MII, GMII or RGMII only + - ipv6: fix possible mem leaks in ipv6_make_skb() + - net/sched: Fix update of lastuse in act modules implementing + stats_update + - ipv6: sr: fix TLVs not being copied using setsockopt + - sfp: fix sfp-bus oops when removing socket/upstream + - membarrier: Disable preemption when calling smp_call_function_many() + - crypto: algapi - fix NULL dereference in crypto_remove_spawns() + - rbd: reacquire lock should update lock owner client id + - rbd: set max_segments to USHRT_MAX + - iwlwifi: pcie: fix DMA memory mapping / unmapping + - [x86] microcode/intel: Extend BDW late-loading with a revision check + - [x86] KVM: Add memory barrier on vmcs field lookup + - [powerpc*] KVM: Book3S PR: Fix WIMG handling under pHyp + - [powerpc*] KVM: Book3S HV: Drop prepare_done from struct kvm_resize_hpt + - [powerpc*] KVM: Book3S HV: Fix use after free in case of multiple resize + requests + - [powerpc*] KVM: Book3S HV: Always flush TLB in kvmppc_alloc_reset_hpt() + - [x86] drm/vmwgfx: Don't cache framebuffer maps + - [x86] drm/vmwgfx: Potential off by one in vmw_view_add() + - [x86] drm/i915/gvt: Clear the shadow page table entry after post-sync + - [x86] drm/i915: Whitelist SLICE_COMMON_ECO_CHICKEN1 on Geminilake. + - [x86] drm/i915: Move init_clock_gating() back to where it was + - [x86] drm/i915: Fix init_clock_gating for resume + - bpf: prevent out-of-bounds speculation (partial mitigation of CVE-2017-5753) + - bpf, array: fix overflow in max_entries and undefined behavior in + index_mask + - bpf: arsh is not supported in 32 bit alu thus reject it + - [arm64, armhf] usb: misc: usb3503: make sure reset is low for at least + 100us + - USB: fix usbmon BUG trigger + - USB: UDC core: fix double-free in usb_add_gadget_udc_release + - usbip: remove kernel addresses from usb device and urb debug msgs + - usbip: fix vudc_rx: harden CMD_SUBMIT path to handle malicious input + - usbip: vudc_tx: fix v_send_ret_submit() vulnerability to null xfer + buffer + - staging: android: ashmem: fix a race condition in ASHMEM_SET_SIZE ioctl + (CVE-2017-13216) + - mux: core: fix double get_device() + - kdump: write correct address of mem_section into vmcoreinfo + - apparmor: fix ptrace label match when matching stacked labels + - [x86] pti: Unbreak EFI old_memmap + - [x86] Documentation: Add PTI description + - [x86] cpufeatures: Add X86_BUG_SPECTRE_V[12] + - sysfs/cpu: Add vulnerability folder + - [x86] cpu: Implement CPU vulnerabilites sysfs functions + - [x86] tboot: Unbreak tboot with PTI enabled + - [x86] mm/pti: Remove dead logic in pti_user_pagetable_walk*() + - [x86] cpu/AMD: Make LFENCE a serializing instruction + - [x86] cpu/AMD: Use LFENCE_RDTSC in preference to MFENCE_RDTSC + - [x86] alternatives: Fix optimize_nops() checking + - [x86] pti: Make unpoison of pgd for trusted boot work for real + - [x86] retpoline: Add initial retpoline support (partial mitigation of + CVE-2017-5715) + - [x86] spectre: Add boot time option to select Spectre v2 mitigation + - [x86] retpoline/crypto: Convert crypto assembler indirect jumps + - [x86] retpoline/entry: Convert entry assembler indirect jumps + - [x86] retpoline/ftrace: Convert ftrace assembler indirect jumps + - [x86] retpoline/hyperv: Convert assembler indirect jumps + - [x86] retpoline/xen: Convert Xen hypercall indirect jumps + - [x86] retpoline/checksum32: Convert assembler indirect jumps + - [x86] retpoline/irq32: Convert assembler indirect jumps + - [x86] retpoline: Fill return stack buffer on vmexit + - [x86] pti: Fix !PCID and sanitize defines + - [x86] perf: Disable intel_bts when PTI + + [ Salvatore Bonaccorso ] * loop: fix concurrent lo_open/lo_release (CVE-2018-5344) + [ Ben Hutchings ] + * bpf: Avoid ABI change in 4.14.14 + -- Salvatore Bonaccorso Tue, 16 Jan 2018 20:50:23 +0100 linux (4.14.13-1) unstable; urgency=medium diff --git a/debian/patches/bugfix/all/RDS-Heap-OOB-write-in-rds_message_alloc_sgs.patch b/debian/patches/bugfix/all/RDS-Heap-OOB-write-in-rds_message_alloc_sgs.patch deleted file mode 100644 index e59fab0bb..000000000 --- a/debian/patches/bugfix/all/RDS-Heap-OOB-write-in-rds_message_alloc_sgs.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Mohamed Ghannam -Date: Tue, 2 Jan 2018 19:44:34 +0000 -Subject: RDS: Heap OOB write in rds_message_alloc_sgs() -Origin: https://git.kernel.org/linus/c095508770aebf1b9218e77026e48345d719b17c -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5332 - -When args->nr_local is 0, nr_pages gets also 0 due some size -calculation via rds_rm_size(), which is later used to allocate -pages for DMA, this bug produces a heap Out-Of-Bound write access -to a specific memory region. - -Signed-off-by: Mohamed Ghannam -Signed-off-by: David S. Miller ---- - net/rds/rdma.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/net/rds/rdma.c b/net/rds/rdma.c -index bc2f1e0977d6..94729d9da437 100644 ---- a/net/rds/rdma.c -+++ b/net/rds/rdma.c -@@ -525,6 +525,9 @@ int rds_rdma_extra_size(struct rds_rdma_args *args) - - local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; - -+ if (args->nr_local == 0) -+ return -EINVAL; -+ - /* figure out the number of pages in the vector */ - for (i = 0; i < args->nr_local; i++) { - if (copy_from_user(&vec, &local_vec[i], --- -2.15.1 - diff --git a/debian/patches/bugfix/all/RDS-null-pointer-dereference-in-rds_atomic_free_op.patch b/debian/patches/bugfix/all/RDS-null-pointer-dereference-in-rds_atomic_free_op.patch deleted file mode 100644 index 47620427f..000000000 --- a/debian/patches/bugfix/all/RDS-null-pointer-dereference-in-rds_atomic_free_op.patch +++ /dev/null @@ -1,32 +0,0 @@ -From: Mohamed Ghannam -Date: Wed, 3 Jan 2018 21:06:06 +0000 -Subject: RDS: null pointer dereference in rds_atomic_free_op -Origin: https://git.kernel.org/linus/7d11f77f84b27cef452cee332f4e469503084737 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5333 - -set rm->atomic.op_active to 0 when rds_pin_pages() fails -or the user supplied address is invalid, -this prevents a NULL pointer usage in rds_atomic_free_op() - -Signed-off-by: Mohamed Ghannam -Acked-by: Santosh Shilimkar -Signed-off-by: David S. Miller ---- - net/rds/rdma.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/net/rds/rdma.c b/net/rds/rdma.c -index 94729d9da437..634cfcb7bba6 100644 ---- a/net/rds/rdma.c -+++ b/net/rds/rdma.c -@@ -877,6 +877,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, - err: - if (page) - put_page(page); -+ rm->atomic.op_active = 0; - kfree(rm->atomic.op_notifier); - - return ret; --- -2.15.1 - diff --git a/debian/patches/bugfix/all/bluetooth-prevent-stack-info-leak-from-the-efs-element.patch b/debian/patches/bugfix/all/bluetooth-prevent-stack-info-leak-from-the-efs-element.patch deleted file mode 100644 index 308204888..000000000 --- a/debian/patches/bugfix/all/bluetooth-prevent-stack-info-leak-from-the-efs-element.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: Ben Seri -Date: Mon, 04 Dec 2017 14:13:25 +0000 -Subject: bluetooth: Prevent stack info leak from the EFS element. -Origin: http://www.openwall.com/lists/oss-security/2017/12/06/3 -Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2017-1000410 - -Signed-off-by: Ben Seri ---- ---- a/net/bluetooth/l2cap_core.c -+++ b/net/bluetooth/l2cap_core.c -@@ -3363,9 +3363,10 @@ static int l2cap_parse_conf_req(struct l - break; - - case L2CAP_CONF_EFS: -- remote_efs = 1; -- if (olen == sizeof(efs)) -+ if (olen == sizeof(efs)) { -+ remote_efs = 1; - memcpy(&efs, (void *) val, olen); -+ } - break; - - case L2CAP_CONF_EWS: -@@ -3584,16 +3585,17 @@ static int l2cap_parse_conf_rsp(struct l - break; - - case L2CAP_CONF_EFS: -- if (olen == sizeof(efs)) -+ if (olen == sizeof(efs)) { - memcpy(&efs, (void *)val, olen); - -- if (chan->local_stype != L2CAP_SERV_NOTRAFIC && -- efs.stype != L2CAP_SERV_NOTRAFIC && -- efs.stype != chan->local_stype) -- return -ECONNREFUSED; -+ if (chan->local_stype != L2CAP_SERV_NOTRAFIC && -+ efs.stype != L2CAP_SERV_NOTRAFIC && -+ efs.stype != chan->local_stype) -+ return -ECONNREFUSED; - -- l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), -- (unsigned long) &efs, endptr - ptr); -+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), -+ (unsigned long) &efs, endptr - ptr); -+ } - break; - - case L2CAP_CONF_FCS: diff --git a/debian/patches/bugfix/all/bpf-encapsulate-verifier-log-state-into-a-structure.patch b/debian/patches/bugfix/all/bpf-encapsulate-verifier-log-state-into-a-structure.patch deleted file mode 100644 index bf0f1c5b0..000000000 --- a/debian/patches/bugfix/all/bpf-encapsulate-verifier-log-state-into-a-structure.patch +++ /dev/null @@ -1,201 +0,0 @@ -From: Jakub Kicinski -Date: Mon, 9 Oct 2017 10:30:10 -0700 -Subject: bpf: encapsulate verifier log state into a structure -Origin: https://git.kernel.org/linus/e7bf8249e8f1bac64885eeccb55bcf6111901a81 - -Put the loose log_* variables into a structure. This will make -it simpler to remove the global verifier state in following patches. - -Signed-off-by: Jakub Kicinski -Reviewed-by: Simon Horman -Acked-by: Alexei Starovoitov -Acked-by: Daniel Borkmann -Signed-off-by: David S. Miller ---- - include/linux/bpf_verifier.h | 13 ++++++++++ - kernel/bpf/verifier.c | 57 +++++++++++++++++++++++--------------------- - 2 files changed, 43 insertions(+), 27 deletions(-) - ---- a/include/linux/bpf_verifier.h -+++ b/include/linux/bpf_verifier.h -@@ -115,6 +115,19 @@ struct bpf_insn_aux_data { - - #define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */ - -+struct bpf_verifer_log { -+ u32 level; -+ char *kbuf; -+ char __user *ubuf; -+ u32 len_used; -+ u32 len_total; -+}; -+ -+static inline bool bpf_verifier_log_full(const struct bpf_verifer_log *log) -+{ -+ return log->len_used >= log->len_total - 1; -+} -+ - struct bpf_verifier_env; - struct bpf_ext_analyzer_ops { - int (*insn_hook)(struct bpf_verifier_env *env, ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -156,8 +156,7 @@ struct bpf_call_arg_meta { - /* verbose verifier prints what it's seeing - * bpf_check() is called under lock, so no race to access these global vars - */ --static u32 log_level, log_size, log_len; --static char *log_buf; -+static struct bpf_verifer_log verifier_log; - - static DEFINE_MUTEX(bpf_verifier_lock); - -@@ -167,13 +166,15 @@ static DEFINE_MUTEX(bpf_verifier_lock); - */ - static __printf(1, 2) void verbose(const char *fmt, ...) - { -+ struct bpf_verifer_log *log = &verifier_log; - va_list args; - -- if (log_level == 0 || log_len >= log_size - 1) -+ if (!log->level || bpf_verifier_log_full(log)) - return; - - va_start(args, fmt); -- log_len += vscnprintf(log_buf + log_len, log_size - log_len, fmt, args); -+ log->len_used += vscnprintf(log->kbuf + log->len_used, -+ log->len_total - log->len_used, fmt, args); - va_end(args); - } - -@@ -834,7 +835,7 @@ static int check_map_access(struct bpf_v - * need to try adding each of min_value and max_value to off - * to make sure our theoretical access will be safe. - */ -- if (log_level) -+ if (verifier_log.level) - print_verifier_state(state); - /* The minimum value is only important with signed - * comparisons where we can't assume the floor of a -@@ -2915,7 +2916,7 @@ static int check_cond_jmp_op(struct bpf_ - verbose("R%d pointer comparison prohibited\n", insn->dst_reg); - return -EACCES; - } -- if (log_level) -+ if (verifier_log.level) - print_verifier_state(this_branch); - return 0; - } -@@ -3633,7 +3634,7 @@ static int do_check(struct bpf_verifier_ - return err; - if (err == 1) { - /* found equivalent state, can prune the search */ -- if (log_level) { -+ if (verifier_log.level) { - if (do_print_state) - verbose("\nfrom %d to %d: safe\n", - prev_insn_idx, insn_idx); -@@ -3646,8 +3647,9 @@ static int do_check(struct bpf_verifier_ - if (need_resched()) - cond_resched(); - -- if (log_level > 1 || (log_level && do_print_state)) { -- if (log_level > 1) -+ if (verifier_log.level > 1 || -+ (verifier_log.level && do_print_state)) { -+ if (verifier_log.level > 1) - verbose("%d:", insn_idx); - else - verbose("\nfrom %d to %d:", -@@ -3656,7 +3658,7 @@ static int do_check(struct bpf_verifier_ - do_print_state = false; - } - -- if (log_level) { -+ if (verifier_log.level) { - verbose("%d: ", insn_idx); - print_bpf_insn(env, insn); - } -@@ -4307,7 +4309,7 @@ static void free_states(struct bpf_verif - - int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) - { -- char __user *log_ubuf = NULL; -+ struct bpf_verifer_log *log = &verifier_log; - struct bpf_verifier_env *env; - int ret = -EINVAL; - -@@ -4332,23 +4334,23 @@ int bpf_check(struct bpf_prog **prog, un - /* user requested verbose verifier output - * and supplied buffer to store the verification trace - */ -- log_level = attr->log_level; -- log_ubuf = (char __user *) (unsigned long) attr->log_buf; -- log_size = attr->log_size; -- log_len = 0; -+ log->level = attr->log_level; -+ log->ubuf = (char __user *) (unsigned long) attr->log_buf; -+ log->len_total = attr->log_size; -+ log->len_used = 0; - - ret = -EINVAL; -- /* log_* values have to be sane */ -- if (log_size < 128 || log_size > UINT_MAX >> 8 || -- log_level == 0 || log_ubuf == NULL) -+ /* log attributes have to be sane */ -+ if (log->len_total < 128 || log->len_total > UINT_MAX >> 8 || -+ !log->level || !log->ubuf) - goto err_unlock; - - ret = -ENOMEM; -- log_buf = vmalloc(log_size); -- if (!log_buf) -+ log->kbuf = vmalloc(log->len_total); -+ if (!log->kbuf) - goto err_unlock; - } else { -- log_level = 0; -+ log->level = 0; - } - - env->strict_alignment = !!(attr->prog_flags & BPF_F_STRICT_ALIGNMENT); -@@ -4385,15 +4387,16 @@ skip_full_check: - if (ret == 0) - ret = fixup_bpf_calls(env); - -- if (log_level && log_len >= log_size - 1) { -- BUG_ON(log_len >= log_size); -+ if (log->level && bpf_verifier_log_full(log)) { -+ BUG_ON(log->len_used >= log->len_total); - /* verifier log exceeded user supplied buffer */ - ret = -ENOSPC; - /* fall through to return what was recorded */ - } - - /* copy verifier log back to user space including trailing zero */ -- if (log_level && copy_to_user(log_ubuf, log_buf, log_len + 1) != 0) { -+ if (log->level && copy_to_user(log->ubuf, log->kbuf, -+ log->len_used + 1) != 0) { - ret = -EFAULT; - goto free_log_buf; - } -@@ -4420,8 +4423,8 @@ skip_full_check: - } - - free_log_buf: -- if (log_level) -- vfree(log_buf); -+ if (log->level) -+ vfree(log->kbuf); - if (!env->prog->aux->used_maps) - /* if we didn't copy map pointers into bpf_prog_info, release - * them now. Otherwise free_bpf_prog_info() will release them. -@@ -4458,7 +4461,7 @@ int bpf_analyzer(struct bpf_prog *prog, - /* grab the mutex to protect few globals used by verifier */ - mutex_lock(&bpf_verifier_lock); - -- log_level = 0; -+ verifier_log.level = 0; - - env->strict_alignment = false; - if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) diff --git a/debian/patches/bugfix/all/bpf-fix-integer-overflows.patch b/debian/patches/bugfix/all/bpf-fix-integer-overflows.patch deleted file mode 100644 index a26b5f057..000000000 --- a/debian/patches/bugfix/all/bpf-fix-integer-overflows.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Alexei Starovoitov -Date: Mon, 18 Dec 2017 20:12:00 -0800 -Subject: [8/9] bpf: fix integer overflows -Origin: https://git.kernel.org/linus/bb7f0f989ca7de1153bd128a40a71709e339fa03 - -There were various issues related to the limited size of integers used in -the verifier: - - `off + size` overflow in __check_map_access() - - `off + reg->off` overflow in check_mem_access() - - `off + reg->var_off.value` overflow or 32-bit truncation of - `reg->var_off.value` in check_mem_access() - - 32-bit truncation in check_stack_boundary() - -Make sure that any integer math cannot overflow by not allowing -pointer math with large values. - -Also reduce the scope of "scalar op scalar" tracking. - -Fixes: f1174f77b50c ("bpf/verifier: rework value tracking") -Reported-by: Jann Horn -Signed-off-by: Alexei Starovoitov -Signed-off-by: Daniel Borkmann -[carnil: - - adjust context, we previously change verbose() signature - - drop changes to include/linux/bpf_verifier.h already set -] ---- - include/linux/bpf_verifier.h | 4 ++-- - kernel/bpf/verifier.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 50 insertions(+), 2 deletions(-) - ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -1821,25 +1821,25 @@ static bool check_reg_sane_offset(struct - s64 smin = reg->smin_value; - - if (known && (val >= BPF_MAX_VAR_OFF || val <= -BPF_MAX_VAR_OFF)) { -- verbose("math between %s pointer and %lld is not allowed\n", -+ verbose(env, "math between %s pointer and %lld is not allowed\n", - reg_type_str[type], val); - return false; - } - - if (reg->off >= BPF_MAX_VAR_OFF || reg->off <= -BPF_MAX_VAR_OFF) { -- verbose("%s pointer offset %d is not allowed\n", -+ verbose(env, "%s pointer offset %d is not allowed\n", - reg_type_str[type], reg->off); - return false; - } - - if (smin == S64_MIN) { -- verbose("math between %s pointer and register with unbounded min value is not allowed\n", -+ verbose(env, "math between %s pointer and register with unbounded min value is not allowed\n", - reg_type_str[type]); - return false; - } - - if (smin >= BPF_MAX_VAR_OFF || smin <= -BPF_MAX_VAR_OFF) { -- verbose("value %lld makes %s pointer be out of bounds\n", -+ verbose(env, "value %lld makes %s pointer be out of bounds\n", - smin, reg_type_str[type]); - return false; - } diff --git a/debian/patches/bugfix/all/bpf-move-global-verifier-log-into-verifier-environme.patch b/debian/patches/bugfix/all/bpf-move-global-verifier-log-into-verifier-environme.patch deleted file mode 100644 index 70f75677e..000000000 --- a/debian/patches/bugfix/all/bpf-move-global-verifier-log-into-verifier-environme.patch +++ /dev/null @@ -1,1667 +0,0 @@ -From: Jakub Kicinski -Date: Mon, 9 Oct 2017 10:30:11 -0700 -Subject: bpf: move global verifier log into verifier environment -Origin: https://git.kernel.org/linus/61bd5218eef349fcacc4976a251bc83a4748b4af - -The biggest piece of global state protected by the verifier lock -is the verifier_log. Move that log to struct bpf_verifier_env. -struct bpf_verifier_env has to be passed now to all invocations -of verbose(). - -Signed-off-by: Jakub Kicinski -Reviewed-by: Simon Horman -Acked-by: Alexei Starovoitov -Acked-by: Daniel Borkmann -Signed-off-by: David S. Miller -[bwh: Backported to 4.14] -[carnil: refresh after 4.14.9 import] ---- - include/linux/bpf_verifier.h | 2 + - kernel/bpf/verifier.c | 491 +++++++++++++++++++++++-------------------- - 2 files changed, 261 insertions(+), 232 deletions(-) - ---- a/include/linux/bpf_verifier.h -+++ b/include/linux/bpf_verifier.h -@@ -152,6 +152,8 @@ struct bpf_verifier_env { - bool allow_ptr_leaks; - bool seen_direct_write; - struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ -+ -+ struct bpf_verifer_log log; - }; - - int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops, ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -153,20 +153,16 @@ struct bpf_call_arg_meta { - int access_size; - }; - --/* verbose verifier prints what it's seeing -- * bpf_check() is called under lock, so no race to access these global vars -- */ --static struct bpf_verifer_log verifier_log; -- - static DEFINE_MUTEX(bpf_verifier_lock); - - /* log_level controls verbosity level of eBPF verifier. - * verbose() is used to dump the verification trace to the log, so the user - * can figure out what's wrong with the program - */ --static __printf(1, 2) void verbose(const char *fmt, ...) -+static __printf(2, 3) void verbose(struct bpf_verifier_env *env, -+ const char *fmt, ...) - { -- struct bpf_verifer_log *log = &verifier_log; -+ struct bpf_verifer_log *log = &env->log; - va_list args; - - if (!log->level || bpf_verifier_log_full(log)) -@@ -207,7 +203,8 @@ static const char *func_id_name(int id) - return "unknown"; - } - --static void print_verifier_state(struct bpf_verifier_state *state) -+static void print_verifier_state(struct bpf_verifier_env *env, -+ struct bpf_verifier_state *state) - { - struct bpf_reg_state *reg; - enum bpf_reg_type t; -@@ -218,21 +215,21 @@ static void print_verifier_state(struct - t = reg->type; - if (t == NOT_INIT) - continue; -- verbose(" R%d=%s", i, reg_type_str[t]); -+ verbose(env, " R%d=%s", i, reg_type_str[t]); - if ((t == SCALAR_VALUE || t == PTR_TO_STACK) && - tnum_is_const(reg->var_off)) { - /* reg->off should be 0 for SCALAR_VALUE */ -- verbose("%lld", reg->var_off.value + reg->off); -+ verbose(env, "%lld", reg->var_off.value + reg->off); - } else { -- verbose("(id=%d", reg->id); -+ verbose(env, "(id=%d", reg->id); - if (t != SCALAR_VALUE) -- verbose(",off=%d", reg->off); -+ verbose(env, ",off=%d", reg->off); - if (t == PTR_TO_PACKET) -- verbose(",r=%d", reg->range); -+ verbose(env, ",r=%d", reg->range); - else if (t == CONST_PTR_TO_MAP || - t == PTR_TO_MAP_VALUE || - t == PTR_TO_MAP_VALUE_OR_NULL) -- verbose(",ks=%d,vs=%d", -+ verbose(env, ",ks=%d,vs=%d", - reg->map_ptr->key_size, - reg->map_ptr->value_size); - if (tnum_is_const(reg->var_off)) { -@@ -240,38 +237,38 @@ static void print_verifier_state(struct - * could be a pointer whose offset is too big - * for reg->off - */ -- verbose(",imm=%llx", reg->var_off.value); -+ verbose(env, ",imm=%llx", reg->var_off.value); - } else { - if (reg->smin_value != reg->umin_value && - reg->smin_value != S64_MIN) -- verbose(",smin_value=%lld", -+ verbose(env, ",smin_value=%lld", - (long long)reg->smin_value); - if (reg->smax_value != reg->umax_value && - reg->smax_value != S64_MAX) -- verbose(",smax_value=%lld", -+ verbose(env, ",smax_value=%lld", - (long long)reg->smax_value); - if (reg->umin_value != 0) -- verbose(",umin_value=%llu", -+ verbose(env, ",umin_value=%llu", - (unsigned long long)reg->umin_value); - if (reg->umax_value != U64_MAX) -- verbose(",umax_value=%llu", -+ verbose(env, ",umax_value=%llu", - (unsigned long long)reg->umax_value); - if (!tnum_is_unknown(reg->var_off)) { - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); -- verbose(",var_off=%s", tn_buf); -+ verbose(env, ",var_off=%s", tn_buf); - } - } -- verbose(")"); -+ verbose(env, ")"); - } - } - for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { - if (state->stack_slot_type[i] == STACK_SPILL) -- verbose(" fp%d=%s", -MAX_BPF_STACK + i, -+ verbose(env, " fp%d=%s", -MAX_BPF_STACK + i, - reg_type_str[state->spilled_regs[i / BPF_REG_SIZE].type]); - } -- verbose("\n"); -+ verbose(env, "\n"); - } - - static const char *const bpf_class_string[] = { -@@ -326,21 +323,21 @@ static const char *const bpf_jmp_string[ - [BPF_EXIT >> 4] = "exit", - }; - --static void print_bpf_insn(const struct bpf_verifier_env *env, -+static void print_bpf_insn(struct bpf_verifier_env *env, - const struct bpf_insn *insn) - { - u8 class = BPF_CLASS(insn->code); - - if (class == BPF_ALU || class == BPF_ALU64) { - if (BPF_SRC(insn->code) == BPF_X) -- verbose("(%02x) %sr%d %s %sr%d\n", -+ verbose(env, "(%02x) %sr%d %s %sr%d\n", - insn->code, class == BPF_ALU ? "(u32) " : "", - insn->dst_reg, - bpf_alu_string[BPF_OP(insn->code) >> 4], - class == BPF_ALU ? "(u32) " : "", - insn->src_reg); - else -- verbose("(%02x) %sr%d %s %s%d\n", -+ verbose(env, "(%02x) %sr%d %s %s%d\n", - insn->code, class == BPF_ALU ? "(u32) " : "", - insn->dst_reg, - bpf_alu_string[BPF_OP(insn->code) >> 4], -@@ -348,46 +345,46 @@ static void print_bpf_insn(const struct - insn->imm); - } else if (class == BPF_STX) { - if (BPF_MODE(insn->code) == BPF_MEM) -- verbose("(%02x) *(%s *)(r%d %+d) = r%d\n", -+ verbose(env, "(%02x) *(%s *)(r%d %+d) = r%d\n", - insn->code, - bpf_ldst_string[BPF_SIZE(insn->code) >> 3], - insn->dst_reg, - insn->off, insn->src_reg); - else if (BPF_MODE(insn->code) == BPF_XADD) -- verbose("(%02x) lock *(%s *)(r%d %+d) += r%d\n", -+ verbose(env, "(%02x) lock *(%s *)(r%d %+d) += r%d\n", - insn->code, - bpf_ldst_string[BPF_SIZE(insn->code) >> 3], - insn->dst_reg, insn->off, - insn->src_reg); - else -- verbose("BUG_%02x\n", insn->code); -+ verbose(env, "BUG_%02x\n", insn->code); - } else if (class == BPF_ST) { - if (BPF_MODE(insn->code) != BPF_MEM) { -- verbose("BUG_st_%02x\n", insn->code); -+ verbose(env, "BUG_st_%02x\n", insn->code); - return; - } -- verbose("(%02x) *(%s *)(r%d %+d) = %d\n", -+ verbose(env, "(%02x) *(%s *)(r%d %+d) = %d\n", - insn->code, - bpf_ldst_string[BPF_SIZE(insn->code) >> 3], - insn->dst_reg, - insn->off, insn->imm); - } else if (class == BPF_LDX) { - if (BPF_MODE(insn->code) != BPF_MEM) { -- verbose("BUG_ldx_%02x\n", insn->code); -+ verbose(env, "BUG_ldx_%02x\n", insn->code); - return; - } -- verbose("(%02x) r%d = *(%s *)(r%d %+d)\n", -+ verbose(env, "(%02x) r%d = *(%s *)(r%d %+d)\n", - insn->code, insn->dst_reg, - bpf_ldst_string[BPF_SIZE(insn->code) >> 3], - insn->src_reg, insn->off); - } else if (class == BPF_LD) { - if (BPF_MODE(insn->code) == BPF_ABS) { -- verbose("(%02x) r0 = *(%s *)skb[%d]\n", -+ verbose(env, "(%02x) r0 = *(%s *)skb[%d]\n", - insn->code, - bpf_ldst_string[BPF_SIZE(insn->code) >> 3], - insn->imm); - } else if (BPF_MODE(insn->code) == BPF_IND) { -- verbose("(%02x) r0 = *(%s *)skb[r%d + %d]\n", -+ verbose(env, "(%02x) r0 = *(%s *)skb[r%d + %d]\n", - insn->code, - bpf_ldst_string[BPF_SIZE(insn->code) >> 3], - insn->src_reg, insn->imm); -@@ -402,36 +399,37 @@ static void print_bpf_insn(const struct - if (map_ptr && !env->allow_ptr_leaks) - imm = 0; - -- verbose("(%02x) r%d = 0x%llx\n", insn->code, -+ verbose(env, "(%02x) r%d = 0x%llx\n", insn->code, - insn->dst_reg, (unsigned long long)imm); - } else { -- verbose("BUG_ld_%02x\n", insn->code); -+ verbose(env, "BUG_ld_%02x\n", insn->code); - return; - } - } else if (class == BPF_JMP) { - u8 opcode = BPF_OP(insn->code); - - if (opcode == BPF_CALL) { -- verbose("(%02x) call %s#%d\n", insn->code, -+ verbose(env, "(%02x) call %s#%d\n", insn->code, - func_id_name(insn->imm), insn->imm); - } else if (insn->code == (BPF_JMP | BPF_JA)) { -- verbose("(%02x) goto pc%+d\n", -+ verbose(env, "(%02x) goto pc%+d\n", - insn->code, insn->off); - } else if (insn->code == (BPF_JMP | BPF_EXIT)) { -- verbose("(%02x) exit\n", insn->code); -+ verbose(env, "(%02x) exit\n", insn->code); - } else if (BPF_SRC(insn->code) == BPF_X) { -- verbose("(%02x) if r%d %s r%d goto pc%+d\n", -+ verbose(env, "(%02x) if r%d %s r%d goto pc%+d\n", - insn->code, insn->dst_reg, - bpf_jmp_string[BPF_OP(insn->code) >> 4], - insn->src_reg, insn->off); - } else { -- verbose("(%02x) if r%d %s 0x%x goto pc%+d\n", -+ verbose(env, "(%02x) if r%d %s 0x%x goto pc%+d\n", - insn->code, insn->dst_reg, - bpf_jmp_string[BPF_OP(insn->code) >> 4], - insn->imm, insn->off); - } - } else { -- verbose("(%02x) %s\n", insn->code, bpf_class_string[class]); -+ verbose(env, "(%02x) %s\n", -+ insn->code, bpf_class_string[class]); - } - } - -@@ -470,7 +468,7 @@ static struct bpf_verifier_state *push_s - env->head = elem; - env->stack_size++; - if (env->stack_size > BPF_COMPLEXITY_LIMIT_STACK) { -- verbose("BPF program is too complex\n"); -+ verbose(env, "BPF program is too complex\n"); - goto err; - } - return &elem->st; -@@ -508,10 +506,11 @@ static void __mark_reg_known_zero(struct - __mark_reg_known(reg, 0); - } - --static void mark_reg_known_zero(struct bpf_reg_state *regs, u32 regno) -+static void mark_reg_known_zero(struct bpf_verifier_env *env, -+ struct bpf_reg_state *regs, u32 regno) - { - if (WARN_ON(regno >= MAX_BPF_REG)) { -- verbose("mark_reg_known_zero(regs, %u)\n", regno); -+ verbose(env, "mark_reg_known_zero(regs, %u)\n", regno); - /* Something bad happened, let's kill all regs */ - for (regno = 0; regno < MAX_BPF_REG; regno++) - __mark_reg_not_init(regs + regno); -@@ -596,10 +595,11 @@ static void __mark_reg_unknown(struct bp - __mark_reg_unbounded(reg); - } - --static void mark_reg_unknown(struct bpf_reg_state *regs, u32 regno) -+static void mark_reg_unknown(struct bpf_verifier_env *env, -+ struct bpf_reg_state *regs, u32 regno) - { - if (WARN_ON(regno >= MAX_BPF_REG)) { -- verbose("mark_reg_unknown(regs, %u)\n", regno); -+ verbose(env, "mark_reg_unknown(regs, %u)\n", regno); - /* Something bad happened, let's kill all regs */ - for (regno = 0; regno < MAX_BPF_REG; regno++) - __mark_reg_not_init(regs + regno); -@@ -614,10 +614,11 @@ static void __mark_reg_not_init(struct b - reg->type = NOT_INIT; - } - --static void mark_reg_not_init(struct bpf_reg_state *regs, u32 regno) -+static void mark_reg_not_init(struct bpf_verifier_env *env, -+ struct bpf_reg_state *regs, u32 regno) - { - if (WARN_ON(regno >= MAX_BPF_REG)) { -- verbose("mark_reg_not_init(regs, %u)\n", regno); -+ verbose(env, "mark_reg_not_init(regs, %u)\n", regno); - /* Something bad happened, let's kill all regs */ - for (regno = 0; regno < MAX_BPF_REG; regno++) - __mark_reg_not_init(regs + regno); -@@ -626,22 +627,23 @@ static void mark_reg_not_init(struct bpf - __mark_reg_not_init(regs + regno); - } - --static void init_reg_state(struct bpf_reg_state *regs) -+static void init_reg_state(struct bpf_verifier_env *env, -+ struct bpf_reg_state *regs) - { - int i; - - for (i = 0; i < MAX_BPF_REG; i++) { -- mark_reg_not_init(regs, i); -+ mark_reg_not_init(env, regs, i); - regs[i].live = REG_LIVE_NONE; - } - - /* frame pointer */ - regs[BPF_REG_FP].type = PTR_TO_STACK; -- mark_reg_known_zero(regs, BPF_REG_FP); -+ mark_reg_known_zero(env, regs, BPF_REG_FP); - - /* 1st arg to a function */ - regs[BPF_REG_1].type = PTR_TO_CTX; -- mark_reg_known_zero(regs, BPF_REG_1); -+ mark_reg_known_zero(env, regs, BPF_REG_1); - } - - enum reg_arg_type { -@@ -675,26 +677,26 @@ static int check_reg_arg(struct bpf_veri - struct bpf_reg_state *regs = env->cur_state.regs; - - if (regno >= MAX_BPF_REG) { -- verbose("R%d is invalid\n", regno); -+ verbose(env, "R%d is invalid\n", regno); - return -EINVAL; - } - - if (t == SRC_OP) { - /* check whether register used as source operand can be read */ - if (regs[regno].type == NOT_INIT) { -- verbose("R%d !read_ok\n", regno); -+ verbose(env, "R%d !read_ok\n", regno); - return -EACCES; - } - mark_reg_read(&env->cur_state, regno); - } else { - /* check whether register used as dest operand can be written to */ - if (regno == BPF_REG_FP) { -- verbose("frame pointer is read only\n"); -+ verbose(env, "frame pointer is read only\n"); - return -EACCES; - } - regs[regno].live |= REG_LIVE_WRITTEN; - if (t == DST_OP) -- mark_reg_unknown(regs, regno); -+ mark_reg_unknown(env, regs, regno); - } - return 0; - } -@@ -718,7 +720,8 @@ static bool is_spillable_regtype(enum bp - /* check_stack_read/write functions track spill/fill of registers, - * stack boundary and alignment are checked in check_mem_access() - */ --static int check_stack_write(struct bpf_verifier_state *state, int off, -+static int check_stack_write(struct bpf_verifier_env *env, -+ struct bpf_verifier_state *state, int off, - int size, int value_regno) - { - int i, spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE; -@@ -731,7 +734,7 @@ static int check_stack_write(struct bpf_ - - /* register containing pointer is being spilled into stack */ - if (size != BPF_REG_SIZE) { -- verbose("invalid size of register spill\n"); -+ verbose(env, "invalid size of register spill\n"); - return -EACCES; - } - -@@ -766,7 +769,8 @@ static void mark_stack_slot_read(const s - } - } - --static int check_stack_read(struct bpf_verifier_state *state, int off, int size, -+static int check_stack_read(struct bpf_verifier_env *env, -+ struct bpf_verifier_state *state, int off, int size, - int value_regno) - { - u8 *slot_type; -@@ -776,12 +780,12 @@ static int check_stack_read(struct bpf_v - - if (slot_type[0] == STACK_SPILL) { - if (size != BPF_REG_SIZE) { -- verbose("invalid size of register spill\n"); -+ verbose(env, "invalid size of register spill\n"); - return -EACCES; - } - for (i = 1; i < BPF_REG_SIZE; i++) { - if (slot_type[i] != STACK_SPILL) { -- verbose("corrupted spill memory\n"); -+ verbose(env, "corrupted spill memory\n"); - return -EACCES; - } - } -@@ -797,14 +801,14 @@ static int check_stack_read(struct bpf_v - } else { - for (i = 0; i < size; i++) { - if (slot_type[i] != STACK_MISC) { -- verbose("invalid read from stack off %d+%d size %d\n", -+ verbose(env, "invalid read from stack off %d+%d size %d\n", - off, i, size); - return -EACCES; - } - } - if (value_regno >= 0) - /* have read misc data from the stack */ -- mark_reg_unknown(state->regs, value_regno); -+ mark_reg_unknown(env, state->regs, value_regno); - return 0; - } - } -@@ -816,7 +820,7 @@ static int __check_map_access(struct bpf - struct bpf_map *map = env->cur_state.regs[regno].map_ptr; - - if (off < 0 || size <= 0 || off + size > map->value_size) { -- verbose("invalid access to map value, value_size=%d off=%d size=%d\n", -+ verbose(env, "invalid access to map value, value_size=%d off=%d size=%d\n", - map->value_size, off, size); - return -EACCES; - } -@@ -835,8 +839,8 @@ static int check_map_access(struct bpf_v - * need to try adding each of min_value and max_value to off - * to make sure our theoretical access will be safe. - */ -- if (verifier_log.level) -- print_verifier_state(state); -+ if (env->log.level) -+ print_verifier_state(env, state); - /* The minimum value is only important with signed - * comparisons where we can't assume the floor of a - * value is 0. If we are using signed variables for our -@@ -844,13 +848,14 @@ static int check_map_access(struct bpf_v - * will have a set floor within our range. - */ - if (reg->smin_value < 0) { -- verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", -+ verbose(env, "R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", - regno); - return -EACCES; - } - err = __check_map_access(env, regno, reg->smin_value + off, size); - if (err) { -- verbose("R%d min value is outside of the array range\n", regno); -+ verbose(env, "R%d min value is outside of the array range\n", -+ regno); - return err; - } - -@@ -859,13 +864,14 @@ static int check_map_access(struct bpf_v - * If reg->umax_value + off could overflow, treat that as unbounded too. - */ - if (reg->umax_value >= BPF_MAX_VAR_OFF) { -- verbose("R%d unbounded memory access, make sure to bounds check any array access into a map\n", -+ verbose(env, "R%d unbounded memory access, make sure to bounds check any array access into a map\n", - regno); - return -EACCES; - } - err = __check_map_access(env, regno, reg->umax_value + off, size); - if (err) -- verbose("R%d max value is outside of the array range\n", regno); -+ verbose(env, "R%d max value is outside of the array range\n", -+ regno); - return err; - } - -@@ -904,7 +910,7 @@ static int __check_packet_access(struct - struct bpf_reg_state *reg = ®s[regno]; - - if (off < 0 || size <= 0 || (u64)off + size > reg->range) { -- verbose("invalid access to packet, off=%d size=%d, R%d(id=%d,off=%d,r=%d)\n", -+ verbose(env, "invalid access to packet, off=%d size=%d, R%d(id=%d,off=%d,r=%d)\n", - off, size, regno, reg->id, reg->off, reg->range); - return -EACCES; - } -@@ -927,13 +933,13 @@ static int check_packet_access(struct bp - * detail to prove they're safe. - */ - if (reg->smin_value < 0) { -- verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", -+ verbose(env, "R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", - regno); - return -EACCES; - } - err = __check_packet_access(env, regno, off, size); - if (err) { -- verbose("R%d offset is outside of the packet\n", regno); -+ verbose(env, "R%d offset is outside of the packet\n", regno); - return err; - } - return err; -@@ -969,7 +975,7 @@ static int check_ctx_access(struct bpf_v - return 0; - } - -- verbose("invalid bpf_context access off=%d size=%d\n", off, size); -+ verbose(env, "invalid bpf_context access off=%d size=%d\n", off, size); - return -EACCES; - } - -@@ -987,7 +993,8 @@ static bool is_pointer_value(struct bpf_ - return __is_pointer_value(env->allow_ptr_leaks, &env->cur_state.regs[regno]); - } - --static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, -+static int check_pkt_ptr_alignment(struct bpf_verifier_env *env, -+ const struct bpf_reg_state *reg, - int off, int size, bool strict) - { - struct tnum reg_off; -@@ -1012,7 +1019,8 @@ static int check_pkt_ptr_alignment(const - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); -- verbose("misaligned packet access off %d+%s+%d+%d size %d\n", -+ verbose(env, -+ "misaligned packet access off %d+%s+%d+%d size %d\n", - ip_align, tn_buf, reg->off, off, size); - return -EACCES; - } -@@ -1020,7 +1028,8 @@ static int check_pkt_ptr_alignment(const - return 0; - } - --static int check_generic_ptr_alignment(const struct bpf_reg_state *reg, -+static int check_generic_ptr_alignment(struct bpf_verifier_env *env, -+ const struct bpf_reg_state *reg, - const char *pointer_desc, - int off, int size, bool strict) - { -@@ -1035,7 +1044,7 @@ static int check_generic_ptr_alignment(c - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); -- verbose("misaligned %saccess off %s+%d+%d size %d\n", -+ verbose(env, "misaligned %saccess off %s+%d+%d size %d\n", - pointer_desc, tn_buf, reg->off, off, size); - return -EACCES; - } -@@ -1053,7 +1062,7 @@ static int check_ptr_alignment(struct bp - switch (reg->type) { - case PTR_TO_PACKET: - /* special case, because of NET_IP_ALIGN */ -- return check_pkt_ptr_alignment(reg, off, size, strict); -+ return check_pkt_ptr_alignment(env, reg, off, size, strict); - case PTR_TO_MAP_VALUE: - pointer_desc = "value "; - break; -@@ -1071,7 +1080,8 @@ static int check_ptr_alignment(struct bp - default: - break; - } -- return check_generic_ptr_alignment(reg, pointer_desc, off, size, strict); -+ return check_generic_ptr_alignment(env, reg, pointer_desc, off, size, -+ strict); - } - - /* truncate register to smaller size (in bytes) -@@ -1126,27 +1136,27 @@ static int check_mem_access(struct bpf_v - if (reg->type == PTR_TO_MAP_VALUE) { - if (t == BPF_WRITE && value_regno >= 0 && - is_pointer_value(env, value_regno)) { -- verbose("R%d leaks addr into map\n", value_regno); -+ verbose(env, "R%d leaks addr into map\n", value_regno); - return -EACCES; - } - - err = check_map_access(env, regno, off, size); - if (!err && t == BPF_READ && value_regno >= 0) -- mark_reg_unknown(state->regs, value_regno); -+ mark_reg_unknown(env, state->regs, value_regno); - - } else if (reg->type == PTR_TO_CTX) { - enum bpf_reg_type reg_type = SCALAR_VALUE; - - if (t == BPF_WRITE && value_regno >= 0 && - is_pointer_value(env, value_regno)) { -- verbose("R%d leaks addr into ctx\n", value_regno); -+ verbose(env, "R%d leaks addr into ctx\n", value_regno); - return -EACCES; - } - /* ctx accesses must be at a fixed offset, so that we can - * determine what type of data were returned. - */ - if (reg->off) { -- verbose("dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n", -+ verbose(env, "dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n", - regno, reg->off, off - reg->off); - return -EACCES; - } -@@ -1154,7 +1164,8 @@ static int check_mem_access(struct bpf_v - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); -- verbose("variable ctx access var_off=%s off=%d size=%d", -+ verbose(env, -+ "variable ctx access var_off=%s off=%d size=%d", - tn_buf, off, size); - return -EACCES; - } -@@ -1165,9 +1176,10 @@ static int check_mem_access(struct bpf_v - * the offset is zero. - */ - if (reg_type == SCALAR_VALUE) -- mark_reg_unknown(state->regs, value_regno); -+ mark_reg_unknown(env, state->regs, value_regno); - else -- mark_reg_known_zero(state->regs, value_regno); -+ mark_reg_known_zero(env, state->regs, -+ value_regno); - state->regs[value_regno].id = 0; - state->regs[value_regno].off = 0; - state->regs[value_regno].range = 0; -@@ -1183,13 +1195,14 @@ static int check_mem_access(struct bpf_v - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); -- verbose("variable stack access var_off=%s off=%d size=%d", -+ verbose(env, "variable stack access var_off=%s off=%d size=%d", - tn_buf, off, size); - return -EACCES; - } - off += reg->var_off.value; - if (off >= 0 || off < -MAX_BPF_STACK) { -- verbose("invalid stack off=%d size=%d\n", off, size); -+ verbose(env, "invalid stack off=%d size=%d\n", off, -+ size); - return -EACCES; - } - -@@ -1200,28 +1213,31 @@ static int check_mem_access(struct bpf_v - if (!env->allow_ptr_leaks && - state->stack_slot_type[MAX_BPF_STACK + off] == STACK_SPILL && - size != BPF_REG_SIZE) { -- verbose("attempt to corrupt spilled pointer on stack\n"); -+ verbose(env, "attempt to corrupt spilled pointer on stack\n"); - return -EACCES; - } -- err = check_stack_write(state, off, size, value_regno); -+ err = check_stack_write(env, state, off, size, -+ value_regno); - } else { -- err = check_stack_read(state, off, size, value_regno); -+ err = check_stack_read(env, state, off, size, -+ value_regno); - } - } else if (reg->type == PTR_TO_PACKET) { - if (t == BPF_WRITE && !may_access_direct_pkt_data(env, NULL, t)) { -- verbose("cannot write into packet\n"); -+ verbose(env, "cannot write into packet\n"); - return -EACCES; - } - if (t == BPF_WRITE && value_regno >= 0 && - is_pointer_value(env, value_regno)) { -- verbose("R%d leaks addr into packet\n", value_regno); -+ verbose(env, "R%d leaks addr into packet\n", -+ value_regno); - return -EACCES; - } - err = check_packet_access(env, regno, off, size); - if (!err && t == BPF_READ && value_regno >= 0) -- mark_reg_unknown(state->regs, value_regno); -+ mark_reg_unknown(env, state->regs, value_regno); - } else { -- verbose("R%d invalid mem access '%s'\n", -+ verbose(env, "R%d invalid mem access '%s'\n", - regno, reg_type_str[reg->type]); - return -EACCES; - } -@@ -1240,7 +1256,7 @@ static int check_xadd(struct bpf_verifie - - if ((BPF_SIZE(insn->code) != BPF_W && BPF_SIZE(insn->code) != BPF_DW) || - insn->imm != 0) { -- verbose("BPF_XADD uses reserved fields\n"); -+ verbose(env, "BPF_XADD uses reserved fields\n"); - return -EINVAL; - } - -@@ -1255,7 +1271,7 @@ static int check_xadd(struct bpf_verifie - return err; - - if (is_pointer_value(env, insn->src_reg)) { -- verbose("R%d leaks addr into mem\n", insn->src_reg); -+ verbose(env, "R%d leaks addr into mem\n", insn->src_reg); - return -EACCES; - } - -@@ -1296,7 +1312,7 @@ static int check_stack_boundary(struct b - register_is_null(regs[regno])) - return 0; - -- verbose("R%d type=%s expected=%s\n", regno, -+ verbose(env, "R%d type=%s expected=%s\n", regno, - reg_type_str[regs[regno].type], - reg_type_str[PTR_TO_STACK]); - return -EACCES; -@@ -1307,14 +1323,14 @@ static int check_stack_boundary(struct b - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), regs[regno].var_off); -- verbose("invalid variable stack read R%d var_off=%s\n", -+ verbose(env, "invalid variable stack read R%d var_off=%s\n", - regno, tn_buf); - return -EACCES; - } - off = regs[regno].off + regs[regno].var_off.value; - if (off >= 0 || off < -MAX_BPF_STACK || off + access_size > 0 || - access_size <= 0) { -- verbose("invalid stack type R%d off=%d access_size=%d\n", -+ verbose(env, "invalid stack type R%d off=%d access_size=%d\n", - regno, off, access_size); - return -EACCES; - } -@@ -1330,7 +1346,7 @@ static int check_stack_boundary(struct b - - for (i = 0; i < access_size; i++) { - if (state->stack_slot_type[MAX_BPF_STACK + off + i] != STACK_MISC) { -- verbose("invalid indirect read from stack off %d+%d size %d\n", -+ verbose(env, "invalid indirect read from stack off %d+%d size %d\n", - off, i, access_size); - return -EACCES; - } -@@ -1372,7 +1388,8 @@ static int check_func_arg(struct bpf_ver - - if (arg_type == ARG_ANYTHING) { - if (is_pointer_value(env, regno)) { -- verbose("R%d leaks addr into helper function\n", regno); -+ verbose(env, "R%d leaks addr into helper function\n", -+ regno); - return -EACCES; - } - return 0; -@@ -1380,7 +1397,7 @@ static int check_func_arg(struct bpf_ver - - if (type == PTR_TO_PACKET && - !may_access_direct_pkt_data(env, meta, BPF_READ)) { -- verbose("helper access to the packet is not allowed\n"); -+ verbose(env, "helper access to the packet is not allowed\n"); - return -EACCES; - } - -@@ -1416,7 +1433,7 @@ static int check_func_arg(struct bpf_ver - goto err_type; - meta->raw_mode = arg_type == ARG_PTR_TO_UNINIT_MEM; - } else { -- verbose("unsupported arg_type %d\n", arg_type); -+ verbose(env, "unsupported arg_type %d\n", arg_type); - return -EFAULT; - } - -@@ -1434,7 +1451,7 @@ static int check_func_arg(struct bpf_ver - * we have to check map_key here. Otherwise it means - * that kernel subsystem misconfigured verifier - */ -- verbose("invalid map_ptr to access map->key\n"); -+ verbose(env, "invalid map_ptr to access map->key\n"); - return -EACCES; - } - if (type == PTR_TO_PACKET) -@@ -1450,7 +1467,7 @@ static int check_func_arg(struct bpf_ver - */ - if (!meta->map_ptr) { - /* kernel subsystem misconfigured verifier */ -- verbose("invalid map_ptr to access map->value\n"); -+ verbose(env, "invalid map_ptr to access map->value\n"); - return -EACCES; - } - if (type == PTR_TO_PACKET) -@@ -1470,7 +1487,8 @@ static int check_func_arg(struct bpf_ver - */ - if (regno == 0) { - /* kernel subsystem misconfigured verifier */ -- verbose("ARG_CONST_SIZE cannot be first argument\n"); -+ verbose(env, -+ "ARG_CONST_SIZE cannot be first argument\n"); - return -EACCES; - } - -@@ -1487,7 +1505,7 @@ static int check_func_arg(struct bpf_ver - meta = NULL; - - if (reg->smin_value < 0) { -- verbose("R%d min value is negative, either use unsigned or 'var &= const'\n", -+ verbose(env, "R%d min value is negative, either use unsigned or 'var &= const'\n", - regno); - return -EACCES; - } -@@ -1501,7 +1519,7 @@ static int check_func_arg(struct bpf_ver - } - - if (reg->umax_value >= BPF_MAX_VAR_SIZ) { -- verbose("R%d unbounded memory access, use 'var &= const' or 'if (var < const)'\n", -+ verbose(env, "R%d unbounded memory access, use 'var &= const' or 'if (var < const)'\n", - regno); - return -EACCES; - } -@@ -1512,12 +1530,13 @@ static int check_func_arg(struct bpf_ver - - return err; - err_type: -- verbose("R%d type=%s expected=%s\n", regno, -+ verbose(env, "R%d type=%s expected=%s\n", regno, - reg_type_str[type], reg_type_str[expected_type]); - return -EACCES; - } - --static int check_map_func_compatibility(struct bpf_map *map, int func_id) -+static int check_map_func_compatibility(struct bpf_verifier_env *env, -+ struct bpf_map *map, int func_id) - { - if (!map) - return 0; -@@ -1603,7 +1622,7 @@ static int check_map_func_compatibility( - - return 0; - error: -- verbose("cannot pass map_type %d into func %s#%d\n", -+ verbose(env, "cannot pass map_type %d into func %s#%d\n", - map->map_type, func_id_name(func_id), func_id); - return -EINVAL; - } -@@ -1638,7 +1657,7 @@ static void clear_all_pkt_pointers(struc - for (i = 0; i < MAX_BPF_REG; i++) - if (regs[i].type == PTR_TO_PACKET || - regs[i].type == PTR_TO_PACKET_END) -- mark_reg_unknown(regs, i); -+ mark_reg_unknown(env, regs, i); - - for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { - if (state->stack_slot_type[i] != STACK_SPILL) -@@ -1662,7 +1681,8 @@ static int check_call(struct bpf_verifie - - /* find function prototype */ - if (func_id < 0 || func_id >= __BPF_FUNC_MAX_ID) { -- verbose("invalid func %s#%d\n", func_id_name(func_id), func_id); -+ verbose(env, "invalid func %s#%d\n", func_id_name(func_id), -+ func_id); - return -EINVAL; - } - -@@ -1670,13 +1690,14 @@ static int check_call(struct bpf_verifie - fn = env->prog->aux->ops->get_func_proto(func_id); - - if (!fn) { -- verbose("unknown func %s#%d\n", func_id_name(func_id), func_id); -+ verbose(env, "unknown func %s#%d\n", func_id_name(func_id), -+ func_id); - return -EINVAL; - } - - /* eBPF programs must be GPL compatible to use GPL-ed functions */ - if (!env->prog->gpl_compatible && fn->gpl_only) { -- verbose("cannot call GPL only function from proprietary program\n"); -+ verbose(env, "cannot call GPL only function from proprietary program\n"); - return -EINVAL; - } - -@@ -1690,7 +1711,7 @@ static int check_call(struct bpf_verifie - */ - err = check_raw_mode(fn); - if (err) { -- verbose("kernel subsystem misconfigured func %s#%d\n", -+ verbose(env, "kernel subsystem misconfigured func %s#%d\n", - func_id_name(func_id), func_id); - return err; - } -@@ -1723,14 +1744,14 @@ static int check_call(struct bpf_verifie - - /* reset caller saved regs */ - for (i = 0; i < CALLER_SAVED_REGS; i++) { -- mark_reg_not_init(regs, caller_saved[i]); -+ mark_reg_not_init(env, regs, caller_saved[i]); - check_reg_arg(env, caller_saved[i], DST_OP_NO_MARK); - } - - /* update return register (already marked as written above) */ - if (fn->ret_type == RET_INTEGER) { - /* sets type to SCALAR_VALUE */ -- mark_reg_unknown(regs, BPF_REG_0); -+ mark_reg_unknown(env, regs, BPF_REG_0); - } else if (fn->ret_type == RET_VOID) { - regs[BPF_REG_0].type = NOT_INIT; - } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) { -@@ -1738,14 +1759,15 @@ static int check_call(struct bpf_verifie - - regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL; - /* There is no offset yet applied, variable or fixed */ -- mark_reg_known_zero(regs, BPF_REG_0); -+ mark_reg_known_zero(env, regs, BPF_REG_0); - regs[BPF_REG_0].off = 0; - /* remember map_ptr, so that check_map_access() - * can check 'value_size' boundary of memory access - * to map element returned from bpf_map_lookup_elem() - */ - if (meta.map_ptr == NULL) { -- verbose("kernel subsystem misconfigured verifier\n"); -+ verbose(env, -+ "kernel subsystem misconfigured verifier\n"); - return -EINVAL; - } - regs[BPF_REG_0].map_ptr = meta.map_ptr; -@@ -1756,12 +1778,12 @@ static int check_call(struct bpf_verifie - else if (insn_aux->map_ptr != meta.map_ptr) - insn_aux->map_ptr = BPF_MAP_PTR_POISON; - } else { -- verbose("unknown return type %d of func %s#%d\n", -+ verbose(env, "unknown return type %d of func %s#%d\n", - fn->ret_type, func_id_name(func_id), func_id); - return -EINVAL; - } - -- err = check_map_func_compatibility(meta.map_ptr, func_id); -+ err = check_map_func_compatibility(env, meta.map_ptr, func_id); - if (err) - return err; - -@@ -1847,39 +1869,42 @@ static int adjust_ptr_min_max_vals(struc - dst_reg = ®s[dst]; - - if (WARN_ON_ONCE(known && (smin_val != smax_val))) { -- print_verifier_state(&env->cur_state); -- verbose("verifier internal error: known but bad sbounds\n"); -+ print_verifier_state(env, &env->cur_state); -+ verbose(env, -+ "verifier internal error: known but bad sbounds\n"); - return -EINVAL; - } - if (WARN_ON_ONCE(known && (umin_val != umax_val))) { -- print_verifier_state(&env->cur_state); -- verbose("verifier internal error: known but bad ubounds\n"); -+ print_verifier_state(env, &env->cur_state); -+ verbose(env, -+ "verifier internal error: known but bad ubounds\n"); - return -EINVAL; - } - - if (BPF_CLASS(insn->code) != BPF_ALU64) { - /* 32-bit ALU ops on pointers produce (meaningless) scalars */ - if (!env->allow_ptr_leaks) -- verbose("R%d 32-bit pointer arithmetic prohibited\n", -+ verbose(env, -+ "R%d 32-bit pointer arithmetic prohibited\n", - dst); - return -EACCES; - } - - if (ptr_reg->type == PTR_TO_MAP_VALUE_OR_NULL) { - if (!env->allow_ptr_leaks) -- verbose("R%d pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL prohibited, null-check it first\n", -+ verbose(env, "R%d pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL prohibited, null-check it first\n", - dst); - return -EACCES; - } - if (ptr_reg->type == CONST_PTR_TO_MAP) { - if (!env->allow_ptr_leaks) -- verbose("R%d pointer arithmetic on CONST_PTR_TO_MAP prohibited\n", -+ verbose(env, "R%d pointer arithmetic on CONST_PTR_TO_MAP prohibited\n", - dst); - return -EACCES; - } - if (ptr_reg->type == PTR_TO_PACKET_END) { - if (!env->allow_ptr_leaks) -- verbose("R%d pointer arithmetic on PTR_TO_PACKET_END prohibited\n", -+ verbose(env, "R%d pointer arithmetic on PTR_TO_PACKET_END prohibited\n", - dst); - return -EACCES; - } -@@ -1948,7 +1973,7 @@ static int adjust_ptr_min_max_vals(struc - if (dst_reg == off_reg) { - /* scalar -= pointer. Creates an unknown scalar */ - if (!env->allow_ptr_leaks) -- verbose("R%d tried to subtract pointer from scalar\n", -+ verbose(env, "R%d tried to subtract pointer from scalar\n", - dst); - return -EACCES; - } -@@ -1958,7 +1983,7 @@ static int adjust_ptr_min_max_vals(struc - */ - if (ptr_reg->type == PTR_TO_STACK) { - if (!env->allow_ptr_leaks) -- verbose("R%d subtraction from stack pointer prohibited\n", -+ verbose(env, "R%d subtraction from stack pointer prohibited\n", - dst); - return -EACCES; - } -@@ -2013,13 +2038,13 @@ static int adjust_ptr_min_max_vals(struc - * ptr &= ~3 which would reduce min_value by 3.) - */ - if (!env->allow_ptr_leaks) -- verbose("R%d bitwise operator %s on pointer prohibited\n", -+ verbose(env, "R%d bitwise operator %s on pointer prohibited\n", - dst, bpf_alu_string[opcode >> 4]); - return -EACCES; - default: - /* other operators (e.g. MUL,LSH) produce non-pointer results */ - if (!env->allow_ptr_leaks) -- verbose("R%d pointer arithmetic with %s operator prohibited\n", -+ verbose(env, "R%d pointer arithmetic with %s operator prohibited\n", - dst, bpf_alu_string[opcode >> 4]); - return -EACCES; - } -@@ -2194,7 +2219,7 @@ static int adjust_scalar_min_max_vals(st - /* Shifts greater than 31 or 63 are undefined. - * This includes shifts by a negative number. - */ -- mark_reg_unknown(regs, insn->dst_reg); -+ mark_reg_unknown(env, regs, insn->dst_reg); - break; - } - /* We lose all sign bit information (except what we can pick -@@ -2222,7 +2247,7 @@ static int adjust_scalar_min_max_vals(st - /* Shifts greater than 31 or 63 are undefined. - * This includes shifts by a negative number. - */ -- mark_reg_unknown(regs, insn->dst_reg); -+ mark_reg_unknown(env, regs, insn->dst_reg); - break; - } - /* BPF_RSH is an unsigned shift. If the value in dst_reg might -@@ -2252,7 +2277,7 @@ static int adjust_scalar_min_max_vals(st - __update_reg_bounds(dst_reg); - break; - default: -- mark_reg_unknown(regs, insn->dst_reg); -+ mark_reg_unknown(env, regs, insn->dst_reg); - break; - } - -@@ -2290,12 +2315,12 @@ static int adjust_reg_min_max_vals(struc - * an arbitrary scalar. - */ - if (!env->allow_ptr_leaks) { -- verbose("R%d pointer %s pointer prohibited\n", -+ verbose(env, "R%d pointer %s pointer prohibited\n", - insn->dst_reg, - bpf_alu_string[opcode >> 4]); - return -EACCES; - } -- mark_reg_unknown(regs, insn->dst_reg); -+ mark_reg_unknown(env, regs, insn->dst_reg); - return 0; - } else { - /* scalar += pointer -@@ -2347,13 +2372,13 @@ static int adjust_reg_min_max_vals(struc - - /* Got here implies adding two SCALAR_VALUEs */ - if (WARN_ON_ONCE(ptr_reg)) { -- print_verifier_state(&env->cur_state); -- verbose("verifier internal error: unexpected ptr_reg\n"); -+ print_verifier_state(env, &env->cur_state); -+ verbose(env, "verifier internal error: unexpected ptr_reg\n"); - return -EINVAL; - } - if (WARN_ON(!src_reg)) { -- print_verifier_state(&env->cur_state); -- verbose("verifier internal error: no src_reg\n"); -+ print_verifier_state(env, &env->cur_state); -+ verbose(env, "verifier internal error: no src_reg\n"); - return -EINVAL; - } - return adjust_scalar_min_max_vals(env, insn, dst_reg, *src_reg); -@@ -2371,14 +2396,14 @@ static int check_alu_op(struct bpf_verif - if (BPF_SRC(insn->code) != 0 || - insn->src_reg != BPF_REG_0 || - insn->off != 0 || insn->imm != 0) { -- verbose("BPF_NEG uses reserved fields\n"); -+ verbose(env, "BPF_NEG uses reserved fields\n"); - return -EINVAL; - } - } else { - if (insn->src_reg != BPF_REG_0 || insn->off != 0 || - (insn->imm != 16 && insn->imm != 32 && insn->imm != 64) || - BPF_CLASS(insn->code) == BPF_ALU64) { -- verbose("BPF_END uses reserved fields\n"); -+ verbose(env, "BPF_END uses reserved fields\n"); - return -EINVAL; - } - } -@@ -2389,7 +2414,7 @@ static int check_alu_op(struct bpf_verif - return err; - - if (is_pointer_value(env, insn->dst_reg)) { -- verbose("R%d pointer arithmetic prohibited\n", -+ verbose(env, "R%d pointer arithmetic prohibited\n", - insn->dst_reg); - return -EACCES; - } -@@ -2403,7 +2428,7 @@ static int check_alu_op(struct bpf_verif - - if (BPF_SRC(insn->code) == BPF_X) { - if (insn->imm != 0 || insn->off != 0) { -- verbose("BPF_MOV uses reserved fields\n"); -+ verbose(env, "BPF_MOV uses reserved fields\n"); - return -EINVAL; - } - -@@ -2413,7 +2438,7 @@ static int check_alu_op(struct bpf_verif - return err; - } else { - if (insn->src_reg != BPF_REG_0 || insn->off != 0) { -- verbose("BPF_MOV uses reserved fields\n"); -+ verbose(env, "BPF_MOV uses reserved fields\n"); - return -EINVAL; - } - } -@@ -2433,11 +2458,12 @@ static int check_alu_op(struct bpf_verif - } else { - /* R1 = (u32) R2 */ - if (is_pointer_value(env, insn->src_reg)) { -- verbose("R%d partial copy of pointer\n", -+ verbose(env, -+ "R%d partial copy of pointer\n", - insn->src_reg); - return -EACCES; - } -- mark_reg_unknown(regs, insn->dst_reg); -+ mark_reg_unknown(env, regs, insn->dst_reg); - coerce_reg_to_size(®s[insn->dst_reg], 4); - } - } else { -@@ -2455,14 +2481,14 @@ static int check_alu_op(struct bpf_verif - } - - } else if (opcode > BPF_END) { -- verbose("invalid BPF_ALU opcode %x\n", opcode); -+ verbose(env, "invalid BPF_ALU opcode %x\n", opcode); - return -EINVAL; - - } else { /* all other ALU ops: and, sub, xor, add, ... */ - - if (BPF_SRC(insn->code) == BPF_X) { - if (insn->imm != 0 || insn->off != 0) { -- verbose("BPF_ALU uses reserved fields\n"); -+ verbose(env, "BPF_ALU uses reserved fields\n"); - return -EINVAL; - } - /* check src1 operand */ -@@ -2471,7 +2497,7 @@ static int check_alu_op(struct bpf_verif - return err; - } else { - if (insn->src_reg != BPF_REG_0 || insn->off != 0) { -- verbose("BPF_ALU uses reserved fields\n"); -+ verbose(env, "BPF_ALU uses reserved fields\n"); - return -EINVAL; - } - } -@@ -2483,7 +2509,7 @@ static int check_alu_op(struct bpf_verif - - if ((opcode == BPF_MOD || opcode == BPF_DIV) && - BPF_SRC(insn->code) == BPF_K && insn->imm == 0) { -- verbose("div by zero\n"); -+ verbose(env, "div by zero\n"); - return -EINVAL; - } - -@@ -2492,7 +2518,7 @@ static int check_alu_op(struct bpf_verif - int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32; - - if (insn->imm < 0 || insn->imm >= size) { -- verbose("invalid shift %d\n", insn->imm); -+ verbose(env, "invalid shift %d\n", insn->imm); - return -EINVAL; - } - } -@@ -2853,13 +2879,13 @@ static int check_cond_jmp_op(struct bpf_ - int err; - - if (opcode > BPF_JSLE) { -- verbose("invalid BPF_JMP opcode %x\n", opcode); -+ verbose(env, "invalid BPF_JMP opcode %x\n", opcode); - return -EINVAL; - } - - if (BPF_SRC(insn->code) == BPF_X) { - if (insn->imm != 0) { -- verbose("BPF_JMP uses reserved fields\n"); -+ verbose(env, "BPF_JMP uses reserved fields\n"); - return -EINVAL; - } - -@@ -2869,13 +2895,13 @@ static int check_cond_jmp_op(struct bpf_ - return err; - - if (is_pointer_value(env, insn->src_reg)) { -- verbose("R%d pointer comparison prohibited\n", -+ verbose(env, "R%d pointer comparison prohibited\n", - insn->src_reg); - return -EACCES; - } - } else { - if (insn->src_reg != BPF_REG_0) { -- verbose("BPF_JMP uses reserved fields\n"); -+ verbose(env, "BPF_JMP uses reserved fields\n"); - return -EINVAL; - } - } -@@ -2991,11 +3017,12 @@ static int check_cond_jmp_op(struct bpf_ - /* pkt_end <= pkt_data' */ - find_good_pkt_pointers(this_branch, ®s[insn->src_reg], true); - } else if (is_pointer_value(env, insn->dst_reg)) { -- verbose("R%d pointer comparison prohibited\n", insn->dst_reg); -+ verbose(env, "R%d pointer comparison prohibited\n", -+ insn->dst_reg); - return -EACCES; - } -- if (verifier_log.level) -- print_verifier_state(this_branch); -+ if (env->log.level) -+ print_verifier_state(env, this_branch); - return 0; - } - -@@ -3014,11 +3041,11 @@ static int check_ld_imm(struct bpf_verif - int err; - - if (BPF_SIZE(insn->code) != BPF_DW) { -- verbose("invalid BPF_LD_IMM insn\n"); -+ verbose(env, "invalid BPF_LD_IMM insn\n"); - return -EINVAL; - } - if (insn->off != 0) { -- verbose("BPF_LD_IMM64 uses reserved fields\n"); -+ verbose(env, "BPF_LD_IMM64 uses reserved fields\n"); - return -EINVAL; - } - -@@ -3076,14 +3103,14 @@ static int check_ld_abs(struct bpf_verif - int i, err; - - if (!may_access_skb(env->prog->type)) { -- verbose("BPF_LD_[ABS|IND] instructions not allowed for this program type\n"); -+ verbose(env, "BPF_LD_[ABS|IND] instructions not allowed for this program type\n"); - return -EINVAL; - } - - if (insn->dst_reg != BPF_REG_0 || insn->off != 0 || - BPF_SIZE(insn->code) == BPF_DW || - (mode == BPF_ABS && insn->src_reg != BPF_REG_0)) { -- verbose("BPF_LD_[ABS|IND] uses reserved fields\n"); -+ verbose(env, "BPF_LD_[ABS|IND] uses reserved fields\n"); - return -EINVAL; - } - -@@ -3093,7 +3120,8 @@ static int check_ld_abs(struct bpf_verif - return err; - - if (regs[BPF_REG_6].type != PTR_TO_CTX) { -- verbose("at the time of BPF_LD_ABS|IND R6 != pointer to skb\n"); -+ verbose(env, -+ "at the time of BPF_LD_ABS|IND R6 != pointer to skb\n"); - return -EINVAL; - } - -@@ -3106,7 +3134,7 @@ static int check_ld_abs(struct bpf_verif - - /* reset caller saved regs to unreadable */ - for (i = 0; i < CALLER_SAVED_REGS; i++) { -- mark_reg_not_init(regs, caller_saved[i]); -+ mark_reg_not_init(env, regs, caller_saved[i]); - check_reg_arg(env, caller_saved[i], DST_OP_NO_MARK); - } - -@@ -3114,7 +3142,7 @@ static int check_ld_abs(struct bpf_verif - * the value fetched from the packet. - * Already marked as written above. - */ -- mark_reg_unknown(regs, BPF_REG_0); -+ mark_reg_unknown(env, regs, BPF_REG_0); - return 0; - } - -@@ -3178,7 +3206,7 @@ static int push_insn(int t, int w, int e - return 0; - - if (w < 0 || w >= env->prog->len) { -- verbose("jump out of range from insn %d to %d\n", t, w); -+ verbose(env, "jump out of range from insn %d to %d\n", t, w); - return -EINVAL; - } - -@@ -3195,13 +3223,13 @@ static int push_insn(int t, int w, int e - insn_stack[cur_stack++] = w; - return 1; - } else if ((insn_state[w] & 0xF0) == DISCOVERED) { -- verbose("back-edge from insn %d to %d\n", t, w); -+ verbose(env, "back-edge from insn %d to %d\n", t, w); - return -EINVAL; - } else if (insn_state[w] == EXPLORED) { - /* forward- or cross-edge */ - insn_state[t] = DISCOVERED | e; - } else { -- verbose("insn state internal bug\n"); -+ verbose(env, "insn state internal bug\n"); - return -EFAULT; - } - return 0; -@@ -3295,7 +3323,7 @@ peek_stack: - mark_explored: - insn_state[t] = EXPLORED; - if (cur_stack-- <= 0) { -- verbose("pop stack internal bug\n"); -+ verbose(env, "pop stack internal bug\n"); - ret = -EFAULT; - goto err_free; - } -@@ -3304,7 +3332,7 @@ mark_explored: - check_state: - for (i = 0; i < insn_cnt; i++) { - if (insn_state[i] != EXPLORED) { -- verbose("unreachable insn %d\n", i); -+ verbose(env, "unreachable insn %d\n", i); - ret = -EINVAL; - goto err_free; - } -@@ -3683,7 +3711,7 @@ static int do_check(struct bpf_verifier_ - int insn_processed = 0; - bool do_print_state = false; - -- init_reg_state(regs); -+ init_reg_state(env, regs); - state->parent = NULL; - insn_idx = 0; - for (;;) { -@@ -3692,7 +3720,7 @@ static int do_check(struct bpf_verifier_ - int err; - - if (insn_idx >= insn_cnt) { -- verbose("invalid insn idx %d insn_cnt %d\n", -+ verbose(env, "invalid insn idx %d insn_cnt %d\n", - insn_idx, insn_cnt); - return -EFAULT; - } -@@ -3701,7 +3729,8 @@ static int do_check(struct bpf_verifier_ - class = BPF_CLASS(insn->code); - - if (++insn_processed > BPF_COMPLEXITY_LIMIT_INSNS) { -- verbose("BPF program is too large. Processed %d insn\n", -+ verbose(env, -+ "BPF program is too large. Processed %d insn\n", - insn_processed); - return -E2BIG; - } -@@ -3711,12 +3740,12 @@ static int do_check(struct bpf_verifier_ - return err; - if (err == 1) { - /* found equivalent state, can prune the search */ -- if (verifier_log.level) { -+ if (env->log.level) { - if (do_print_state) -- verbose("\nfrom %d to %d: safe\n", -+ verbose(env, "\nfrom %d to %d: safe\n", - prev_insn_idx, insn_idx); - else -- verbose("%d: safe\n", insn_idx); -+ verbose(env, "%d: safe\n", insn_idx); - } - goto process_bpf_exit; - } -@@ -3724,19 +3753,18 @@ static int do_check(struct bpf_verifier_ - if (need_resched()) - cond_resched(); - -- if (verifier_log.level > 1 || -- (verifier_log.level && do_print_state)) { -- if (verifier_log.level > 1) -- verbose("%d:", insn_idx); -+ if (env->log.level > 1 || (env->log.level && do_print_state)) { -+ if (env->log.level > 1) -+ verbose(env, "%d:", insn_idx); - else -- verbose("\nfrom %d to %d:", -+ verbose(env, "\nfrom %d to %d:", - prev_insn_idx, insn_idx); -- print_verifier_state(&env->cur_state); -+ print_verifier_state(env, &env->cur_state); - do_print_state = false; - } - -- if (verifier_log.level) { -- verbose("%d: ", insn_idx); -+ if (env->log.level) { -+ verbose(env, "%d: ", insn_idx); - print_bpf_insn(env, insn); - } - -@@ -3794,7 +3822,7 @@ static int do_check(struct bpf_verifier_ - * src_reg == stack|map in some other branch. - * Reject it. - */ -- verbose("same insn cannot be used with different pointers\n"); -+ verbose(env, "same insn cannot be used with different pointers\n"); - return -EINVAL; - } - -@@ -3834,14 +3862,14 @@ static int do_check(struct bpf_verifier_ - } else if (dst_reg_type != *prev_dst_type && - (dst_reg_type == PTR_TO_CTX || - *prev_dst_type == PTR_TO_CTX)) { -- verbose("same insn cannot be used with different pointers\n"); -+ verbose(env, "same insn cannot be used with different pointers\n"); - return -EINVAL; - } - - } else if (class == BPF_ST) { - if (BPF_MODE(insn->code) != BPF_MEM || - insn->src_reg != BPF_REG_0) { -- verbose("BPF_ST uses reserved fields\n"); -+ verbose(env, "BPF_ST uses reserved fields\n"); - return -EINVAL; - } - /* check src operand */ -@@ -3864,7 +3892,7 @@ static int do_check(struct bpf_verifier_ - insn->off != 0 || - insn->src_reg != BPF_REG_0 || - insn->dst_reg != BPF_REG_0) { -- verbose("BPF_CALL uses reserved fields\n"); -+ verbose(env, "BPF_CALL uses reserved fields\n"); - return -EINVAL; - } - -@@ -3877,7 +3905,7 @@ static int do_check(struct bpf_verifier_ - insn->imm != 0 || - insn->src_reg != BPF_REG_0 || - insn->dst_reg != BPF_REG_0) { -- verbose("BPF_JA uses reserved fields\n"); -+ verbose(env, "BPF_JA uses reserved fields\n"); - return -EINVAL; - } - -@@ -3889,7 +3917,7 @@ static int do_check(struct bpf_verifier_ - insn->imm != 0 || - insn->src_reg != BPF_REG_0 || - insn->dst_reg != BPF_REG_0) { -- verbose("BPF_EXIT uses reserved fields\n"); -+ verbose(env, "BPF_EXIT uses reserved fields\n"); - return -EINVAL; - } - -@@ -3904,7 +3932,7 @@ static int do_check(struct bpf_verifier_ - return err; - - if (is_pointer_value(env, BPF_REG_0)) { -- verbose("R0 leaks addr as return value\n"); -+ verbose(env, "R0 leaks addr as return value\n"); - return -EACCES; - } - -@@ -3937,19 +3965,19 @@ process_bpf_exit: - insn_idx++; - env->insn_aux_data[insn_idx].seen = true; - } else { -- verbose("invalid BPF_LD mode\n"); -+ verbose(env, "invalid BPF_LD mode\n"); - return -EINVAL; - } - } else { -- verbose("unknown insn class %d\n", class); -+ verbose(env, "unknown insn class %d\n", class); - return -EINVAL; - } - - insn_idx++; - } - -- verbose("processed %d insns, stack depth %d\n", -- insn_processed, env->prog->aux->stack_depth); -+ verbose(env, "processed %d insns, stack depth %d\n", insn_processed, -+ env->prog->aux->stack_depth); - return 0; - } - -@@ -3961,7 +3989,8 @@ static int check_map_prealloc(struct bpf - !(map->map_flags & BPF_F_NO_PREALLOC); - } - --static int check_map_prog_compatibility(struct bpf_map *map, -+static int check_map_prog_compatibility(struct bpf_verifier_env *env, -+ struct bpf_map *map, - struct bpf_prog *prog) - - { -@@ -3972,12 +4001,12 @@ static int check_map_prog_compatibility( - */ - if (prog->type == BPF_PROG_TYPE_PERF_EVENT) { - if (!check_map_prealloc(map)) { -- verbose("perf_event programs can only use preallocated hash map\n"); -+ verbose(env, "perf_event programs can only use preallocated hash map\n"); - return -EINVAL; - } - if (map->inner_map_meta && - !check_map_prealloc(map->inner_map_meta)) { -- verbose("perf_event programs can only use preallocated inner hash map\n"); -+ verbose(env, "perf_event programs can only use preallocated inner hash map\n"); - return -EINVAL; - } - } -@@ -4000,14 +4029,14 @@ static int replace_map_fd_with_map_ptr(s - for (i = 0; i < insn_cnt; i++, insn++) { - if (BPF_CLASS(insn->code) == BPF_LDX && - (BPF_MODE(insn->code) != BPF_MEM || insn->imm != 0)) { -- verbose("BPF_LDX uses reserved fields\n"); -+ verbose(env, "BPF_LDX uses reserved fields\n"); - return -EINVAL; - } - - if (BPF_CLASS(insn->code) == BPF_STX && - ((BPF_MODE(insn->code) != BPF_MEM && - BPF_MODE(insn->code) != BPF_XADD) || insn->imm != 0)) { -- verbose("BPF_STX uses reserved fields\n"); -+ verbose(env, "BPF_STX uses reserved fields\n"); - return -EINVAL; - } - -@@ -4018,7 +4047,7 @@ static int replace_map_fd_with_map_ptr(s - if (i == insn_cnt - 1 || insn[1].code != 0 || - insn[1].dst_reg != 0 || insn[1].src_reg != 0 || - insn[1].off != 0) { -- verbose("invalid bpf_ld_imm64 insn\n"); -+ verbose(env, "invalid bpf_ld_imm64 insn\n"); - return -EINVAL; - } - -@@ -4027,19 +4056,20 @@ static int replace_map_fd_with_map_ptr(s - goto next_insn; - - if (insn->src_reg != BPF_PSEUDO_MAP_FD) { -- verbose("unrecognized bpf_ld_imm64 insn\n"); -+ verbose(env, -+ "unrecognized bpf_ld_imm64 insn\n"); - return -EINVAL; - } - - f = fdget(insn->imm); - map = __bpf_map_get(f); - if (IS_ERR(map)) { -- verbose("fd %d is not pointing to valid bpf_map\n", -+ verbose(env, "fd %d is not pointing to valid bpf_map\n", - insn->imm); - return PTR_ERR(map); - } - -- err = check_map_prog_compatibility(map, env->prog); -+ err = check_map_prog_compatibility(env, map, env->prog); - if (err) { - fdput(f); - return err; -@@ -4183,7 +4213,7 @@ static int convert_ctx_accesses(struct b - cnt = ops->gen_prologue(insn_buf, env->seen_direct_write, - env->prog); - if (cnt >= ARRAY_SIZE(insn_buf)) { -- verbose("bpf verifier is misconfigured\n"); -+ verbose(env, "bpf verifier is misconfigured\n"); - return -EINVAL; - } else if (cnt) { - new_prog = bpf_patch_insn_data(env, 0, insn_buf, cnt); -@@ -4231,7 +4261,7 @@ static int convert_ctx_accesses(struct b - u8 size_code; - - if (type == BPF_WRITE) { -- verbose("bpf verifier narrow ctx access misconfigured\n"); -+ verbose(env, "bpf verifier narrow ctx access misconfigured\n"); - return -EINVAL; - } - -@@ -4250,7 +4280,7 @@ static int convert_ctx_accesses(struct b - &target_size); - if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf) || - (ctx_field_size && !target_size)) { -- verbose("bpf verifier is misconfigured\n"); -+ verbose(env, "bpf verifier is misconfigured\n"); - return -EINVAL; - } - -@@ -4332,7 +4362,7 @@ static int fixup_bpf_calls(struct bpf_ve - - cnt = map_ptr->ops->map_gen_lookup(map_ptr, insn_buf); - if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) { -- verbose("bpf verifier is misconfigured\n"); -+ verbose(env, "bpf verifier is misconfigured\n"); - return -EINVAL; - } - -@@ -4376,7 +4406,8 @@ patch_call_imm: - * programs to call them, must be real in-kernel functions - */ - if (!fn->func) { -- verbose("kernel subsystem misconfigured func %s#%d\n", -+ verbose(env, -+ "kernel subsystem misconfigured func %s#%d\n", - func_id_name(insn->imm), insn->imm); - return -EFAULT; - } -@@ -4410,8 +4441,8 @@ static void free_states(struct bpf_verif - - int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) - { -- struct bpf_verifer_log *log = &verifier_log; - struct bpf_verifier_env *env; -+ struct bpf_verifer_log *log; - int ret = -EINVAL; - - /* 'struct bpf_verifier_env' can be global, but since it's not small, -@@ -4420,6 +4451,7 @@ int bpf_check(struct bpf_prog **prog, un - env = kzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL); - if (!env) - return -ENOMEM; -+ log = &env->log; - - env->insn_aux_data = vzalloc(sizeof(struct bpf_insn_aux_data) * - (*prog)->len); -@@ -4438,7 +4470,6 @@ int bpf_check(struct bpf_prog **prog, un - log->level = attr->log_level; - log->ubuf = (char __user *) (unsigned long) attr->log_buf; - log->len_total = attr->log_size; -- log->len_used = 0; - - ret = -EINVAL; - /* log attributes have to be sane */ -@@ -4450,8 +4481,6 @@ int bpf_check(struct bpf_prog **prog, un - log->kbuf = vmalloc(log->len_total); - if (!log->kbuf) - goto err_unlock; -- } else { -- log->level = 0; - } - - env->strict_alignment = !!(attr->prog_flags & BPF_F_STRICT_ALIGNMENT); -@@ -4565,8 +4594,6 @@ int bpf_analyzer(struct bpf_prog *prog, - /* grab the mutex to protect few globals used by verifier */ - mutex_lock(&bpf_verifier_lock); - -- verifier_log.level = 0; -- - env->strict_alignment = false; - if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) - env->strict_alignment = true; diff --git a/debian/patches/bugfix/all/e1000e-fix-e1000_check_for_copper_link_ich8lan-return-value.patch b/debian/patches/bugfix/all/e1000e-fix-e1000_check_for_copper_link_ich8lan-return-value.patch deleted file mode 100644 index bedfd0282..000000000 --- a/debian/patches/bugfix/all/e1000e-fix-e1000_check_for_copper_link_ich8lan-return-value.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Benjamin Poirier -Date: Mon, 11 Dec 2017 16:26:40 +0900 -Subject: e1000e: Fix e1000_check_for_copper_link_ich8lan return value. -Origin: https://marc.info/?l=linux-kernel&m=151297726823919&w=2 -Bug: https://bugzilla.kernel.org/show_bug.cgi?id=198047 -Bug-Debian: https://bugs.debian.org/885348 - -e1000e_check_for_copper_link() and e1000_check_for_copper_link_ich8lan() -are the two functions that may be assigned to mac.ops.check_for_link when -phy.media_type == e1000_media_type_copper. Commit 19110cfbb34d ("e1000e: -Separate signaling for link check/link up") changed the meaning of the -return value of check_for_link for copper media but only adjusted the first -function. This patch adjusts the second function likewise. - -Reported-by: Christian Hesse -Reported-by: Gabriel C -Link: https://bugzilla.kernel.org/show_bug.cgi?id=198047 -Fixes: 19110cfbb34d ("e1000e: Separate signaling for link check/link up") -Tested-by: Christian Hesse -Signed-off-by: Benjamin Poirier ---- - drivers/net/ethernet/intel/e1000e/ich8lan.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/intel/e1000e/ich8lan.c -+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c -@@ -1367,6 +1367,9 @@ out: - * Checks to see of the link status of the hardware has changed. If a - * change in link status has been detected, then we read the PHY registers - * to get the current speed/duplex if link exists. -+ * -+ * Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link -+ * up). - **/ - static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) - { -@@ -1382,7 +1385,7 @@ static s32 e1000_check_for_copper_link_i - * Change or Rx Sequence Error interrupt. - */ - if (!mac->get_link_status) -- return 0; -+ return 1; - - /* First we want to see if the MII Status Register reports - * link. If so, then we want to get the current speed/duplex -@@ -1613,10 +1616,12 @@ static s32 e1000_check_for_copper_link_i - * different link partner. - */ - ret_val = e1000e_config_fc_after_link_up(hw); -- if (ret_val) -+ if (ret_val) { - e_dbg("Error configuring flow control\n"); -+ return ret_val; -+ } - -- return ret_val; -+ return 1; - } - - static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) diff --git a/debian/patches/bugfix/all/kvm-fix-stack-out-of-bounds-read-in-write_mmio.patch b/debian/patches/bugfix/all/kvm-fix-stack-out-of-bounds-read-in-write_mmio.patch deleted file mode 100644 index c460e89c5..000000000 --- a/debian/patches/bugfix/all/kvm-fix-stack-out-of-bounds-read-in-write_mmio.patch +++ /dev/null @@ -1,153 +0,0 @@ -From: Wanpeng Li -Date: Thu, 14 Dec 2017 17:40:50 -0800 -Subject: KVM: Fix stack-out-of-bounds read in write_mmio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Origin: https://git.kernel.org/pub/scm/virt/kvm/kvm.git/commit?id=e39d200fa5bf5b94a0948db0dae44c1b73b84a56 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-17741 - -Reported by syzkaller: - - BUG: KASAN: stack-out-of-bounds in write_mmio+0x11e/0x270 [kvm] - Read of size 8 at addr ffff8803259df7f8 by task syz-executor/32298 - - CPU: 6 PID: 32298 Comm: syz-executor Tainted: G OE 4.15.0-rc2+ #18 - Hardware name: LENOVO ThinkCentre M8500t-N000/SHARKBAY, BIOS FBKTC1AUS 02/16/2016 - Call Trace: - dump_stack+0xab/0xe1 - print_address_description+0x6b/0x290 - kasan_report+0x28a/0x370 - write_mmio+0x11e/0x270 [kvm] - emulator_read_write_onepage+0x311/0x600 [kvm] - emulator_read_write+0xef/0x240 [kvm] - emulator_fix_hypercall+0x105/0x150 [kvm] - em_hypercall+0x2b/0x80 [kvm] - x86_emulate_insn+0x2b1/0x1640 [kvm] - x86_emulate_instruction+0x39a/0xb90 [kvm] - handle_exception+0x1b4/0x4d0 [kvm_intel] - vcpu_enter_guest+0x15a0/0x2640 [kvm] - kvm_arch_vcpu_ioctl_run+0x549/0x7d0 [kvm] - kvm_vcpu_ioctl+0x479/0x880 [kvm] - do_vfs_ioctl+0x142/0x9a0 - SyS_ioctl+0x74/0x80 - entry_SYSCALL_64_fastpath+0x23/0x9a - -The path of patched vmmcall will patch 3 bytes opcode 0F 01 C1(vmcall) -to the guest memory, however, write_mmio tracepoint always prints 8 bytes -through *(u64 *)val since kvm splits the mmio access into 8 bytes. This -leaks 5 bytes from the kernel stack (CVE-2017-17741). This patch fixes -it by just accessing the bytes which we operate on. - -Before patch: - -syz-executor-5567 [007] .... 51370.561696: kvm_mmio: mmio write len 3 gpa 0x10 val 0x1ffff10077c1010f - -After patch: - -syz-executor-13416 [002] .... 51302.299573: kvm_mmio: mmio write len 3 gpa 0x10 val 0xc1010f - -Reported-by: Dmitry Vyukov -Reviewed-by: Darren Kenny -Reviewed-by: Marc Zyngier -Tested-by: Marc Zyngier -Cc: Paolo Bonzini -Cc: Radim Krčmář -Cc: Marc Zyngier -Cc: Christoffer Dall -Signed-off-by: Wanpeng Li -Signed-off-by: Paolo Bonzini ---- - arch/x86/kvm/x86.c | 8 ++++---- - include/trace/events/kvm.h | 7 +++++-- - virt/kvm/arm/mmio.c | 6 +++--- - 3 files changed, 12 insertions(+), 9 deletions(-) - ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -4362,7 +4362,7 @@ static int vcpu_mmio_read(struct kvm_vcp - addr, n, v)) - && kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, n, v)) - break; -- trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v); -+ trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, v); - handled += n; - addr += n; - len -= n; -@@ -4621,7 +4621,7 @@ static int read_prepare(struct kvm_vcpu - { - if (vcpu->mmio_read_completed) { - trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, -- vcpu->mmio_fragments[0].gpa, *(u64 *)val); -+ vcpu->mmio_fragments[0].gpa, val); - vcpu->mmio_read_completed = 0; - return 1; - } -@@ -4643,14 +4643,14 @@ static int write_emulate(struct kvm_vcpu - - static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val) - { -- trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val); -+ trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, val); - return vcpu_mmio_write(vcpu, gpa, bytes, val); - } - - static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, - void *val, int bytes) - { -- trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0); -+ trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, NULL); - return X86EMUL_IO_NEEDED; - } - ---- a/include/trace/events/kvm.h -+++ b/include/trace/events/kvm.h -@@ -211,7 +211,7 @@ TRACE_EVENT(kvm_ack_irq, - { KVM_TRACE_MMIO_WRITE, "write" } - - TRACE_EVENT(kvm_mmio, -- TP_PROTO(int type, int len, u64 gpa, u64 val), -+ TP_PROTO(int type, int len, u64 gpa, void *val), - TP_ARGS(type, len, gpa, val), - - TP_STRUCT__entry( -@@ -225,7 +225,10 @@ TRACE_EVENT(kvm_mmio, - __entry->type = type; - __entry->len = len; - __entry->gpa = gpa; -- __entry->val = val; -+ __entry->val = 0; -+ if (val) -+ memcpy(&__entry->val, val, -+ min_t(u32, sizeof(__entry->val), len)); - ), - - TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx", ---- a/virt/kvm/arm/mmio.c -+++ b/virt/kvm/arm/mmio.c -@@ -112,7 +112,7 @@ int kvm_handle_mmio_return(struct kvm_vc - } - - trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, -- data); -+ &data); - data = vcpu_data_host_to_guest(vcpu, data, len); - vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data); - } -@@ -182,14 +182,14 @@ int io_mem_abort(struct kvm_vcpu *vcpu, - data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt), - len); - -- trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data); -+ trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, &data); - kvm_mmio_write_buf(data_buf, len, data); - - ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len, - data_buf); - } else { - trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len, -- fault_ipa, 0); -+ fault_ipa, NULL); - - ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len, - data_buf); diff --git a/debian/patches/debian/bpf-avoid-abi-change-in-4.14.14.patch b/debian/patches/debian/bpf-avoid-abi-change-in-4.14.14.patch new file mode 100644 index 000000000..39b879e10 --- /dev/null +++ b/debian/patches/debian/bpf-avoid-abi-change-in-4.14.14.patch @@ -0,0 +1,138 @@ +From: Ben Hutchings +Date: Thu, 18 Jan 2018 05:17:34 +0000 +Subject: bpf: Avoid ABI change in 4.14.14 +Forwarded: not-needed + +Commit b2157399cc98 "bpf: prevent out-of-bounds speculation" added one +member each to struct bpf_map and struct bpf_array (which is +effectively a sub-type of bpf_map). Changing the size of struct +bpf_array is an ABI change, since the array contents immediately +follows the structure. However, bpf_map::work is not used (or even +initialised) until after the map's refcount drops to zero. We can +therefore move the new members into a union with it. + +--- +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -51,10 +51,20 @@ struct bpf_map { + u32 pages; + u32 id; + int numa_node; +- bool unpriv_array; ++ + struct user_struct *user; + const struct bpf_map_ops *ops; ++#ifdef __GENKSYMS__ + struct work_struct work; ++#else ++ union { ++ struct work_struct work; ++ struct { ++ bool unpriv_array; ++ u32 index_mask; ++ }; ++ }; ++#endif + atomic_t usercnt; + struct bpf_map *inner_map_meta; + }; +@@ -196,7 +206,6 @@ struct bpf_prog_aux { + struct bpf_array { + struct bpf_map map; + u32 elem_size; +- u32 index_mask; + /* 'ownership' of prog_array is claimed by the first program that + * is going to use this map or by the first program which FD is stored + * in the map to make sure that all callers and callees have the same +--- a/kernel/bpf/arraymap.c ++++ b/kernel/bpf/arraymap.c +@@ -104,7 +104,7 @@ static struct bpf_map *array_map_alloc(u + array = bpf_map_area_alloc(array_size, numa_node); + if (!array) + return ERR_PTR(-ENOMEM); +- array->index_mask = index_mask; ++ array->map.index_mask = index_mask; + array->map.unpriv_array = unpriv; + + /* copy mandatory map attributes */ +@@ -141,7 +141,7 @@ static void *array_map_lookup_elem(struc + if (unlikely(index >= array->map.max_entries)) + return NULL; + +- return array->value + array->elem_size * (index & array->index_mask); ++ return array->value + array->elem_size * (index & array->map.index_mask); + } + + /* emit BPF instructions equivalent to C code of array_map_lookup_elem() */ +@@ -158,7 +158,7 @@ static u32 array_map_gen_lookup(struct b + *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); + if (map->unpriv_array) { + *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 4); +- *insn++ = BPF_ALU32_IMM(BPF_AND, ret, array->index_mask); ++ *insn++ = BPF_ALU32_IMM(BPF_AND, ret, array->map.index_mask); + } else { + *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 3); + } +@@ -183,7 +183,7 @@ static void *percpu_array_map_lookup_ele + if (unlikely(index >= array->map.max_entries)) + return NULL; + +- return this_cpu_ptr(array->pptrs[index & array->index_mask]); ++ return this_cpu_ptr(array->pptrs[index & array->map.index_mask]); + } + + int bpf_percpu_array_copy(struct bpf_map *map, void *key, void *value) +@@ -203,7 +203,7 @@ int bpf_percpu_array_copy(struct bpf_map + */ + size = round_up(map->value_size, 8); + rcu_read_lock(); +- pptr = array->pptrs[index & array->index_mask]; ++ pptr = array->pptrs[index & array->map.index_mask]; + for_each_possible_cpu(cpu) { + bpf_long_memcpy(value + off, per_cpu_ptr(pptr, cpu), size); + off += size; +@@ -251,11 +251,11 @@ static int array_map_update_elem(struct + return -EEXIST; + + if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) +- memcpy(this_cpu_ptr(array->pptrs[index & array->index_mask]), ++ memcpy(this_cpu_ptr(array->pptrs[index & array->map.index_mask]), + value, map->value_size); + else + memcpy(array->value + +- array->elem_size * (index & array->index_mask), ++ array->elem_size * (index & array->map.index_mask), + value, map->value_size); + return 0; + } +@@ -289,7 +289,7 @@ int bpf_percpu_array_update(struct bpf_m + */ + size = round_up(map->value_size, 8); + rcu_read_lock(); +- pptr = array->pptrs[index & array->index_mask]; ++ pptr = array->pptrs[index & array->map.index_mask]; + for_each_possible_cpu(cpu) { + bpf_long_memcpy(per_cpu_ptr(pptr, cpu), value + off, size); + off += size; +@@ -651,7 +651,7 @@ static u32 array_of_map_gen_lookup(struc + *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); + if (map->unpriv_array) { + *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 6); +- *insn++ = BPF_ALU32_IMM(BPF_AND, ret, array->index_mask); ++ *insn++ = BPF_ALU32_IMM(BPF_AND, ret, array->map.index_mask); + } else { + *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5); + } +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -4344,9 +4344,7 @@ static int fixup_bpf_calls(struct bpf_ve + insn_buf[0] = BPF_JMP_IMM(BPF_JGE, BPF_REG_3, + map_ptr->max_entries, 2); + insn_buf[1] = BPF_ALU32_IMM(BPF_AND, BPF_REG_3, +- container_of(map_ptr, +- struct bpf_array, +- map)->index_mask); ++ map_ptr->index_mask); + insn_buf[2] = *insn; + cnt = 3; + new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); diff --git a/debian/patches/series b/debian/patches/series index 8e4bcf339..6b7526171 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -81,7 +81,6 @@ bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch bugfix/all/i40e-i40evf-organize-and-re-number-feature-flags.patch bugfix/all/i40e-fix-flags-declaration.patch bugfix/all/xen-time-do-not-decrease-steal-time-after-live-migra.patch -bugfix/all/e1000e-fix-e1000_check_for_copper_link_ich8lan-return-value.patch bugfix/all/libsas-Disable-asynchronous-aborts-for-SATA-devices.patch bugfix/all/drm-nouveau-disp-gf119-add-missing-drive-vfunc-ptr.patch debian/revert-objtool-fix-config_stack_validation-y-warning.patch @@ -126,13 +125,6 @@ bugfix/all/netfilter-xt_osf-add-missing-permission-checks.patch bugfix/all/media-dvb-usb-v2-lmedm04-Improve-logic-checking-of-w.patch bugfix/all/media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_.patch bugfix/all/media-hdpvr-fix-an-error-handling-path-in-hdpvr_prob.patch -bugfix/all/kvm-fix-stack-out-of-bounds-read-in-write_mmio.patch -bugfix/all/bluetooth-prevent-stack-info-leak-from-the-efs-element.patch -bugfix/all/bpf-encapsulate-verifier-log-state-into-a-structure.patch -bugfix/all/bpf-move-global-verifier-log-into-verifier-environme.patch -bugfix/all/bpf-fix-integer-overflows.patch -bugfix/all/RDS-Heap-OOB-write-in-rds_message_alloc_sgs.patch -bugfix/all/RDS-null-pointer-dereference-in-rds_atomic_free_op.patch bugfix/all/loop-fix-concurrent-lo_open-lo_release.patch # Fix exported symbol versions @@ -164,3 +156,4 @@ features/arm/dwmac-sun8i/0008-ARM-dts-sunxi-h3-h5-represent-the-mdio-switch-used features/arm64/tegra210-smp/0001-arm64-tegra-Add-CPU-and-PSCI-nodes-for-NVIDIA-Tegra2.patch # ABI maintenance +debian/bpf-avoid-abi-change-in-4.14.14.patch