/* Test if /proc/{self,$PID}/auxv is correctly simulated and that the aux vector contains plausible values. */ #include <errno.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/auxv.h> #include <sys/fcntl.h> static int check_file(const char *path, auxv_t *auxv) { auxv_t rauxv; int res = 1; FILE *fi; if (!(fi = fopen(path, "r"))) { perror("fopen"); return 1; } while (1) { if (fread(&rauxv, sizeof(rauxv), 1, fi) != 1) { if (ferror(fi)) { perror("fread"); goto out; } fprintf(stderr, "unexpected EOF\n"); goto out; } if (memcmp(auxv, &rauxv, sizeof(rauxv))) { fprintf(stderr, "incorrect auxv in %s\n", path); fprintf(stderr, "expected: type=%d, val=%ld\n", auxv->a_type, auxv->a_un.a_val); fprintf(stderr, "got: type=%d, val=%ld\n", rauxv.a_type, rauxv.a_un.a_val); goto out; } if (auxv->a_type == AT_NULL) break; auxv++; } res = 0; out: fclose(fi); return res; } int main(int argc, char *argv[], char *envp[]) { auxv_t *auxv; char buf[128]; /* Find aux vector. */ while (*envp) envp++; auxv = (auxv_t*)(envp + 1); /* /proc/self/auxv check */ if (check_file("/proc/self/auxv", auxv)) return 1; /* /proc/$PID/auxv check */ snprintf(buf, sizeof(buf), "/proc/%ld/auxv", (long)getpid()); if (check_file(buf, auxv)) return 1; /* AT_SUN_EXECNAME check */ while (auxv->a_type != AT_NULL) { if (auxv->a_type == AT_SUN_EXECNAME) { const char *execname = auxv->a_un.a_ptr; if (!execname) { fprintf(stderr, "AT_SUN_EXECNAME is null\n"); return 1; } if (access(execname, R_OK | X_OK)) { fprintf(stderr, "AT_SUN_EXECNAME (%s) is invalid: %s\n", execname, strerror(errno)); return 1; } break; } auxv++; } return 0; }