All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM32: Support mremap() for sigpage/vDSO
@ 2017-04-14 10:10 ` Dmitry Safonov
  0 siblings, 0 replies; 4+ messages in thread
From: Dmitry Safonov @ 2017-04-14 10:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: 0x7f454c46, Dmitry Safonov, linux-arm-kernel, Russell King,
	Will Deacon, Andy Lutomirski, Thomas Gleixner, Cyrill Gorcunov,
	Pavel Emelyanov, Christopher Covington

CRIU restores application mappings on the same place where they
were before Checkpoint. That means, that we need to move vDSO
and sigpage during restore on exactly the same place where
they were before C/R.

Make mremap() code update mm->context.{sigpage,vdso} pointers
during VMA move. Sigpage is used for landing after handling
a signal - if the pointer is not updated during moving, the
application might crash on any signal after mremap().

vDSO pointer on ARM32 is used only for setting auxv at this moment,
update it during mremap() in case of future usage.

Without those updates, current work of CRIU on ARM32 is not reliable.
Historically, we error Checkpointing if we find vDSO page on ARM32
and suggest user to disable CONFIG_VDSO.
But that's not correct - it goes from x86 where signal processing
is ended in vDSO blob. For arm32 it's sigpage, which is not disabled
with `CONFIG_VDSO=n'.

Looks like C/R was working by luck - because userspace on ARM32 at
this moment always sets SA_RESTORER (and sigpage is not used in
that case).

