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
11static 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
47out:
48   fclose(fi);
49   return res;
50}
51
52int 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