Re: regression: lk 4.8 + !CONFIG_SHMEM + shmat() = oops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 30, 2016 at 01:52:11PM -0400, Tony Battersby wrote:
> The following commit is causing shmat() to oops when CONFIG_SHMEM is
> not set:
> 
> c01d5b300774 ("shmem: get_unmapped_area align huge page")
> 
> Here is the oops:
> 
> BUG: unable to handle kernel NULL pointer dereference at           (null)

Sorry, for delay. This should fix the issue:

>From 9f8cc79361fc874f9926b476cc674b2604a35701 Mon Sep 17 00:00:00 2001
From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx>
Date: Wed, 7 Sep 2016 13:57:20 +0300
Subject: [PATCH] ipc/shm: fix crash if CONFIG_SHMEM is not set

Commit c01d5b300774 makes use of shm_get_unmapped_area() in
shm_file_operations() unconditional to CONFIG_MMU.

As Tony Battersby pointed this can lead NULL-pointer dereference on
machine with CONFIG_MMU=y and CONFIG_SHMEM=n. In this case ipc/shm is
backed by ramfs which doesn't provide f_op->get_unmapped_area for
configurations with MMU.

The solution is to check whether the backing file has the f_op, before
using it and use current->mm->get_unmapped_area as fallback.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx>
Reported-by: Tony Battersby <tonyb@xxxxxxxxxxxxxxx>
Fixes: c01d5b300774 ("shmem: get_unmapped_area align huge page")
---
 ipc/shm.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/ipc/shm.c b/ipc/shm.c
index dbac8860c721..54e256bd40cb 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -467,9 +467,15 @@ static unsigned long shm_get_unmapped_area(struct file *file,
 	unsigned long addr, unsigned long len, unsigned long pgoff,
 	unsigned long flags)
 {
+	unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
+			unsigned long, unsigned long);
 	struct shm_file_data *sfd = shm_file_data(file);
-	return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
-						pgoff, flags);
+
+	if (sfd->file->f_op->get_unmapped_area)
+		get_area = sfd->file->f_op->get_unmapped_area;
+	else
+		get_area = current->mm->get_unmapped_area;
+	return get_area(sfd->file, addr, len, pgoff, flags);
 }
 
 static const struct file_operations shm_file_operations = {
-- 
 Kirill A. Shutemov

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxx.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]