Cc: linux-arm-kernel@lists.infradead.org
Cc: Russell King <linux@armlinux.org.uk>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@virtuozzo.com>
Cc: Christopher Covington <cov@codeaurora.org>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
 arch/arm/kernel/process.c |  8 ++++++++
 arch/arm/kernel/vdso.c    | 18 ++++++++++++++++++
 arch/x86/entry/vdso/vma.c |  3 ---
 mm/mmap.c                 |  4 ++++
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 939e8b58c59d..1e6039cac68d 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -404,9 +404,17 @@ static unsigned long sigpage_addr(const struct mm_struct *mm,
 static struct page *signal_page;
 extern struct page *get_signal_page(void);
 
+static int sigpage_mremap(const struct vm_special_mapping *sm,
+		struct vm_area_struct *new_vma)
+{
+	current->mm->context.sigpage = new_vma->vm_start;
+	return 0;
+}
+
 static const struct vm_special_mapping sigpage_mapping = {
 	.name = "[sigpage]",
 	.pages = &signal_page,
+	.mremap = sigpage_mremap,
 };
 
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index 53cf86cf2d1a..27777d26aeac 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -54,8 +54,26 @@ static const struct vm_special_mapping vdso_data_mapping = {
 	.pages = &vdso_data_page,
 };
 
+static int vdso_mremap(const struct vm_special_mapping *sm,
+		struct vm_area_struct *new_vma)
+{
+	unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
+	unsigned long vdso_size;
+
+	/* without VVAR page */
+	vdso_size = (vdso_total_pages - 1) << PAGE_SHIFT;
+
+	if (vdso_size != new_size)
+		return -EINVAL;
+
+	current->mm->context.vdso = (void __user *)new_vma->vm_start;
+
+	return 0;
+}
+
 static struct vm_special_mapping vdso_text_mapping __ro_after_init = {
 	.name = "[vdso]",
+	.mremap = vdso_mremap,
 };
 
 struct elfinfo {
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 226ca70dc6bd..363730caa60e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -77,9 +77,6 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
 	if (image->size != new_size)
 		return -EINVAL;
 
-	if (WARN_ON_ONCE(current->mm != new_vma->vm_mm))
-		return -EFAULT;
-
 	vdso_fix_landing(image, new_vma);
 	current->mm->context.vdso = (void __user *)new_vma->vm_start;
 
diff --git a/mm/mmap.c b/mm/mmap.c
index bfbe8856d134..534aef99cfe9 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -3152,8 +3152,12 @@ static int special_mapping_mremap(struct vm_area_struct *new_vma)
 {
 	struct vm_special_mapping *sm = new_vma->vm_private_data;
 
+	if (WARN_ON_ONCE(current->mm != new_vma->vm_mm))
+		return -EFAULT;
+
 	if (sm->mremap)
 		return sm->mremap(sm, new_vma);
+
 	return 0;
 }
 
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] ARM32: Support mremap() for sigpage/vDSO
@ 2017-04-14 10:10 ` Dmitry Safonov
  0 siblings, 0 replies; 4+ messages in thread
From: Dmitry Safonov @ 2017-04-14 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

CRIU restores application mappings on the same place where they
were before Checkpoint. That means, that we need to move vDSO
and sigpage during restore on exactly the same place where
they were before C/R.

Make mremap() code update mm->context.{sigpage,vdso} pointers
during VMA move. Sigpage is used for landing after handling
a signal - if the pointer is not updated during moving, the
application might crash on any signal after mremap().

vDSO pointer on ARM32 is used only for setting auxv at this moment,
update it during mremap() in case of future usage.

Without those updates, current work of CRIU on ARM32 is not reliable.
Historically, we error Checkpointing if we find vDSO page on ARM32
and suggest user to disable CONFIG_VDSO.
But that's not correct - it goes from x86 where signal processing
is ended in vDSO blob. For arm32 it's sigpage, which is not disabled
with `CONFIG_VDSO=n'.

Looks like C/R was working by luck - because userspace on ARM32 at
this moment always sets SA_RESTORER (and sigpage is not used in
that case).

Cc: linux-arm-kernel at lists.infradead.org
Cc: Russell King <linux@armlinux.org.uk>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@virtuozzo.com>
Cc: Christopher Covington <cov@codeaurora.org>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
 arch/arm/kernel/process.c |  8 ++++++++
 arch/arm/kernel/vdso.c    | 18 ++++++++++++++++++
 arch/x86/entry/vdso/vma.c |  3 ---
 mm/mmap.c                 |  4 ++++
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 939e8b58c59d..1e6039cac68d 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -404,9 +404,17 @@ static unsigned long sigpage_addr(const struct mm_struct *mm,
 static struct page *signal_page;
 extern struct page *get_signal_page(void);
 
+static int sigpage_mremap(const struct vm_special_mapping *sm,
+		struct vm_area_struct *new_vma)
+{
+	current->mm->context.sigpage = new_vma->vm_start;
+	return 0;
+}
+
 static const struct vm_special_mapping sigpage_mapping = {
 	.name = "[sigpage]",
 	.pages = &signal_page,
+	.mremap = sigpage_mremap,
 };
 
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index 53cf86cf2d1a..27777d26aeac 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -54,8 +54,26 @@ static const struct vm_special_mapping vdso_data_mapping = {
 	.pages = &vdso_data_page,
 };
 
+static int vdso_mremap(const struct vm_special_mapping *sm,
+		struct vm_area_struct *new_vma)
+{
+	unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
+	unsigned long vdso_size;
+
+	/* without VVAR page */
+	vdso_size = (vdso_total_pages - 1) << PAGE_SHIFT;
+
+	if (vdso_size != new_size)
+		return -EINVAL;
+
+	current->mm->context.vdso = (void __user *)new_vma->vm_start;
+
+	return 0;
+}
+
 static struct vm_special_mapping vdso_text_mapping __ro_after_init = {
 	.name = "[vdso]",
+	.mremap = vdso_mremap,
 };
 
 struct elfinfo {
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 226ca70dc6bd..363730caa60e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -77,9 +77,6 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
 	if (image->size != new_size)
 		return -EINVAL;
 
-	if (WARN_ON_ONCE(current->mm != new_vma->vm_mm))
-		return -EFAULT;
-
 	vdso_fix_landing(image, new_vma);
 	current->mm->context.vdso = (void __user *)new_vma->vm_start;
 
diff --git a/mm/mmap.c b/mm/mmap.c
index bfbe8856d134..534aef99cfe9 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -3152,8 +3152,12 @@ static int special_mapping_mremap(struct vm_area_struct *new_vma)
 {
 	struct vm_special_mapping *sm = new_vma->vm_private_data;
 
+	if (WARN_ON_ONCE(current->mm != new_vma->vm_mm))
+		return -EFAULT;
+
 	if (sm->mremap)
 		return sm->mremap(sm, new_vma);
+
 	return 0;
 }
 
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] ARM32: Support mremap() for sigpage/vDSO
  2017-04-14 10:10 ` Dmitry Safonov
@ 2017-04-14 13:20   ` kbuild test robot
  -1 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2017-04-14 13:20 UTC (permalink / raw)
  To: Dmitry Safonov
  Cc: kbuild-all, linux-kernel, 0x7f454c46, Dmitry Safonov,
	linux-arm-kernel, Russell King, Will Deacon, Andy Lutomirski,
	Thomas Gleixner, Cyrill Gorcunov, Pavel Emelyanov,
	Christopher Covington

[-- Attachment #1: Type: text/plain, Size: 1909 bytes --]

Hi Dmitry,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.11-rc6 next-20170413]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Safonov/ARM32-Support-mremap-for-sigpage-vDSO/20170414-190018
config: arm-sunxi_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All warnings (new ones prefixed by >>):

   arch/arm/kernel/vdso.c: In function 'vdso_mremap':
>> arch/arm/kernel/vdso.c:69:28: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
     current->mm->context.vdso = (void __user *)new_vma->vm_start;
                               ^

vim +69 arch/arm/kernel/vdso.c

    53		.name = "[vvar]",
    54		.pages = &vdso_data_page,
    55	};
    56	
    57	static int vdso_mremap(const struct vm_special_mapping *sm,
    58			struct vm_area_struct *new_vma)
    59	{
    60		unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
    61		unsigned long vdso_size;
    62	
    63		/* without VVAR page */
    64		vdso_size = (vdso_total_pages - 1) << PAGE_SHIFT;
    65	
    66		if (vdso_size != new_size)
    67			return -EINVAL;
    68	
  > 69		current->mm->context.vdso = (void __user *)new_vma->vm_start;
    70	
    71		return 0;
    72	}
    73	
    74	static struct vm_special_mapping vdso_text_mapping __ro_after_init = {
    75		.name = "[vdso]",
    76		.mremap = vdso_mremap,
    77	};

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 20767 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] ARM32: Support mremap() for sigpage/vDSO
@ 2017-04-14 13:20   ` kbuild test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2017-04-14 13:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dmitry,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.11-rc6 next-20170413]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Safonov/ARM32-Support-mremap-for-sigpage-vDSO/20170414-190018
config: arm-sunxi_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All warnings (new ones prefixed by >>):

   arch/arm/kernel/vdso.c: In function 'vdso_mremap':
>> arch/arm/kernel/vdso.c:69:28: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
     current->mm->context.vdso = (void __user *)new_vma->vm_start;
                               ^

vim +69 arch/arm/kernel/vdso.c

    53		.name = "[vvar]",
    54		.pages = &vdso_data_page,
    55	};
    56	
    57	static int vdso_mremap(const struct vm_special_mapping *sm,
    58			struct vm_area_struct *new_vma)
    59	{
    60		unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
    61		unsigned long vdso_size;
    62	
    63		/* without VVAR page */
    64		vdso_size = (vdso_total_pages - 1) << PAGE_SHIFT;
    65	
    66		if (vdso_size != new_size)
    67			return -EINVAL;
    68	
  > 69		current->mm->context.vdso = (void __user *)new_vma->vm_start;
    70	
    71		return 0;
    72	}
    73	
    74	static struct vm_special_mapping vdso_text_mapping __ro_after_init = {
    75		.name = "[vdso]",
    76		.mremap = vdso_mremap,
    77	};

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 20767 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170414/e61d08a5/attachment-0001.gz>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-04-14 13:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-14 10:10 [PATCH] ARM32: Support mremap() for sigpage/vDSO Dmitry Safonov
2017-04-14 10:10 ` Dmitry Safonov
2017-04-14 13:20 ` kbuild test robot
2017-04-14 13:20   ` kbuild test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.