jeroen/RAppArmor

Nested Profiles: Permissions needed to kill a fork?

Closed this issue · 3 comments

Dear Jeroen,

first, thanks a lot for creating the RAppArmor package. Here is my issue. I would like to call eval.secure from an R process that is already restricted with RAppArmor. The code does run, but I get a warning that the fork cannot be killed. Here is an example:

library(RAppArmor)
# Set outer profile with more access
aa_change_profile("ps_intro-armor-outer")
eval.secure(quote(1+1),profile = "ps_intro-armor-inner")
## [1] 2
## Warning messages:
## 1: In kill(myfork$pid, SIGKILL, verbose = verbose) : EACCES
## 2: In kill(-1 * myfork$pid, SIGKILL, verbose = verbose) : EACCES

The problem probably seems to be that the outer profile "ps_intro-armor-outer" has no right to kill a created fork. Do you know by any chance the permissions I have to grant to the profile ps_intro-armor-outer so that killing the fork works? (A related question: Do you know whether the non-killed fork remains active for a long time and consume system ressources, or be deleted somehow automatically?)

Here is my file with the two apparmor profiles:

## Apparmor profiles for an RTutor problem set app

## The outer profile, restricts access to problem set
## folder. It must be enabled in global.R to provide a
## safeguard if there should be a security hole in
## RTutor that prevents correctly setting the inner armor
## every time a user expression is evaluated.

## alias appdir -> /home/sk/libraries/RTutor/apps/ps_intro

profile ps_intro-armor-outer {

    #include <abstractions/base>
    #include <abstractions/nameservice>

    @{PROC}/[0-9]*/attr/current r,  

    change_profile -> ps_intro-armor-inner,

    /bin/* rix,
    /dev/tty r, 
    /etc/R/ r,
    /etc/R/* r,
    /etc/fonts/** mr,
    /etc/resolv.conf r,
    /etc/xml/* r,
    /tmp/** rw,
    /usr/bin/* rix,
    /usr/lib/R/bin/* rix,
    /usr/lib{,32,64}/** mr,
    /usr/lib{,32,64}/R/bin/exec/R rix,
    /usr/local/lib/R/** mr,
    /usr/local/share/** mr,
    /usr/share/** mr,
    /usr/share/ca-certificates/** r,
    /etc/xml/* r,

## Access to app dir 
    /home/sk/libraries/RTutor/apps/ps_intro/* r,
    /home/sk/libraries/RTutor/apps/ps_intro/figure/* r,
    /home/sk/libraries/RTutor/apps/ps_intro/sessions/* r,
    /home/sk/libraries/RTutor/apps/ps_intro/ups/* rw,
    /home/sk/libraries/RTutor/apps/ps_intro/Intro.log w,
}


## The inner profile used when user statements
## are evaluated. Should only allow read access
## to data sets that must be loaded. No write access
## beyond "rtutor-r-access" needed.

profile ps_intro-armor-inner {
    #include <abstractions/base>
    #include <abstractions/nameservice>

    @{PROC}/[0-9]*/attr/current r,  

    /bin/* rix,
    /dev/tty r, 
    /etc/R/ r,
    /etc/R/* r,
    /etc/fonts/** mr,
    /etc/resolv.conf r,
    /etc/xml/* r,
    /tmp/** rw,
    /usr/bin/* rix,
    /usr/lib/R/bin/* rix,
    /usr/lib{,32,64}/** mr,
    /usr/lib{,32,64}/R/bin/exec/R rix,
    /usr/local/lib/R/** mr,
    /usr/local/share/** mr,
    /usr/share/** mr,
    /usr/share/ca-certificates/** r,
    /etc/xml/* r,

## Add read access to data files that will be 
## loaded inside the problem set
##  @{APPDIR}/MYFILE.csv r,


}

Background:
You may wonder, why I want to use nested RAppArmor profiles. My RTutor package (https://github.com/skranz/RTutor) allows users to enter and evaluate free R code on a webpage. Currently users can run it on their local machines or on shinyapps.io but I am working on ways to securely host it on own shiny servers to better use it for teaching.

Inside the package I want to use secure.eval with a tight inner security profile to prevent undesired behavior of entered code. However, since the package is fairly complex (e.g. it generates automatic hints based on the user code), I may have overlooked some loophole how code could be evaluated in a less secure way. As a safeguard, I would like to enforce a less restrictive outer profile in which the whole app will be wrapped and which can prevent any larger damage if such loopholes exist.

Best wishes,
Sebastian

Great, the warnings go away. Thanks a lot. Just for reference for future users, my outer profile needs to have these two lines:

    change_profile -> ps_intro-armor-inner,
    signal w peer=ps_intro-armor-inner,

and one also needs to add this line to the tighter inner profile

    signal r peer=ps_intro-armor-outer, 

Cool. I use a similar design for opencpu: an outer profile for the server and a more restrictive inner profile for executing user code.