1 /* Test if /proc/{self,$PID}/auxv is correctly simulated and that the aux
2    vector contains plausible values. */
3 
4 #include <errno.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/auxv.h>
9 #include <sys/fcntl.h>
10 
check_file(const char * path,auxv_t * auxv)11 static int check_file(const char *path, auxv_t *auxv)
12 {
13    auxv_t rauxv;
14    int res = 1;
15    FILE *fi;
16 
17    if (!(fi = fopen(path, "r"))) {
18       perror("fopen");
19       return 1;
20    }
21    while (1) {
22       if (fread(&rauxv, sizeof(rauxv), 1, fi) != 1) {
23          if (ferror(fi)) {
24             perror("fread");
25             goto out;
26          }
27          fprintf(stderr, "unexpected EOF\n");
28          goto out;
29       }
30       if (memcmp(auxv, &rauxv, sizeof(rauxv))) {
31          fprintf(stderr, "incorrect auxv in %s\n", path);
32          fprintf(stderr, "expected: type=%d, val=%ld\n", auxv->a_type,
33                  auxv->a_un.a_val);
34          fprintf(stderr, "got: type=%d, val=%ld\n", rauxv.a_type,
35                  rauxv.a_un.a_val);
36          goto out;
37       }
38 
39       if (auxv->a_type == AT_NULL)
40          break;
41 
42       auxv++;
43    }
44 
45    res = 0;
46 
47 out:
48    fclose(fi);
49    return res;
50 }
51 
main(int argc,char * argv[],char * envp[])52 int main(int argc, char *argv[], char *envp[])
53 {
54    auxv_t *auxv;
55    char buf[128];
56 
57    /* Find aux vector. */
58    while (*envp)
59       envp++;
60    auxv = (auxv_t*)(envp + 1);
61 
62    /* /proc/self/auxv check */
63    if (check_file("/proc/self/auxv", auxv))
64       return 1;
65 
66    /* /proc/$PID/auxv check */
67    snprintf(buf, sizeof(buf), "/proc/%ld/auxv", (long)getpid());
68    if (check_file(buf, auxv))
69       return 1;
70 
71    /* AT_SUN_EXECNAME check */
72    while (auxv->a_type != AT_NULL) {
73       if (auxv->a_type == AT_SUN_EXECNAME) {
74          const char *execname = auxv->a_un.a_ptr;
75          if (!execname) {
76             fprintf(stderr, "AT_SUN_EXECNAME is null\n");
77             return 1;
78          }
79          if (access(execname, R_OK | X_OK)) {
80             fprintf(stderr, "AT_SUN_EXECNAME (%s) is invalid: %s\n",
81                     execname, strerror(errno));
82             return 1;
83          }
84          break;
85       }
86       auxv++;
87    }
88 
89    return 0;
90 }
91 
92