/* Verifies that %.*s is safe in practice for printing out counted strings by positioning a counted string at the end of a mapped region. Checked on Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.96-2 x86_64 and Linux 5.4.0-70-generic #78-Ubuntu SMP. $ ./countedprintf hello, world $ ./countedprintf -l Segmentation fault */ #include #include #include #include #include #include #include #include #include enum { pagesize = 4096 }; int main(int argc, char **argv) { char *m = mmap(NULL, 2ul * pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (!m) err(errno, "mmap"); // At first I tried just mapping a single page, but for some reason, // I was getting a three-page mapping instead: // 7ffff7ff8000-7ffff7ffb000 rw-p 00000000 00:00 0 // So I’m resorting to explicit unmapping, which does work. if (0 != munmap(m + pagesize, pagesize)) err(errno, "munmap"); char *hello = "hello, world"; char *dest = m + pagesize - strlen(hello); memcpy(dest, hello, strlen(hello)); // This strcpy also segfaults, because the terminating '\0' goes // into the guard page: // strcpy(dest, hello); printf("%.*s\n", (int)strlen(hello) + (argc > 1 ? 1 : 0), dest); return 0; }