/[path-sandbox]/trunk/src/sandbox.c
Gentoo

Diff of /trunk/src/sandbox.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 283 Revision 286
48 48
49static char log_domain[] = "sandbox"; 49static char log_domain[] = "sandbox";
50 50
51extern char **environ; 51extern char **environ;
52 52
53int sandbox_setup(struct sandbox_info_t *sandbox_info) 53int sandbox_setup(struct sandbox_info_t *sandbox_info, bool interactive)
54{ 54{
55 if (NULL != getenv(ENV_PORTAGE_TMPDIR)) { 55 if (NULL != getenv(ENV_PORTAGE_TMPDIR)) {
56 /* Portage handle setting SANDBOX_WRITE itself. */ 56 /* Portage handle setting SANDBOX_WRITE itself. */
57 sandbox_info->work_dir[0] = '\0'; 57 sandbox_info->work_dir[0] = '\0';
58 } else { 58 } else {
59 if (NULL == getcwd(sandbox_info->work_dir, SB_PATH_MAX)) { 59 if (NULL == getcwd(sandbox_info->work_dir, SB_PATH_MAX)) {
60 perror("sandbox: Failed to get current directory"); 60 perror("sandbox: Failed to get current directory");
61 return -1; 61 return -1;
62 } 62 }
63 if (interactive)
64 setenv(ENV_SANDBOX_WORKDIR, sandbox_info->work_dir, 1);
63 } 65 }
64 66
65 /* Do not resolve symlinks, etc .. libsandbox will handle that. */ 67 /* Do not resolve symlinks, etc .. libsandbox will handle that. */
66 if (!rc_is_dir(VAR_TMPDIR, TRUE)) { 68 if (!rc_is_dir(VAR_TMPDIR, TRUE)) {
67 perror("sandbox: Failed to get var_tmp_dir"); 69 perror("sandbox: Failed to get var_tmp_dir");
192 fprintf(stderr, 194 fprintf(stderr,
193 "sandbox: Signal already caught and busy still cleaning up!\n"); 195 "sandbox: Signal already caught and busy still cleaning up!\n");
194 } 196 }
195} 197}
196 198
197int get_sandbox_write_envvar(char *buf, struct sandbox_info_t *sandbox_info) 199char *sandbox_subst_env_vars(dyn_buf_t *env_data)
198{ 200{
199 int retval = 0; 201 dyn_buf_t *new_data = NULL;
200 202 char *tmp_ptr, *tmp_data = NULL;
201 /* bzero out entire buffer then append trailing 0 */ 203 char *var_start, *var_stop;
202 memset(buf, 0, SB_BUF_LEN);
203 204
204 /* these could go into make.globals later on */ 205 new_data = new_dyn_buf();
205 retval = snprintf(buf, SB_BUF_LEN, 206 if (NULL == new_data)
206 "%s:%s/.gconfd/lock:%s/.bash_history:%s:%s:%s:%s", 207 return NULL;
207 "/dev/zero:/dev/null:/dev/full:/dev/fd:/proc/self/fd:/dev/pts/:" 208
208 "/dev/vc/:/dev/pty:/dev/tty:/dev/tts:/dev/console:" 209 tmp_data = read_line_dyn_buf(env_data);
209 "/dev/shm:/dev/shm/ngpt:/var/log/scrollkeeper.log:" 210 if (NULL == tmp_data)
210 "/usr/tmp/conftest:/usr/lib/conftest:" 211 goto error;
211 "/usr/lib32/conftest:/usr/lib64/conftest:" 212 tmp_ptr = tmp_data;
212 "/usr/tmp/cf:/usr/lib/cf:/usr/lib32/cf:/usr/lib64/cf", 213
213 sandbox_info->home_dir, sandbox_info->home_dir, 214 while (NULL != (var_start = strchr(tmp_ptr, '$'))) {
214 sandbox_info->work_dir[0] != '\0' ? sandbox_info->work_dir 215 char *env = NULL;
215 : "", 216
216 sandbox_info->tmp_dir, sandbox_info->var_tmp_dir, 217 var_stop = strchr(var_start, '}');
217 "/tmp/:/var/tmp/"); 218
218 if (SB_BUF_LEN <= retval) { 219 /* We only support ${} style env var names, so just skip any
219 errno = EMSGSIZE; 220 * '$' that do not follow this syntax */
220 perror("sandbox: Failed to generate SANDBOX_WRITE"); 221 if (('{' != var_start[1]) || (NULL == var_stop)) {
222 tmp_ptr = var_start + 1;
223 continue;
224 }
225
226 /* Terminate part before env string so that we can copy it */
227 var_start[0] = '\0';
228 /* Move var_start past '${' */
229 var_start += 2;
230 /* Terminate the name of the env var */
231 var_stop[0] = '\0';
232
233 if (strlen(var_start) > 0)
234 env = getenv(var_start);
235 if (-1 == sprintf_dyn_buf(new_data, "%s%s",
236 tmp_ptr ? tmp_ptr : "",
237 env ? env : ""))
238 goto error;
239
240 /* Move tmp_ptr past the '}' of the env var */
241 tmp_ptr = var_stop + 1;
242 }
243
244 if (0 != strlen(tmp_ptr))
245 if (-1 == write_dyn_buf(new_data, tmp_ptr, strlen(tmp_ptr)))
246 goto error;
247
248 free(tmp_data);
249
250 tmp_data = read_line_dyn_buf(new_data);
251 if (NULL == tmp_data)
252 goto error;
253
254 free_dyn_buf(new_data);
255
256 return tmp_data;
257
258error:
259 if (NULL != new_data)
260 free_dyn_buf(new_data);
261 if (NULL != tmp_data)
262 free(tmp_data);
263
264 return NULL;
265}
266
267void sandbox_set_env_var(const char *env_var)
268{
269 char *config;
270
271 /* We check if the variable is set in the environment, and if not, we
272 * get it from sandbox.conf, and if they exist, we just add them to the
273 * environment if not already present. */
274 if (NULL == getenv(env_var)) {
275 config = rc_get_cnf_entry(SANDBOX_CONF_FILE, env_var, NULL);
276 if (NULL != config) {
277 setenv(ENV_SANDBOX_VERBOSE, config, 0);
278 free(config);
279 }
280 }
281}
282
283int sandbox_set_env_access_var(const char *access_var)
284{
285 dyn_buf_t *env_data = NULL;
286 int count = 0;
287 char *config = NULL;
288 char **confd_files = NULL;
289 bool use_confd = TRUE;
290
291 env_data = new_dyn_buf();
292 if (NULL == env_data)
221 return -1; 293 return -1;
294
295 /* Now get the defaults for the access variable from sandbox.conf.
296 * These do not get overridden via the environment. */
297 config = rc_get_cnf_entry(SANDBOX_CONF_FILE, access_var, ":");
298 if (NULL != config) {
299 if (-1 == write_dyn_buf(env_data, config, strlen(config)))
300 goto error;
301 free(config);
302 config = NULL;
303 }
304 /* Append whatever might be already set. If anything is set, we do
305 * not process the sandbox.d/ files for this variable. */
306 if (NULL != getenv(access_var)) {
307 use_confd = FALSE;
308 if (-1 == sprintf_dyn_buf(env_data, env_data->wr_index ? ":%s" : "%s",
309 getenv(access_var)))
310 goto error;
311 }
312
313 if (!use_confd)
314 goto done;
315
316 /* Now scan the files in sandbox.d/ if the access variable was not
317 * alreay set. */
318 confd_files = rc_ls_dir(SANDBOX_CONFD_DIR, FALSE, TRUE);
319 if (NULL != confd_files) {
320 while (NULL != confd_files[count]) {
321 config = rc_get_cnf_entry(confd_files[count], access_var, ":");
322 if (NULL != config) {
323 if (-1 == sprintf_dyn_buf(env_data,
324 env_data->wr_index ? ":%s" : "%s",
325 config))
326 goto error;
327 free(config);
328 config = NULL;
329 }
330 count++;
222 } 331 }
332
333 str_list_free(confd_files);
334 }
335
336done:
337 if (env_data->wr_index > 0) {
338 char *subst;
339
340 subst = sandbox_subst_env_vars(env_data);
341 if (NULL == subst)
342 goto error;
343
344 setenv(access_var, subst, 1);
345 free(subst);
346 }
347
348 free_dyn_buf(env_data);
223 349
224 return 0; 350 return 0;
225}
226 351
352error:
353 if (NULL != env_data)
354 free_dyn_buf(env_data);
355 if (NULL != config)
356 free(config);
357 if (NULL != confd_files)
358 str_list_free(confd_files);
359
360 return -1;
361}
362
227int get_sandbox_predict_envvar(char *buf, struct sandbox_info_t *sandbox_info) 363int sandbox_setup_env_config(struct sandbox_info_t *sandbox_info)
228{ 364{
229 int retval = 0; 365 sandbox_set_env_var(ENV_SANDBOX_VERBOSE);
230 /* bzero out entire buffer then append trailing 0 */ 366 sandbox_set_env_var(ENV_SANDBOX_DEBUG);
231 memset(buf, 0, SB_BUF_LEN); 367 sandbox_set_env_var(ENV_SANDBOX_BEEP);
368 sandbox_set_env_var(ENV_NOCOLOR);
232 369
233 /* these should go into make.globals later on */ 370 if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_DENY))
234 retval = snprintf(buf, SB_BUF_LEN, "%s/.:"
235 "/usr/lib/python2.0/:"
236 "/usr/lib/python2.1/:"
237 "/usr/lib/python2.2/:"
238 "/usr/lib/python2.3/:"
239 "/usr/lib/python2.4/:"
240 "/usr/lib/python2.5/:"
241 "/usr/lib/python3.0/:"
242 "/var/db/aliases.db:"
243 "/var/db/netgroup.db:"
244 "/var/db/netmasks.db:"
245 "/var/db/ethers.db:"
246 "/var/db/rpc.db:"
247 "/var/db/protocols.db:"
248 "/var/db/services.db:"
249 "/var/db/networks.db:"
250 "/var/db/hosts.db:"
251 "/var/db/group.db:"
252 "/var/db/passwd.db",
253 sandbox_info->home_dir);
254 if (SB_BUF_LEN <= retval) {
255 errno = EMSGSIZE;
256 perror("sandbox: Failed to generate SANDBOX_PREDICT");
257 return -1; 371 return -1;
258 } 372 if (NULL == getenv(ENV_SANDBOX_DENY))
373 setenv(ENV_SANDBOX_DENY, LD_PRELOAD_FILE, 1);
374
375 if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_READ))
376 return -1;
377 if (NULL == getenv(ENV_SANDBOX_READ))
378 setenv(ENV_SANDBOX_READ, "/", 1);
379
380 if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_WRITE))
381 return -1;
382 if ((NULL == getenv(ENV_SANDBOX_WRITE)) &&
383 (NULL != sandbox_info->work_dir))
384 setenv(ENV_SANDBOX_WRITE, sandbox_info->work_dir, 1);
385
386 if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_PREDICT))
387 return -1;
388 if ((NULL == getenv(ENV_SANDBOX_PREDICT)) &&
389 (NULL != sandbox_info->home_dir))
390 setenv(ENV_SANDBOX_PREDICT, sandbox_info->home_dir, 1);
259 391
260 return 0; 392 return 0;
261} 393}
262 394
263int sandbox_setenv(char **env, const char *name, const char *val) { 395int sandbox_setenv(char **env, const char *name, const char *val) {
293 int env_size = 0; 425 int env_size = 0;
294 int have_ld_preload = 0; 426 int have_ld_preload = 0;
295 427
296 char **new_environ; 428 char **new_environ;
297 char **env_ptr = environ; 429 char **env_ptr = environ;
298 char sandbox_write_envvar[SB_BUF_LEN];
299 char sandbox_predict_envvar[SB_BUF_LEN];
300 char *ld_preload_envvar = NULL; 430 char *ld_preload_envvar = NULL;
301 char *orig_ld_preload_envvar = NULL; 431 char *orig_ld_preload_envvar = NULL;
302 char sb_pid[64]; 432 char sb_pid[64];
433
434 if (-1 == sandbox_setup_env_config(sandbox_info))
435 return NULL;
303 436
304 /* Unset these, as its easier than replacing when setting up our 437 /* Unset these, as its easier than replacing when setting up our
305 * new environment below */ 438 * new environment below */
306 unsetenv(ENV_SANDBOX_ON); 439 unsetenv(ENV_SANDBOX_ON);
307 unsetenv(ENV_SANDBOX_PID); 440 unsetenv(ENV_SANDBOX_PID);
308 unsetenv(ENV_SANDBOX_LIB); 441 unsetenv(ENV_SANDBOX_LIB);
309 unsetenv(ENV_SANDBOX_BASHRC); 442 unsetenv(ENV_SANDBOX_BASHRC);
310 unsetenv(ENV_SANDBOX_LOG); 443 unsetenv(ENV_SANDBOX_LOG);
311 unsetenv(ENV_SANDBOX_DEBUG_LOG); 444 unsetenv(ENV_SANDBOX_DEBUG_LOG);
445 unsetenv(ENV_SANDBOX_WORKDIR);
312 unsetenv(ENV_SANDBOX_ACTIVE); 446 unsetenv(ENV_SANDBOX_ACTIVE);
313 447
314 if (NULL != getenv(ENV_LD_PRELOAD)) { 448 if (NULL != getenv(ENV_LD_PRELOAD)) {
315 have_ld_preload = 1; 449 have_ld_preload = 1;
316 orig_ld_preload_envvar = getenv(ENV_LD_PRELOAD); 450 orig_ld_preload_envvar = getenv(ENV_LD_PRELOAD);
370 sandbox_setenv(new_environ, ENV_NOCOLOR, "no"); 504 sandbox_setenv(new_environ, ENV_NOCOLOR, "no");
371 /* If LD_PRELOAD was not set, set it here, else do it below */ 505 /* If LD_PRELOAD was not set, set it here, else do it below */
372 if (1 != have_ld_preload) 506 if (1 != have_ld_preload)
373 sandbox_setenv(new_environ, ENV_LD_PRELOAD, ld_preload_envvar); 507 sandbox_setenv(new_environ, ENV_LD_PRELOAD, ld_preload_envvar);
374 508
375 if (!getenv(ENV_SANDBOX_DENY))
376 sandbox_setenv(new_environ, ENV_SANDBOX_DENY, LD_PRELOAD_FILE);
377
378 if (!getenv(ENV_SANDBOX_READ))
379 sandbox_setenv(new_environ, ENV_SANDBOX_READ, "/");
380
381 if (-1 == get_sandbox_write_envvar(sandbox_write_envvar, sandbox_info))
382 return NULL;
383 if (!getenv(ENV_SANDBOX_WRITE))
384 sandbox_setenv(new_environ, ENV_SANDBOX_WRITE, sandbox_write_envvar);
385
386 if (-1 == get_sandbox_predict_envvar(sandbox_predict_envvar, sandbox_info))
387 return NULL;
388 if (!getenv(ENV_SANDBOX_PREDICT))
389 sandbox_setenv(new_environ, ENV_SANDBOX_PREDICT, sandbox_predict_envvar);
390
391 /* Make sure our bashrc gets preference */ 509 /* Make sure our bashrc gets preference */
392 sandbox_setenv(new_environ, ENV_BASH_ENV, sandbox_info->sandbox_rc); 510 sandbox_setenv(new_environ, ENV_BASH_ENV, sandbox_info->sandbox_rc);
393 511
394 /* This one should NEVER be set in ebuilds, as it is the one 512 /* This one should NEVER be set in ebuilds, as it is the one
395 * private thing libsandbox.so use to test if the sandbox 513 * private thing libsandbox.so use to test if the sandbox
482 600
483 /* determine the location of all the sandbox support files */ 601 /* determine the location of all the sandbox support files */
484 if (print_debug) 602 if (print_debug)
485 printf("Detection of the support files.\n"); 603 printf("Detection of the support files.\n");
486 604
487 if (-1 == sandbox_setup(&sandbox_info)) { 605 if (-1 == sandbox_setup(&sandbox_info, print_debug)) {
488 fprintf(stderr, "sandbox: Failed to setup sandbox."); 606 fprintf(stderr, "sandbox: Failed to setup sandbox.");
489 exit(EXIT_FAILURE); 607 exit(EXIT_FAILURE);
490 } 608 }
491 609
492 /* verify the existance of required files */ 610 /* verify the existance of required files */

Legend:
Removed from v.283  
changed lines
  Added in v.286

  ViewVC Help
Powered by ViewVC 1.1.20