File: proc_auxv.c

package info (click to toggle)
valgrind 1%3A3.16.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 158,568 kB
  • sloc: ansic: 746,130; exp: 26,134; xml: 22,708; asm: 13,570; cpp: 7,691; makefile: 6,177; perl: 5,965; sh: 5,665; javascript: 929
file content (91 lines) | stat: -rw-r--r-- 2,064 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* 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;
}