/[path-sandbox]/trunk/libsandbox/wrapper-funcs/execve.c
Gentoo

Contents of /trunk/libsandbox/wrapper-funcs/execve.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 395 - (show annotations) (download) (as text)
Mon Nov 10 21:04:32 2008 UTC (10 years ago) by vapier
File MIME type: text/x-csrc
File size: 3511 byte(s)
detect static ELFs and warn when we try to execute them
1 /*
2 * execve() wrapper.
3 *
4 * Copyright 1999-2008 Gentoo Foundation
5 * Licensed under the GPL-2
6 *
7 * Partly Copyright (C) 1998-9 Pancrazio `Ezio' de Mauro <p@demauro.net>,
8 * as some of the InstallWatch code was used.
9 */
10
11 #define WRAPPER_ARGS const char *filename, char *const argv[], char *const envp[]
12 extern int EXTERN_NAME(WRAPPER_ARGS);
13 static int (*WRAPPER_TRUE_NAME)(WRAPPER_ARGS) = NULL;
14
15 /* See to see if this an ELF and if so, is it static which we can't wrap */
16 void check_exec(const char *filename)
17 {
18 int color = ((is_env_on(ENV_NOCOLOR)) ? 0 : 1);
19 int fd;
20 unsigned char *elf;
21 struct stat st;
22
23 fd = open(filename, O_RDONLY);
24 if (fd == -1)
25 return;
26 if (stat(filename, &st))
27 goto out_fd;
28 elf = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
29 if (elf == MAP_FAILED)
30 goto out_fd;
31
32 if (elf[EI_MAG0] != ELFMAG0 &&
33 elf[EI_MAG1] != ELFMAG1 &&
34 elf[EI_MAG2] != ELFMAG2 &&
35 elf[EI_MAG3] != ELFMAG3 &&
36 !(elf[EI_CLASS] != ELFCLASS32 ||
37 elf[EI_CLASS] != ELFCLASS64))
38 goto out_mmap;
39
40 #define PARSE_ELF(n) \
41 ({ \
42 Elf##n##_Ehdr *ehdr = (void *)elf; \
43 Elf##n##_Phdr *phdr = (void *)(elf + ehdr->e_phoff); \
44 uint16_t p; \
45 for (p = 0; p < ehdr->e_phnum; ++p) \
46 if (phdr[p].p_type == PT_INTERP) \
47 goto done; \
48 })
49 if (elf[EI_CLASS] == ELFCLASS32)
50 PARSE_ELF(32);
51 else
52 PARSE_ELF(64);
53 SB_EWARN(color, "QA: Static ELF", " %s\n", filename);
54 done:
55
56 out_mmap:
57 munmap(elf, st.st_size);
58 out_fd:
59 close(fd);
60 }
61
62 int WRAPPER_NAME(WRAPPER_ARGS)
63 {
64 char **my_env = NULL;
65 char *entry;
66 char *ld_preload = NULL;
67 char *old_ld_preload = NULL;
68 int old_errno = errno;
69 int result = -1;
70 int count;
71
72 if (!FUNCTION_SANDBOX_SAFE(STRING_NAME, filename))
73 return result;
74
75 check_exec(filename);
76
77 str_list_for_each_item(envp, entry, count) {
78 if (strstr(entry, LD_PRELOAD_EQ) != entry)
79 continue;
80
81 /* Check if we do not have to do anything */
82 if (NULL != strstr(entry, sandbox_lib)) {
83 /* Use the user's envp */
84 my_env = (char **)envp;
85 goto do_execve;
86 } else {
87 old_ld_preload = entry;
88 /* No need to continue, we have to modify LD_PRELOAD */
89 break;
90 }
91 }
92
93 /* Ok, we need to create our own envp, as we need to add LD_PRELOAD,
94 * and we should not touch the user's envp. First we add LD_PRELOAD,
95 * and just all the rest. */
96 count = strlen(LD_PRELOAD_EQ) + strlen(sandbox_lib) + 1;
97 if (NULL != old_ld_preload)
98 count += strlen(old_ld_preload) - strlen(LD_PRELOAD_EQ) + 1;
99 ld_preload = xmalloc(count * sizeof(char));
100 if (NULL == ld_preload)
101 goto error;
102 snprintf(ld_preload, count, "%s%s%s%s", LD_PRELOAD_EQ, sandbox_lib,
103 (old_ld_preload) ? " " : "",
104 (old_ld_preload) ? old_ld_preload + strlen(LD_PRELOAD_EQ) : "");
105 str_list_add_item(my_env, ld_preload, error);
106
107 str_list_for_each_item(envp, entry, count) {
108 if (strstr(entry, LD_PRELOAD_EQ) != entry) {
109 str_list_add_item(my_env, entry, error);
110 continue;
111 }
112 }
113
114 do_execve:
115 errno = old_errno;
116 check_dlsym(WRAPPER_TRUE_NAME, WRAPPER_SYMNAME,
117 WRAPPER_SYMVER);
118 result = WRAPPER_TRUE_NAME(filename, argv, my_env);
119
120 if ((NULL != my_env) && (my_env != envp))
121 /* We do not use str_list_free(), as we did not allocate the
122 * entries except for LD_PRELOAD. */
123 free(my_env);
124 if (NULL != ld_preload)
125 free(ld_preload);
126
127 return result;
128
129 error:
130 if ((NULL != my_env) && (my_env != envp))
131 /* We do not use str_list_free(), as we did not allocate the
132 * entries except for LD_PRELOAD. */
133 free(my_env);
134 if (NULL != ld_preload)
135 free(ld_preload);
136
137 return -1;
138 }

  ViewVC Help
Powered by ViewVC 1.1.20