Current kernel (v3.10) or older has a problem in cow optimization. Cow
optimization is that if we find a page which has only 1 reference from
this process, we use it directly for private write. This applied to
anonymous page and a page from page cache until now. This cause a problem
for a page cache case, because we can remap this file by another process,
and it can see corrupt data. To detect this problem, add this test case.

This problem will be fixed on v3.12 kernel.

Signed-off-by: Joonsoo Kim <iamjoonsoo....@lge.com>

diff --git a/tests/Makefile b/tests/Makefile
index 231e3b0..7d28c7d 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -12,7 +12,8 @@ LIB_TESTS = gethugepagesize test_root find_path unlinked_fd 
misalign \
        madvise_reserve fadvise_reserve readahead_reserve \
        shm-perms \
        mremap-expand-slice-collision \
-       mremap-fixed-normal-near-huge mremap-fixed-huge-near-normal
+       mremap-fixed-normal-near-huge mremap-fixed-huge-near-normal \
+       corrupt-by-cow-opt
 LIB_TESTS_64 =
 LIB_TESTS_64_STATIC = straddle_4GB huge_at_4GB_normal_below \
        huge_below_4GB_normal_above
diff --git a/tests/corrupt-by-cow-opt.c b/tests/corrupt-by-cow-opt.c
new file mode 100644
index 0000000..1c46ecc
--- /dev/null
+++ b/tests/corrupt-by-cow-opt.c
@@ -0,0 +1,78 @@
+/*
+ * libhugetlbfs - Easy use of Linux hugepages
+ * Copyright (C) 2013 Joonsoo Kim, LG Electronics.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <hugetlbfs.h>
+#include "hugetests.h"
+
+#define P "corrupt-by-cow-opt"
+#define DESC \
+       "* Test sanity of cow optimization on page cache. If a page        *\n"\
+       "* in page cache has only 1 ref count, it is mapped for a private  *\n"\
+       "* mapping directly and is overwritten freely, so next time we     *\n"\
+       "* access the page, we can see corrupt data.                       *\n"\
+
+int main(int argc, char *argv[])
+{
+       long hpage_size;
+       int fd;
+       char *p;
+       char c;
+
+       test_init(argc, argv);
+
+       hpage_size = check_hugepagesize();
+
+       check_free_huge_pages(2);
+
+       fd = hugetlbfs_unlinked_fd();
+       if (fd < 0)
+               FAIL("hugetlbfs_unlinked_fd()");
+
+       p = mmap(NULL, hpage_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       if (p == MAP_FAILED)
+               FAIL("mmap() 1: %s", strerror(errno));
+
+       *p = 's';
+       verbose_printf("Write %c to %p via shared mapping\n", *p, p);
+       munmap(p, hpage_size);
+
+       p = mmap(NULL, hpage_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+       if (p == MAP_FAILED)
+               FAIL("mmap() 2: %s", strerror(errno));
+
+       *p = 'p';
+       verbose_printf("Write %c to %p via private mapping\n", *p, p);
+       munmap(p, hpage_size);
+
+       p = mmap(NULL, hpage_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       if (p == MAP_FAILED)
+               FAIL("mmap() 3: %s", strerror(errno));
+
+       c = *p;
+       verbose_printf("Read %c from %p via shared mapping\n", *p, p);
+       munmap(p, hpage_size);
+
+       if (c != 's')
+               FAIL("data corrupt");
+
+       PASS();
+}
diff --git a/tests/run_tests.py b/tests/run_tests.py
index c060699..9570547 100755
--- a/tests/run_tests.py
+++ b/tests/run_tests.py
@@ -536,6 +536,7 @@ def functional_tests():
     do_test("brk_near_huge")
     do_test("task-size-overrun")
     do_test_with_rlimit(resource.RLIMIT_STACK, -1, "stack_grow_into_huge")
+    do_test("corrupt-by-cow-opt")
 
     if dangerous == 1:
         do_test("readahead_reserve")
-- 
1.7.9.5


------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent 
caught up. So what steps can you take to put your SQL databases under 
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Libhugetlbfs-devel mailing list
Libhugetlbfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to