[R] Chrooted R + Rserve

Peter Danenberg pcd at wikitex.org
Sun Feb 3 17:30:23 CET 2008

I successfully chrooted R running Rserve with an unprivileged user,
and thought I'd publish the process.

Attached is a jailkit.ini for use with jailkit;* and a chroot/setuid
wrapper, chwrap.c.

To set up the chroot in, for instance, /var/R; perform:

   mkdir -v /var/R
   jk_init -v -c jailkit.ini -j /var/R R

then create the unprivileged user `r':

   useradd r

After compiling chwrap with:

   gcc -o chwrap chwrap.c

finally invoke Rserve with r's uid and gid (see /etc/passwd):

   chwrap [UID] [GID] /var/R /usr/local/bin/Rserve

* http://olivier.sessink.nl/jailkit
-------------- next part --------------
executables = /usr/bin/strace

comment = common files for all jails that need user/group information
libraries = /lib/libnsl.so.1, /lib/libnss_compat.so.2, /lib/libnss_files.so.2
regularfiles = /etc/nsswitch.conf
users = r
groups = r

executables = /sbin/ldconfig
regularfiles = /etc/ld.so.conf

executables = /bin/sh, /bin/rm, /bin/sed, /bin/uname

executables = /usr/local/bin/R, /usr/local/bin/Rserve, /usr/local/bin/Rserve.dbg
paths = /proc/meminfo, /etc/Rserv.conf
directories = /usr/local/lib/R, /usr/local/Rserve
devices = /dev/tty, /proc/self/fd/0
emptydirs = /tmp
includesections = ldconfig, strace, shell, uidbasics
-------------- next part --------------
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[], char *envp[])
  enum { PROG, UID, GID, ROOT, EXEC, ARGC };
  uid_t	*uid = malloc(sizeof(uid));
  gid_t	*gid = malloc(sizeof(gid));
  char *p, *e;

  if (argc < ARGC) {
    fprintf(stderr, "USAGE: %s UID GID ROOT EXEC [ARGS]\n", argv[0]);
  } else {
    sscanf(argv[UID], "%d", uid);
    sscanf(argv[GID], "%d", gid);
    p = argv[ROOT];
    e = argv[EXEC];

    if (chdir(p)) {
      printf("chdir to %s failed: %s", p, strerror(errno));
    } else if (chroot(p)) {
      printf("chroot to %s failed: %s", p, strerror(errno));
    } else if (setgid(*gid) != 0) {
      printf("setgid failed: %s", strerror(errno));
    } else if (setuid(*uid) != 0) {
      printf("setuid failed: %s", strerror(errno));
    } else {
      execve(e, argv + EXEC, envp);
      printf("execve failed: %s", strerror(errno));

More information about the R-help mailing list