[Devel] [VZ10 02/21] ve/vma: Fix NULL dereference when accessing ve->vdso_image_*
Vladimir Riabchun
vladimir.riabchun at virtuozzo.com
Thu May 7 22:10:14 MSK 2026
With !CONFIG_VE get_exec_env() returns NULL, all accesses to
vdso fields are done without config check.
Add helpers that return pointers to vdso_image_{32,64} objects
when !CONFIG_VE.
https://virtuozzo.atlassian.net/browse/VSTOR-130116
Feature: !CONFIG_VE build
Signed-off-by: Vladimir Riabchun <vladimir.riabchun at virtuozzo.com>
---
arch/x86/entry/vdso/vma.c | 6 +++---
arch/x86/kernel/process_64.c | 4 ++--
include/linux/ve.h | 20 ++++++++++++++++++++
3 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 6427a3a10d15..04b5134362eb 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -80,7 +80,7 @@ static void vdso_fix_landing(const struct vdso_image *image,
struct vm_area_struct *new_vma)
{
#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
- if (in_ia32_syscall() && image == get_exec_env()->vdso_32) {
+ if (in_ia32_syscall() && image == ve_get_vdso_32(get_exec_env())) {
struct pt_regs *regs = current_pt_regs();
unsigned long vdso_land = image->sym_int80_landing_pad;
unsigned long old_land_addr = vdso_land +
@@ -310,7 +310,7 @@ static int load_vdso32(void)
if (vdso32_enabled != 1) /* Other values all mean "disabled" */
return 0;
- return map_vdso(get_exec_env()->vdso_32, 0);
+ return map_vdso(ve_get_vdso_32(get_exec_env()), 0);
}
#endif
@@ -320,7 +320,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (!vdso64_enabled)
return 0;
- return map_vdso(get_exec_env()->vdso_64, 0);
+ return map_vdso(ve_get_vdso_64(get_exec_env()), 0);
}
#ifdef CONFIG_COMPAT
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 18a02b62cc37..3761380d68da 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -945,10 +945,10 @@ long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2)
# endif
# if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
case ARCH_MAP_VDSO_32:
- return prctl_map_vdso(get_exec_env()->vdso_32, arg2);
+ return prctl_map_vdso(ve_get_vdso_32(get_exec_env()), arg2);
# endif
case ARCH_MAP_VDSO_64:
- return prctl_map_vdso(get_exec_env()->vdso_64, arg2);
+ return prctl_map_vdso(ve_get_vdso_64(get_exec_env()), arg2);
#endif
#ifdef CONFIG_ADDRESS_MASKING
case ARCH_GET_UNTAG_MASK:
diff --git a/include/linux/ve.h b/include/linux/ve.h
index 224acf012821..c64860664b62 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -279,6 +279,16 @@ extern bool is_ve_init_net(const struct net *net);
void ve_setup_task(struct task_struct *p, struct ve_struct *ve);
+static inline struct vdso_image *ve_get_vdso_32(struct ve_struct *ve)
+{
+ return ve->vdso_32;
+}
+
+static inline struct vdso_image *ve_get_vdso_64(struct ve_struct *ve)
+{
+ return ve->vdso_64;
+}
+
#else /* CONFIG_VE */
#include <linux/init_task.h>
#define get_ve(ve) ((void)(ve), NULL)
@@ -336,6 +346,16 @@ static inline int vz_security_protocol_check(struct net *net, int protocol) { re
static inline void ve_setup_task(struct task_struct *p, struct ve_struct *ve) { }
+static inline struct vdso_image *ve_get_vdso_32(struct ve_struct *ve)
+{
+ return (struct vdso_image *)&vdso_image_32;
+}
+
+static inline struct vdso_image *ve_get_vdso_64(struct ve_struct *ve)
+{
+ return (struct vdso_image *)&vdso_image_64;
+}
+
#endif /* CONFIG_VE */
struct seq_file;
--
2.43.0
More information about the Devel
mailing list