#include #include #include #include #include #include #include #include #define BUF_SIZE 4096 char buf[BUF_SIZE]; char namebuf[256]; struct linux_dirent { uint32_t inode; uint16_t rec_len; uint8_t name_len; uint8_t file_type; char* name; }; void test_failed(const char* reason) { printf("[FAILED] %s\n", reason); fflush(stdout); exit(1); } void test_ok(const char* name) { printf("[OK] %s\n", name); fflush(stdout); } int main(int argc, char** argv) { int fd, nread; struct linux_dirent* d; int bpos; setenv("PATH", "/bin:/usr/bin:/test_bin", 1); fd = open("/test_bin", O_RDONLY | O_DIRECTORY); if (fd < 0) { test_failed("can't open /test_bin\n"); } for (;;) { nread = getdents(fd, buf, BUF_SIZE); if (nread < 0) { test_failed("can't read dir"); } if (nread == 0) break; for (bpos = 0; bpos < nread;) { d = (struct linux_dirent*)(buf + bpos); if (((char*)&d->name)[0] != '.') { int pid = fork(); if (pid) { int out = 0; waitpid(pid, &out, 0); if (out != 0) { test_failed((char*)&d->name); } else { test_ok((char*)&d->name); } } else { setuid(10); setgid(10); sprintf(namebuf, "/test_bin/%s", (char*)&d->name); execlp(namebuf, namebuf, NULL); exit(0); } } bpos += d->rec_len; } } printf("[ALL TESTS PASSED]\n\n"); fflush(stdout); return 0; }