]> granicus.if.org Git - strace/commitdiff
Fixed decoding of mincore syscall's last argument
authorDmitry V. Levin <ldv@altlinux.org>
Fri, 29 Jan 2016 01:51:54 +0000 (01:51 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Fri, 29 Jan 2016 02:39:40 +0000 (02:39 +0000)
* mem.c (SYS_FUNC(mincore)): Print only those bytes of the vector
that were written by the kernel.
* NEWS: Mention this fix.
* tests/mincore.c: New file.
* tests/mincore.test: New test.
* tests/Makefile.am (check_PROGRAMS): Add mincore.
(TESTS): Add mincore.test.
* tests/.gitignore: Add mincore.

NEWS
mem.c
tests/.gitignore
tests/Makefile.am
tests/mincore.c [new file with mode: 0644]
tests/mincore.test [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index a7520d661bda7802d15f3adedea6cd2cae419ad7..b9ed032b982d6412da52b3c321cfa765066a433e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Noteworthy changes in release ?.?? (????-??-??)
     (addresses Debian bug #485979 and Fedora bug #1298294).
   * Fixed decoding and dumping of readv syscall in case of short read.
   * Fixed dumping of recvmsg and recvmmsg syscalls in case of short read.
+  * Fixed decoding of mincore syscall's last argument.
 
 Noteworthy changes in release 4.11 (2015-12-21)
 ===============================================
diff --git a/mem.c b/mem.c
index 37c7daba88dfc3b7ef322a25bc6d3e5291bcc4bd..28b49c9758dd29c2c705c565a80a0a59e01e0856 100644 (file)
--- a/mem.c
+++ b/mem.c
@@ -264,15 +264,18 @@ SYS_FUNC(mincore)
                printaddr(tcp->u_arg[0]);
                tprintf(", %lu, ", tcp->u_arg[1]);
        } else {
-               unsigned long i, len;
-               char *vec = NULL;
+               const unsigned long page_size = get_pagesize();
+               const unsigned long page_mask = page_size - 1;
+               unsigned long len = tcp->u_arg[1];
+               unsigned char *vec = NULL;
 
-               len = tcp->u_arg[1];
+               len = len / page_size + (len & page_mask ? 1 : 0);
                if (syserror(tcp) || !verbose(tcp) ||
                    !tcp->u_arg[2] || !(vec = malloc(len)) ||
                    umoven(tcp, tcp->u_arg[2], len, vec) < 0)
                        printaddr(tcp->u_arg[2]);
                else {
+                       unsigned long i;
                        tprints("[");
                        for (i = 0; i < len; i++) {
                                if (abbrev(tcp) && i >= max_strlen) {
index 207a9b2e0a5bfc8544cc6b3e8a630c622530f975..10214d35ffcfd58bb408e041a0fc52936c7d8541 100644 (file)
@@ -50,6 +50,7 @@ lstat
 lstat64
 membarrier
 memfd_create
+mincore
 mlock2
 mmap
 mmap64
index f6345836bdfa517c64d38985750d7d2976199047..e31be34ef06f0e29fb76f29f368972a870e86d11 100644 (file)
@@ -96,6 +96,7 @@ check_PROGRAMS = \
        lstat64 \
        membarrier \
        memfd_create \
+       mincore \
        mlock2 \
        mmap \
        mmap64 \
@@ -235,6 +236,7 @@ TESTS = \
        lstat64.test \
        membarrier.test \
        memfd_create.test \
+       mincore.test \
        mlock2.test \
        mmap.test \
        mmap64.test \
diff --git a/tests/mincore.c b/tests/mincore.c
new file mode 100644 (file)
index 0000000..d9cbbd4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <stdio.h>
+#include <sys/mman.h>
+
+#define DEFAULT_STRLEN 32
+
+static void
+test_mincore(const unsigned int pages)
+{
+       const size_t size = pages * get_page_size();
+       char *addr = tail_alloc(size);
+       unsigned char *vec = tail_alloc(pages);
+       unsigned int i;
+
+       if (mincore(addr, size, vec))
+               perror_msg_and_skip("mincore");
+       printf("mincore(%p, %zu, [", addr, size);
+       for (i = 0; i < pages; ++i) {
+               if (i >= DEFAULT_STRLEN) {
+                       printf("...");
+                       break;
+               }
+               printf("%u", vec[i] & 1);
+       }
+       puts("]) = 0");
+}
+
+int main(void)
+{
+       test_mincore(1);
+       test_mincore(2);
+       test_mincore(DEFAULT_STRLEN + 1);
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
diff --git a/tests/mincore.test b/tests/mincore.test
new file mode 100755 (executable)
index 0000000..9a6a686
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Check mincore syscall decoding.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+OUT="$LOG.out"
+run_strace -a22 -emincore $args > "$OUT"
+match_diff "$LOG" "$OUT"
+rm -f "$OUT"