* util.c (umovestr): Check the right address.
* tests/umovestr.c: New file.
* tests/umovestr2.c: Likewise.
* tests/umovestr.expected: Likewise.
* tests/umovestr.test: New test.
* tests/umovestr2.test: Likewise.
* tests/Makefile.am (check_PROGRAMS): Add umovestr and umovestr2.
(TESTS): Add umovestr.test and umovestr2.test.
(EXTRA_DIST): Add umovestr.expected.
* tests/.gitignore: Add umovestr and umovestr2.
Reported-by: Josef T. Burger <bolo@cs.wisc.edu>
uid16
uid32
uio
+umovestr
+umovestr2
unix-pair-send-recv
*.log
*.log.*
uid16 \
uid32 \
uio \
+ umovestr \
+ umovestr2 \
unix-pair-send-recv
mmap64_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
pipe.test \
pc.test \
sun_path.test \
+ umovestr.test \
+ umovestr2.test \
unix-yy.test \
uid.test \
uid16.test \
sun_path.expected \
uid.awk \
uio.expected \
+ umovestr.expected \
unix-yy-accept.awk \
unix-yy-connect.awk \
$(TESTS)
--- /dev/null
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int
+main(void)
+{
+ const size_t page_len = sysconf(_SC_PAGESIZE);
+ const size_t tail_len = 257;
+
+ if (tail_len >= page_len)
+ return 77;
+
+ void *p = mmap(NULL, page_len * 2, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (p == MAP_FAILED || mprotect(p + page_len, page_len, PROT_NONE))
+ return 77;
+
+ memset(p, 0, page_len);
+ char *addr = p + page_len - tail_len;
+ memset(addr, '/', tail_len - 1);
+ if (chdir(addr))
+ return 77;
+
+ return 0;
+}
--- /dev/null
+chdir("////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////") = 0
++++ exited with 0 +++
--- /dev/null
+#!/bin/sh
+
+# umovestr short read regression test
+
+. "${srcdir=.}/init.sh"
+
+run_prog
+run_strace -e chdir $args
+match_diff
+
+exit 0
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int
+main(void)
+{
+ const size_t page_len = sysconf(_SC_PAGESIZE);
+ const size_t work_len = page_len * 2;
+ const size_t tail_len = work_len - 1;
+
+ void *p = mmap(NULL, page_len * 3, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (p == MAP_FAILED || mprotect(p + work_len, page_len, PROT_NONE))
+ return 77;
+
+ memset(p, 0, work_len);
+ char *addr = p + work_len - tail_len;
+ memset(addr, '0', tail_len - 1);
+
+ char *argv[] = { NULL };
+ char *envp[] = { addr, NULL };
+ execve("", argv, envp);
+
+ printf("execve\\(\"\", \\[\\], \\[\"%0*u\"\\]\\) = -1 .*\n",
+ (int) tail_len - 1, 0);
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+
+# umovestr short read regression test
+
+. "${srcdir=.}/init.sh"
+
+OUT="$LOG.out"
+
+run_prog > /dev/null
+run_strace -veexecve -s262144 $args > "$OUT"
+match_grep "$LOG" "$OUT"
+
+rm -f "$OUT"
+
+exit 0
* in the existing (first) page.
* (I hope there aren't arches with pages < 4K)
*/
- end_in_page = ((addr + chunk_len) & 4095);
+ end_in_page = ((long) remote[0].iov_base + chunk_len) & 4095;
if (chunk_len > end_in_page) /* crosses to the next page */
chunk_len -= end_in_page;