From: Andrey Ryabinin <aryabi...@virtuozzo.com>

On the write to ve.os_release file patch the linux_version_code
in the .note section of vdso.

https://jira.sw.ru/browse/PSBM-121668
Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>

(cherry-picked from vz8 commit 9c63f77b5556 ("ve: patch linux_version_code
in vdso"))

Signed-off-by: Nikita Yushchenko <nikita.yushche...@virtuozzo.com>
---
 arch/x86/entry/vdso/vdso-note.S   | 2 ++
 arch/x86/entry/vdso/vdso2c.c      | 1 +
 arch/x86/entry/vdso/vdso32/note.S | 2 ++
 arch/x86/include/asm/vdso.h       | 1 +
 kernel/ve/ve.c                    | 7 +++++++
 5 files changed, 13 insertions(+)

diff --git a/arch/x86/entry/vdso/vdso-note.S b/arch/x86/entry/vdso/vdso-note.S
index 79423170118f..80f2888c3ecd 100644
--- a/arch/x86/entry/vdso/vdso-note.S
+++ b/arch/x86/entry/vdso/vdso-note.S
@@ -8,7 +8,9 @@
 #include <linux/version.h>
 #include <linux/elfnote.h>
 
+       .globl linux_version_code
 ELFNOTE_START(Linux, 0, "a")
+linux_version_code:
        .long LINUX_VERSION_CODE
 ELFNOTE_END
 
diff --git a/arch/x86/entry/vdso/vdso2c.c b/arch/x86/entry/vdso/vdso2c.c
index edfe9780f6d1..4e03e1835e98 100644
--- a/arch/x86/entry/vdso/vdso2c.c
+++ b/arch/x86/entry/vdso/vdso2c.c
@@ -101,6 +101,7 @@ struct vdso_sym required_syms[] = {
        {"__kernel_sigreturn", true},
        {"__kernel_rt_sigreturn", true},
        {"int80_landing_pad", true},
+       {"linux_version_code", true},
        {"vdso32_rt_sigreturn_landing_pad", true},
        {"vdso32_sigreturn_landing_pad", true},
 };
diff --git a/arch/x86/entry/vdso/vdso32/note.S 
b/arch/x86/entry/vdso/vdso32/note.S
index 2cbd39939dc6..58be060ed258 100644
--- a/arch/x86/entry/vdso/vdso32/note.S
+++ b/arch/x86/entry/vdso/vdso32/note.S
@@ -11,7 +11,9 @@
 /* Ideally this would use UTS_NAME, but using a quoted string here
    doesn't work. Remember to change this when changing the
    kernel's name. */
+       .globl linux_version_code
 ELFNOTE_START(Linux, 0, "a")
+linux_version_code:
        .long LINUX_VERSION_CODE
 ELFNOTE_END
 
diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h
index 98aa103eb4ab..3cb944456f1e 100644
--- a/arch/x86/include/asm/vdso.h
+++ b/arch/x86/include/asm/vdso.h
@@ -29,6 +29,7 @@ struct vdso_image {
        long sym___kernel_rt_sigreturn;
        long sym___kernel_vsyscall;
        long sym_int80_landing_pad;
+       long sym_linux_version_code;
        long sym_vdso32_sigreturn_landing_pad;
        long sym_vdso32_rt_sigreturn_landing_pad;
 };
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 0dabbb544898..55ceb93bf9e2 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -986,6 +986,7 @@ static ssize_t ve_os_release_write(struct kernfs_open_file 
*of, char *buf,
 {
        struct cgroup_subsys_state *css = of_css(of);
        struct ve_struct *ve = css_to_ve(css);
+       int n1, n2, n3, new_version;
        char *release;
        int ret = 0;
 
@@ -996,6 +997,12 @@ static ssize_t ve_os_release_write(struct kernfs_open_file 
*of, char *buf,
                goto up_opsem;
        }
 
+       if (sscanf(buf, "%d.%d.%d", &n1, &n2, &n3) == 3) {
+               new_version = ((n1 << 16) + (n2 << 8)) + n3;
+               *((int *)(ve->vdso_64->data + 
ve->vdso_64->sym_linux_version_code)) = new_version;
+               *((int *)(ve->vdso_32->data + 
ve->vdso_32->sym_linux_version_code)) = new_version;
+       }
+
        down_write(&uts_sem);
        release = ve->ve_ns->uts_ns->name.release;
        strncpy(release, buf, __NEW_UTS_LEN);
-- 
2.30.2

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to