2013-10-14 09:36:11

by Hatayama, Daisuke

[permalink] [raw]
Subject: [PATCH 0/3] procfs, vmcore: fix regression of mmap on /proc/vmcore since v3.12-rc1

This patch set fixes regression of mmap on /proc/vmcore since
v3.12-rc1. The primary one is the 2nd patch. The 1st patch is another
bug I found during investiation and it affects mmap on /proc/vmcore
even if only 2nd patch is applied, so fix it together in this patch
set. The last patch is just for cleaning up of target function in both
1st and 2nd patches.

---

HATAYAMA Daisuke (3):
procfs: fix unintended truncation of returned mapped address
procfs: Call default get_unmapped_area on MMU-present architectures
procfs: clean up proc_reg_get_unmapped_area for 80-column limit


fs/proc/inode.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)

--
Thanks.
HATAYAMA, Daisuke


2013-10-14 09:36:16

by Hatayama, Daisuke

[permalink] [raw]
Subject: [PATCH 1/3] procfs: fix unintended truncation of returned mapped address

Currently, proc_reg_get_unmapped_area truncates upper 32-bit of the
mapped virtual address returned from get_unmapped_area method in
pde->proc_fops due to the variable rv of signed integer on
x86_64. This is too small to have vitual address of unsigned long on
x86_64 since on x86_64, signed integer is of 4 bytes while unsigned
long is of 8 bytes. To fix this issue, use unsigned long instead.

Signed-off-by: HATAYAMA Daisuke <[email protected]>
---
fs/proc/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 9f8ef9b..6c501c4 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -288,7 +288,7 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
static unsigned long proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct proc_dir_entry *pde = PDE(file_inode(file));
- int rv = -EIO;
+ unsigned long rv = -EIO;
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
if (use_pde(pde)) {
get_unmapped_area = pde->proc_fops->get_unmapped_area;

2013-10-14 09:36:27

by Hatayama, Daisuke

[permalink] [raw]
Subject: [PATCH 3/3] procfs: clean up proc_reg_get_unmapped_area for 80-column limit

Clean up proc_reg_get_unmapped_area due to its 80-column limit
violation.

Signed-off-by: HATAYAMA Daisuke <[email protected]>
---
fs/proc/inode.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 8eaa1ba..28955d4 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -285,19 +285,23 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
return rv;
}

-static unsigned long proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+static unsigned long
+proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags)
{
struct proc_dir_entry *pde = PDE(file_inode(file));
unsigned long rv = -EIO;
- unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long) = NULL;
+ unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
+ unsigned long, unsigned long) = NULL;
if (use_pde(pde)) {
#ifdef CONFIG_MMU
- get_unmapped_area = current->mm->get_unmapped_area;
+ get_area = current->mm->get_unmapped_area;
#endif
if (pde->proc_fops->get_unmapped_area)
- get_unmapped_area = pde->proc_fops->get_unmapped_area;
- if (get_unmapped_area)
- rv = get_unmapped_area(file, orig_addr, len, pgoff, flags);
+ get_area = pde->proc_fops->get_unmapped_area;
+ if (get_area)
+ rv = get_area(file, orig_addr, len, pgoff, flags);
unuse_pde(pde);
}
return rv;

2013-10-14 09:36:22

by Hatayama, Daisuke

[permalink] [raw]
Subject: [PATCH 2/3] procfs: Call default get_unmapped_area on MMU-present architectures

commit c4fe24485729fc2cbff324c111e67a1cc2f9adea added
proc_reg_get_unmapped_area in proc_reg_file_ops and
proc_reg_file_ops_no_compat, by which now mmap always returns EIO if
get_unmapped_area method is not defiend for the target procfs file,
which causes regression of mmap on /proc/vmcore.

To address this issue, like get_unmapped_area(), call default
current->mm->get_unmapped_area on MMU-present architectures if
pde->proc_fops->get_unmapped_area, i.e. the one in actual file
operation in the procfs file, is not defined.

Reported-by: Michael Holzheu <[email protected]>
Signed-off-by: HATAYAMA Daisuke <[email protected]>
Cc: Alexey Dobriyan <[email protected]>
---
fs/proc/inode.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 6c501c4..8eaa1ba 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -289,9 +289,13 @@ static unsigned long proc_reg_get_unmapped_area(struct file *file, unsigned long
{
struct proc_dir_entry *pde = PDE(file_inode(file));
unsigned long rv = -EIO;
- unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long) = NULL;
if (use_pde(pde)) {
- get_unmapped_area = pde->proc_fops->get_unmapped_area;
+#ifdef CONFIG_MMU
+ get_unmapped_area = current->mm->get_unmapped_area;
+#endif
+ if (pde->proc_fops->get_unmapped_area)
+ get_unmapped_area = pde->proc_fops->get_unmapped_area;
if (get_unmapped_area)
rv = get_unmapped_area(file, orig_addr, len, pgoff, flags);
unuse_pde(pde);

2013-10-15 11:31:45

by Michael Holzheu

[permalink] [raw]
Subject: Re: [PATCH 0/3] procfs, vmcore: fix regression of mmap on /proc/vmcore since v3.12-rc1

Hello Hatayama,

We successfully tested your patches on s390, mmap for /proc/vmcore
seems to work again.

Thanks!

Michael

On Mon, 14 Oct 2013 18:36:06 +0900
HATAYAMA Daisuke <[email protected]> wrote:

> This patch set fixes regression of mmap on /proc/vmcore since
> v3.12-rc1. The primary one is the 2nd patch. The 1st patch is another
> bug I found during investiation and it affects mmap on /proc/vmcore
> even if only 2nd patch is applied, so fix it together in this patch
> set. The last patch is just for cleaning up of target function in both
> 1st and 2nd patches.
>
> ---
>
> HATAYAMA Daisuke (3):
> procfs: fix unintended truncation of returned mapped address
> procfs: Call default get_unmapped_area on MMU-present architectures
> procfs: clean up proc_reg_get_unmapped_area for 80-column limit
>
>
> fs/proc/inode.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>