From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 0F01B1382C5 for ; Fri, 5 Jan 2018 15:02:34 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 721E3E0880; Fri, 5 Jan 2018 15:02:33 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 464E5E0880 for ; Fri, 5 Jan 2018 15:02:33 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 290A2335C2C for ; Fri, 5 Jan 2018 15:02:32 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id A5706198 for ; Fri, 5 Jan 2018 15:02:30 +0000 (UTC) From: "Alice Ferrazzi" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Alice Ferrazzi" Message-ID: <1515164540.c72b8737f3a452232dbb3c1eb0fdc621313cff3c.alicef@gentoo> Subject: [gentoo-commits] proj/linux-patches:4.14 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1011_linux-4.14.12.patch X-VCS-Directories: / X-VCS-Committer: alicef X-VCS-Committer-Name: Alice Ferrazzi X-VCS-Revision: c72b8737f3a452232dbb3c1eb0fdc621313cff3c X-VCS-Branch: 4.14 Date: Fri, 5 Jan 2018 15:02:30 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: a59e27b5-bf11-4681-8131-94da726f5c73 X-Archives-Hash: 44525d2a9a4cf01f7b4082301361180c commit: c72b8737f3a452232dbb3c1eb0fdc621313cff3c Author: Alice Ferrazzi gentoo org> AuthorDate: Fri Jan 5 15:02:20 2018 +0000 Commit: Alice Ferrazzi gentoo org> CommitDate: Fri Jan 5 15:02:20 2018 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c72b8737 linux kernel 4.14.12 0000_README | 4 + 1011_linux-4.14.12.patch | 514 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 518 insertions(+) diff --git a/0000_README b/0000_README index c07cc2b..a10ea98 100644 --- a/0000_README +++ b/0000_README @@ -87,6 +87,10 @@ Patch: 1010_linux-4.14.11.patch From: http://www.kernel.org Desc: Linux 4.14.11 +Patch: 1011_linux-4.14.12.patch +From: http://www.kernel.org +Desc: Linux 4.14.12 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1011_linux-4.14.12.patch b/1011_linux-4.14.12.patch new file mode 100644 index 0000000..8f9d788 --- /dev/null +++ b/1011_linux-4.14.12.patch @@ -0,0 +1,514 @@ +diff --git a/Makefile b/Makefile +index 655887067dc7..20f7d4de0f1c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 14 +-SUBLEVEL = 11 ++SUBLEVEL = 12 + EXTRAVERSION = + NAME = Petit Gorille + +diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S +index 40f17009ec20..98d5358e4041 100644 +--- a/arch/x86/entry/entry_64_compat.S ++++ b/arch/x86/entry/entry_64_compat.S +@@ -190,8 +190,13 @@ ENTRY(entry_SYSCALL_compat) + /* Interrupts are off on entry. */ + swapgs + +- /* Stash user ESP and switch to the kernel stack. */ ++ /* Stash user ESP */ + movl %esp, %r8d ++ ++ /* Use %rsp as scratch reg. User ESP is stashed in r8 */ ++ SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp ++ ++ /* Switch to the kernel stack */ + movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp + + /* Construct struct pt_regs on stack */ +@@ -219,12 +224,6 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe) + pushq $0 /* pt_regs->r14 = 0 */ + pushq $0 /* pt_regs->r15 = 0 */ + +- /* +- * We just saved %rdi so it is safe to clobber. It is not +- * preserved during the C calls inside TRACE_IRQS_OFF anyway. +- */ +- SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi +- + /* + * User mode is traced as though IRQs are on, and SYSENTER + * turned them off. +diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h +index c1688c2d0a12..1f86e1b0a5cd 100644 +--- a/arch/x86/include/asm/unwind.h ++++ b/arch/x86/include/asm/unwind.h +@@ -56,18 +56,27 @@ void unwind_start(struct unwind_state *state, struct task_struct *task, + + #if defined(CONFIG_UNWINDER_ORC) || defined(CONFIG_UNWINDER_FRAME_POINTER) + /* +- * WARNING: The entire pt_regs may not be safe to dereference. In some cases, +- * only the iret frame registers are accessible. Use with caution! ++ * If 'partial' returns true, only the iret frame registers are valid. + */ +-static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) ++static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state, ++ bool *partial) + { + if (unwind_done(state)) + return NULL; + ++ if (partial) { ++#ifdef CONFIG_UNWINDER_ORC ++ *partial = !state->full_regs; ++#else ++ *partial = false; ++#endif ++ } ++ + return state->regs; + } + #else +-static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) ++static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state, ++ bool *partial) + { + return NULL; + } +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index f2a94dfb434e..b1be494ab4e8 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -899,8 +899,8 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) + + setup_force_cpu_cap(X86_FEATURE_ALWAYS); + +- /* Assume for now that ALL x86 CPUs are insecure */ +- setup_force_cpu_bug(X86_BUG_CPU_INSECURE); ++ if (c->x86_vendor != X86_VENDOR_AMD) ++ setup_force_cpu_bug(X86_BUG_CPU_INSECURE); + + fpu__init_system(c); + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 5fa110699ed2..afbecff161d1 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -76,12 +76,23 @@ void show_iret_regs(struct pt_regs *regs) + regs->sp, regs->flags); + } + +-static void show_regs_safe(struct stack_info *info, struct pt_regs *regs) ++static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, ++ bool partial) + { +- if (on_stack(info, regs, sizeof(*regs))) ++ /* ++ * These on_stack() checks aren't strictly necessary: the unwind code ++ * has already validated the 'regs' pointer. The checks are done for ++ * ordering reasons: if the registers are on the next stack, we don't ++ * want to print them out yet. Otherwise they'll be shown as part of ++ * the wrong stack. Later, when show_trace_log_lvl() switches to the ++ * next stack, this function will be called again with the same regs so ++ * they can be printed in the right context. ++ */ ++ if (!partial && on_stack(info, regs, sizeof(*regs))) { + __show_regs(regs, 0); +- else if (on_stack(info, (void *)regs + IRET_FRAME_OFFSET, +- IRET_FRAME_SIZE)) { ++ ++ } else if (partial && on_stack(info, (void *)regs + IRET_FRAME_OFFSET, ++ IRET_FRAME_SIZE)) { + /* + * When an interrupt or exception occurs in entry code, the + * full pt_regs might not have been saved yet. In that case +@@ -98,11 +109,13 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + struct stack_info stack_info = {0}; + unsigned long visit_mask = 0; + int graph_idx = 0; ++ bool partial; + + printk("%sCall Trace:\n", log_lvl); + + unwind_start(&state, task, regs, stack); + stack = stack ? : get_stack_pointer(task, regs); ++ regs = unwind_get_entry_regs(&state, &partial); + + /* + * Iterate through the stacks, starting with the current stack pointer. +@@ -120,7 +133,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + * - hardirq stack + * - entry stack + */ +- for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { ++ for ( ; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { + const char *stack_name; + + if (get_stack_info(stack, task, &stack_info, &visit_mask)) { +@@ -140,7 +153,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + printk("%s <%s>\n", log_lvl, stack_name); + + if (regs) +- show_regs_safe(&stack_info, regs); ++ show_regs_if_on_stack(&stack_info, regs, partial); + + /* + * Scan the stack, printing any text addresses we find. At the +@@ -164,7 +177,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + + /* + * Don't print regs->ip again if it was already printed +- * by show_regs_safe() below. ++ * by show_regs_if_on_stack(). + */ + if (regs && stack == ®s->ip) + goto next; +@@ -199,9 +212,9 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unwind_next_frame(&state); + + /* if the frame has entry regs, print them */ +- regs = unwind_get_entry_regs(&state); ++ regs = unwind_get_entry_regs(&state, &partial); + if (regs) +- show_regs_safe(&stack_info, regs); ++ show_regs_if_on_stack(&stack_info, regs, partial); + } + + if (stack_name) +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index 517415978409..3cb2486c47e4 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -47,7 +47,7 @@ + * section. Since TSS's are completely CPU-local, we want them + * on exact cacheline boundaries, to eliminate cacheline ping-pong. + */ +-__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss_rw) = { ++__visible DEFINE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw) = { + .x86_tss = { + /* + * .sp0 is only used when entering ring 0 from a lower +diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c +index 8dabd7bf1673..60244bfaf88f 100644 +--- a/arch/x86/kernel/stacktrace.c ++++ b/arch/x86/kernel/stacktrace.c +@@ -98,7 +98,7 @@ static int __save_stack_trace_reliable(struct stack_trace *trace, + for (unwind_start(&state, task, NULL, NULL); !unwind_done(&state); + unwind_next_frame(&state)) { + +- regs = unwind_get_entry_regs(&state); ++ regs = unwind_get_entry_regs(&state, NULL); + if (regs) { + /* + * Kernel mode registers on the stack indicate an +diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c +index bce8aea65606..2da28ba97508 100644 +--- a/arch/x86/mm/pti.c ++++ b/arch/x86/mm/pti.c +@@ -367,7 +367,8 @@ static void __init pti_setup_espfix64(void) + static void __init pti_clone_entry_text(void) + { + pti_clone_pmds((unsigned long) __entry_text_start, +- (unsigned long) __irqentry_text_end, _PAGE_RW); ++ (unsigned long) __irqentry_text_end, ++ _PAGE_RW | _PAGE_GLOBAL); + } + + /* +diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c +index f4c070ea8384..c90fba3ed861 100644 +--- a/drivers/rtc/rtc-m41t80.c ++++ b/drivers/rtc/rtc-m41t80.c +@@ -154,6 +154,8 @@ struct m41t80_data { + struct rtc_device *rtc; + #ifdef CONFIG_COMMON_CLK + struct clk_hw sqw; ++ unsigned long freq; ++ unsigned int sqwe; + #endif + }; + +@@ -443,43 +445,40 @@ static SIMPLE_DEV_PM_OPS(m41t80_pm, m41t80_suspend, m41t80_resume); + #ifdef CONFIG_COMMON_CLK + #define sqw_to_m41t80_data(_hw) container_of(_hw, struct m41t80_data, sqw) + +-static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) ++static unsigned long m41t80_decode_freq(int setting) ++{ ++ return (setting == 0) ? 0 : (setting == 1) ? M41T80_SQW_MAX_FREQ : ++ M41T80_SQW_MAX_FREQ >> setting; ++} ++ ++static unsigned long m41t80_get_freq(struct m41t80_data *m41t80) + { +- struct m41t80_data *m41t80 = sqw_to_m41t80_data(hw); + struct i2c_client *client = m41t80->client; + int reg_sqw = (m41t80->features & M41T80_FEATURE_SQ_ALT) ? + M41T80_REG_WDAY : M41T80_REG_SQW; + int ret = i2c_smbus_read_byte_data(client, reg_sqw); +- unsigned long val = M41T80_SQW_MAX_FREQ; + + if (ret < 0) + return 0; ++ return m41t80_decode_freq(ret >> 4); ++} + +- ret >>= 4; +- if (ret == 0) +- val = 0; +- else if (ret > 1) +- val = val / (1 << ret); +- +- return val; ++static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ return sqw_to_m41t80_data(hw)->freq; + } + + static long m41t80_sqw_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) + { +- int i, freq = M41T80_SQW_MAX_FREQ; +- +- if (freq <= rate) +- return freq; +- +- for (i = 2; i <= ilog2(M41T80_SQW_MAX_FREQ); i++) { +- freq /= 1 << i; +- if (freq <= rate) +- return freq; +- } +- +- return 0; ++ if (rate >= M41T80_SQW_MAX_FREQ) ++ return M41T80_SQW_MAX_FREQ; ++ if (rate >= M41T80_SQW_MAX_FREQ / 4) ++ return M41T80_SQW_MAX_FREQ / 4; ++ if (!rate) ++ return 0; ++ return 1 << ilog2(rate); + } + + static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, +@@ -491,17 +490,12 @@ static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, + M41T80_REG_WDAY : M41T80_REG_SQW; + int reg, ret, val = 0; + +- if (rate) { +- if (!is_power_of_2(rate)) +- return -EINVAL; +- val = ilog2(rate); +- if (val == ilog2(M41T80_SQW_MAX_FREQ)) +- val = 1; +- else if (val < (ilog2(M41T80_SQW_MAX_FREQ) - 1)) +- val = ilog2(M41T80_SQW_MAX_FREQ) - val; +- else +- return -EINVAL; +- } ++ if (rate >= M41T80_SQW_MAX_FREQ) ++ val = 1; ++ else if (rate >= M41T80_SQW_MAX_FREQ / 4) ++ val = 2; ++ else if (rate) ++ val = 15 - ilog2(rate); + + reg = i2c_smbus_read_byte_data(client, reg_sqw); + if (reg < 0) +@@ -510,10 +504,9 @@ static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, + reg = (reg & 0x0f) | (val << 4); + + ret = i2c_smbus_write_byte_data(client, reg_sqw, reg); +- if (ret < 0) +- return ret; +- +- return -EINVAL; ++ if (!ret) ++ m41t80->freq = m41t80_decode_freq(val); ++ return ret; + } + + static int m41t80_sqw_control(struct clk_hw *hw, bool enable) +@@ -530,7 +523,10 @@ static int m41t80_sqw_control(struct clk_hw *hw, bool enable) + else + ret &= ~M41T80_ALMON_SQWE; + +- return i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, ret); ++ ret = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, ret); ++ if (!ret) ++ m41t80->sqwe = enable; ++ return ret; + } + + static int m41t80_sqw_prepare(struct clk_hw *hw) +@@ -545,14 +541,7 @@ static void m41t80_sqw_unprepare(struct clk_hw *hw) + + static int m41t80_sqw_is_prepared(struct clk_hw *hw) + { +- struct m41t80_data *m41t80 = sqw_to_m41t80_data(hw); +- struct i2c_client *client = m41t80->client; +- int ret = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); +- +- if (ret < 0) +- return ret; +- +- return !!(ret & M41T80_ALMON_SQWE); ++ return sqw_to_m41t80_data(hw)->sqwe; + } + + static const struct clk_ops m41t80_sqw_ops = { +@@ -587,6 +576,7 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80) + init.parent_names = NULL; + init.num_parents = 0; + m41t80->sqw.init = &init; ++ m41t80->freq = m41t80_get_freq(m41t80); + + /* optional override of the clockname */ + of_property_read_string(node, "clock-output-names", &init.name); +diff --git a/fs/exec.c b/fs/exec.c +index 3e14ba25f678..acec119fcc31 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1350,9 +1350,14 @@ void setup_new_exec(struct linux_binprm * bprm) + + current->sas_ss_sp = current->sas_ss_size = 0; + +- /* Figure out dumpability. */ ++ /* ++ * Figure out dumpability. Note that this checking only of current ++ * is wrong, but userspace depends on it. This should be testing ++ * bprm->secureexec instead. ++ */ + if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP || +- bprm->secureexec) ++ !(uid_eq(current_euid(), current_uid()) && ++ gid_eq(current_egid(), current_gid()))) + set_dumpable(current->mm, suid_dumpable); + else + set_dumpable(current->mm, SUID_DUMP_USER); +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index 2a6093840e7e..6bc16bb61b55 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -1362,29 +1362,36 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl, + struct net *net = xp_net(policy); + int nx; + int i, error; ++ xfrm_address_t *daddr = xfrm_flowi_daddr(fl, family); ++ xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family); + xfrm_address_t tmp; + + for (nx = 0, i = 0; i < policy->xfrm_nr; i++) { + struct xfrm_state *x; +- xfrm_address_t *local; +- xfrm_address_t *remote; ++ xfrm_address_t *remote = daddr; ++ xfrm_address_t *local = saddr; + struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i]; + +- remote = &tmpl->id.daddr; +- local = &tmpl->saddr; +- if (xfrm_addr_any(local, tmpl->encap_family)) { +- error = xfrm_get_saddr(net, fl->flowi_oif, +- &tmp, remote, +- tmpl->encap_family, 0); +- if (error) +- goto fail; +- local = &tmp; ++ if (tmpl->mode == XFRM_MODE_TUNNEL || ++ tmpl->mode == XFRM_MODE_BEET) { ++ remote = &tmpl->id.daddr; ++ local = &tmpl->saddr; ++ if (xfrm_addr_any(local, tmpl->encap_family)) { ++ error = xfrm_get_saddr(net, fl->flowi_oif, ++ &tmp, remote, ++ tmpl->encap_family, 0); ++ if (error) ++ goto fail; ++ local = &tmp; ++ } + } + + x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family); + + if (x && x->km.state == XFRM_STATE_VALID) { + xfrm[nx++] = x; ++ daddr = remote; ++ saddr = local; + continue; + } + if (x) { +diff --git a/security/commoncap.c b/security/commoncap.c +index fc46f5b85251..7b01431d1e19 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -348,21 +348,18 @@ static __u32 sansflags(__u32 m) + return m & ~VFS_CAP_FLAGS_EFFECTIVE; + } + +-static bool is_v2header(size_t size, __le32 magic) ++static bool is_v2header(size_t size, const struct vfs_cap_data *cap) + { +- __u32 m = le32_to_cpu(magic); + if (size != XATTR_CAPS_SZ_2) + return false; +- return sansflags(m) == VFS_CAP_REVISION_2; ++ return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_2; + } + +-static bool is_v3header(size_t size, __le32 magic) ++static bool is_v3header(size_t size, const struct vfs_cap_data *cap) + { +- __u32 m = le32_to_cpu(magic); +- + if (size != XATTR_CAPS_SZ_3) + return false; +- return sansflags(m) == VFS_CAP_REVISION_3; ++ return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_3; + } + + /* +@@ -405,7 +402,7 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, + + fs_ns = inode->i_sb->s_user_ns; + cap = (struct vfs_cap_data *) tmpbuf; +- if (is_v2header((size_t) ret, cap->magic_etc)) { ++ if (is_v2header((size_t) ret, cap)) { + /* If this is sizeof(vfs_cap_data) then we're ok with the + * on-disk value, so return that. */ + if (alloc) +@@ -413,7 +410,7 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, + else + kfree(tmpbuf); + return ret; +- } else if (!is_v3header((size_t) ret, cap->magic_etc)) { ++ } else if (!is_v3header((size_t) ret, cap)) { + kfree(tmpbuf); + return -EINVAL; + } +@@ -470,9 +467,9 @@ static kuid_t rootid_from_xattr(const void *value, size_t size, + return make_kuid(task_ns, rootid); + } + +-static bool validheader(size_t size, __le32 magic) ++static bool validheader(size_t size, const struct vfs_cap_data *cap) + { +- return is_v2header(size, magic) || is_v3header(size, magic); ++ return is_v2header(size, cap) || is_v3header(size, cap); + } + + /* +@@ -495,7 +492,7 @@ int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) + + if (!*ivalue) + return -EINVAL; +- if (!validheader(size, cap->magic_etc)) ++ if (!validheader(size, cap)) + return -EINVAL; + if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP)) + return -EPERM;