RAppArmor (version 2.0.2)

eval.secure: Secure evaluation

Description

Evaluate in a sandboxed environment.

Usage

eval.secure(..., uid, gid, priority, profile, timeout = 60, silent = FALSE,
  verbose = FALSE, affinity, closeAllConnections = FALSE, RLIMIT_AS,
  RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_MEMLOCK,
  RLIMIT_MSGQUEUE, RLIMIT_NICE, RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_RTPRIO,
  RLIMIT_RTTIME, RLIMIT_SIGPENDING, RLIMIT_STACK)

Arguments

...

arguments passed on to eval.

uid

integer or name of linux user. See setuid.

gid

integer or name of linux group. See setgid.

priority

priority. Value between -20 and 20. See setpriority.

profile

AppArmor security profile. Has to be preloaded by Linux. See aa_change_profile.

timeout

timeout in seconds.

silent

suppress output on stdout. See mcparallel.

verbose

print some C output (TRUE/FALSE)

affinity

which cpu(s) to use. See setaffinity.

closeAllConnections

closes (and destroys) all user connections. See closeAllConnections.

RLIMIT_AS

hard limit passed on to rlimit_as.

RLIMIT_CORE

hard limit passed on to rlimit_core.

RLIMIT_CPU

hard limit passed on to rlimit_cpu.

RLIMIT_DATA

hard limit passed on to rlimit_data.

RLIMIT_FSIZE

hard limit passed on to rlimit_fsize.

RLIMIT_MEMLOCK

hard limit passed on to rlimit_memlock.

RLIMIT_MSGQUEUE

hard limit passed on to rlimit_msgqueue.

RLIMIT_NICE

hard limit passed on to rlimit_nice.

RLIMIT_NOFILE

hard limit passed on to rlimit_nofile.

RLIMIT_NPROC

hard limit passed on to rlimit_nproc.

RLIMIT_RTPRIO

hard limit passed on to rlimit_rtprio.

RLIMIT_RTTIME

hard limit passed on to rlimit_rttime.

RLIMIT_SIGPENDING

hard limit passed on to rlimit_sigpending.

RLIMIT_STACK

hard limit passed on to rlimit_stack.

Details

This function creates a fork, then sets rlimits, uid, gid, priority, apparmor profile where specified, and then evaluates the expression inside the fork. The return object of the evaluation is copied to the parent process and returned by eval.secure. After evaluation is done, the fork is immediately killed. If the timeout is reached the fork is also killed and an error is raised.

Evaluation of an expression using eval.secure has no side effects on the current R session. Any assignments to the global environment, changes in options, or library loadings done by the evaluation will get lost, as we explicitly want to prevent this. Only the return value of the expression will be copied to the main process. Files saved to disk by the sandboxed evaluation (where allowed by apparmor profile, etc) will also persist.

Note that if the initial process does not have superuser rights, rlimits can only be decreased and setuid/setgid might not work. In this case, specifying an RLIMIT higher than the current value will result in an error. Some of the rlimits can also be specified inside of the apparmor profile. When a rlimit is set both in the profile and through R, the more restrictive one will be effective.

References

Jeroen Ooms (2013). The RAppArmor Package: Enforcing Security Policies in R Using Dynamic Sandboxing on Linux. Journal of Statistical Software, 55(7), 1-34. http://www.jstatsoft.org/v55/i07/.

Examples

Run this code
# NOT RUN {
## Restricting file access ##
eval.secure(list.files("/"))
eval.secure(list.files("/"), profile="r-base")

eval.secure(system("ls /", intern=TRUE))
eval.secure(system("ls /", intern=TRUE), profile="r-base")

## Limiting CPU time ##
cputest <- function(){
A <- matrix(rnorm(1e7), 1e3);
B <- svd(A);
}

## setTimeLimit doesn't always work:
setTimeLimit(5);
cputest();
setTimeLimit();

#timeout does work:
eval.secure(cputest(), timeout=5)

## Limiting memory ##
A <- matrix(rnorm(1e8), 1e4);
B <- eval.secure(matrix(rnorm(1e8), 1e4), RLIMIT_AS = 100*1024*1024)

## Limiting procs ##
forkbomb <- function(){
repeat{
	parallel::mcparallel(forkbomb());
}
}

## Forkbomb is mitigated ##
eval.secure(forkbomb(), RLIMIT_NPROC=10)
# }

Run the code above in your browser using DataLab