]> granicus.if.org Git - strace/commitdiff
test: rewrite skodic.c demo
authorDmitry V. Levin <ldv@altlinux.org>
Sat, 18 Mar 2017 22:14:16 +0000 (22:14 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 19 Mar 2017 13:34:16 +0000 (13:34 +0000)
* test/skodic.c: Rewrite this demo to simplify its use.

test/skodic.c

index 4dcd955661062752409abf28b16adae00cf79633..39d916411901a45a0ee154638179e3f4c5a92fd2 100644 (file)
@@ -1,36 +1,64 @@
-/* This demonstrates races: kernel may actually open other file then
- * you read at strace output. Create /tmp/delme with 10K of zeros and
- * 666 mode, then run this under strace. If you see open successfull
- * open of /etc/shadow, you know you've seen a race.
+/*
+ * This demonstrates races: kernel may actually open other file
+ * than you read in the strace output.
+ * If you see a successfull open of /etc/shadow,
+ * you know you've seen a race.
+ *
+ * $ gcc -Wall -O0 skodic.c -o skodic
+ * $ timeout 0.1 ../strace -yeopen -o'|grep "shadow.*= [0-9]"' ./skodic
  */
 
+#ifndef _GNU_SOURCE
+# define  _GNU_SOURCE 1
+#endif
+
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 
-int main(int argc, char *argv[])
+int
+main(void)
 {
-       char *c;
-       int fd;
+       FILE *fp = tmpfile();
+       if (!fp)
+               error(1, errno, "tmpfile");
+
+       int fd = fileno(fp);
+       size_t size = sysconf(_SC_PAGESIZE);
 
-       fd = open("/tmp/delme", O_RDWR);
-       c = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-       *c = 0;
+       if (ftruncate(fd, size))
+               error(1, errno, "ftruncate");
 
-       if (fork()) {
-               while (1) {
-                       strcpy(c, "/etc/passwd");
-                       strcpy(c, "/etc/shadow");
+       char *p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       if (p == MAP_FAILED)
+               error(1, errno, "mmap");
+       fclose(fp);
+       fp = NULL;
+       fd = -1;
+
+       strcpy(p, "/etc/shadow");
+       if (open(p, 0) >= 0)
+               error(1, 0, p);
+
+       pid_t pid = fork();
+       if (pid < 0)
+               error(1, errno, "fork");
+
+       if (!pid) {
+               for (;;) {
+                       strcpy(p, "/etc/passwd");
+                       strcpy(p, "/etc/shadow");
                }
        } else {
-               while (1)
-                       if ((fd = open(c, 0)) != -1)
+               for (;;) {
+                       if ((fd = open(p, 0)) >= 0)
                                close(fd);
+               }
        }
 
        return 0;