From: Rusty Russell <rusty@rustcorp.com.au>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: lkml - Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: get_user_pages vs mmap MAP_FIXED bug
Date: Sun, 06 May 2007 17:01:16 +1000 [thread overview]
Message-ID: <1178434876.12284.175.camel@localhost.localdomain> (raw)
This bug is in 2.6.21-rc7-mm2, but not 2.6.21. Haven't tested
2.6.21-mm1 yet.
The following kernel module uses get_user_pages() to look at user
memory, and gets zeroed pages if they're not touched by userspace first.
The test case seems a little sensitive to change (eg. mapping at a
non-fixed address seems to work).
Usage:
(build kernel)
gcc -o examine_mmap examine_mmap.c
sudo insmod kernel/examiner.ko
sudo ./examine_mmap
examine_mmap: For 0x1000: kernel sees 0, I see 1179403647
sudo ./examine_mmap --touch
OK: Both saw 1179403647
Anyone?
Rusty.
diff -r 142e4ca8c069 examine_mmap.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examine_mmap.c Sun May 06 16:21:19 2007 +1000
@@ -0,0 +1,38 @@
+/* Make with gcc -o examine_mmap examine_mmap.c */
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int main(int argc, char *argv[])
+{
+ int *p;
+ char addrstr[80];
+ int res, fd;
+
+ /* Grab some file to mmap. */
+ fd = open("./vmlinux", O_RDONLY);
+ if (fd < 0)
+ err(1, "open");
+
+ /* Map one page of it at 4096 */
+ p = (void *)4096;
+ if (mmap(p, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, fd, 0) != p)
+ err(1, "mmap");
+
+ /* This makes it work. */
+ if (argc > 1 && strcmp(argv[1], "--touch") == 0)
+ printf("Before: %p == %i\n", p, *p);
+
+ /* Find out what the kernel thinks it is with get_user_pages() */
+ fd = open("/proc/examiner", O_RDWR);
+ sprintf(addrstr, "%p", p);
+ res = write(fd, addrstr, strlen(addrstr));
+ if (res != *p)
+ errx(1, "For %p: kernel sees %i, I see %i\n", p, res, *p);
+ printf("OK: Both saw %i\n", res);
+ return 0;
+}
diff -r 142e4ca8c069 kernel/Makefile
--- a/kernel/Makefile Sat May 05 22:01:39 2007 +1000
+++ b/kernel/Makefile Sun May 06 10:38:27 2007 +1000
@@ -53,6 +53,7 @@ obj-$(CONFIG_UTS_NS) += utsname.o
obj-$(CONFIG_UTS_NS) += utsname.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
+obj-m += examiner.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff -r 142e4ca8c069 kernel/examiner.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/examiner.c Sun May 06 16:15:24 2007 +1000
@@ -0,0 +1,45 @@
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/highmem.h>
+#include <asm/uaccess.h>
+
+ssize_t examiner_write(struct file *f, const char __user *u, size_t s, loff_t *o)
+{
+ char addrstr[20];
+ unsigned long addr, res = 0xBADFEED;
+ struct page *page;
+
+ copy_from_user(addrstr, u, sizeof(addrstr));
+ addr = simple_strtoul(addrstr, NULL, 0);
+
+ down_read(¤t->mm->mmap_sem);
+ if (get_user_pages(current, current->mm, addr,
+ 1, 0, 1, &page, NULL) == 1) {
+ int *p = kmap(page);
+ res = *p;
+ kunmap(page);
+ }
+ up_read(¤t->mm->mmap_sem);
+ return res;
+}
+
+static const struct file_operations examiner_fops = {
+ .write = examiner_write,
+};
+
+
+static int examiner(void)
+{
+ struct proc_dir_entry *p;
+
+ p = create_proc_entry("examiner", 0600, NULL);
+ p->proc_fops = &examiner_fops;
+ return 0;
+}
+
+static void unexaminer(void)
+{
+ remove_proc_entry("examiner", NULL);
+}
+module_init(examiner);
+module_exit(unexaminer);
next reply other threads:[~2007-05-06 7:01 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-06 7:01 Rusty Russell [this message]
2007-05-07 1:26 ` get_user_pages vs mmap MAP_FIXED bug Rusty Russell
2007-05-07 3:22 ` Andrew Morton
2007-05-08 7:41 ` Nick Piggin
2007-05-08 23:34 ` Rusty Russell
2007-05-09 0:08 ` Nick Piggin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1178434876.12284.175.camel@localhost.localdomain \
--to=rusty@rustcorp.com.au \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox