#include <pwd.h>
#include <fcntl.h>
#include <sys/file.h>
+#include <sys/resource.h>
/* CONFIG: */
static gchar *optarg_setuid=CAPTIVE_SANDBOX_SETUID;
static gchar *optarg_setgid=CAPTIVE_SANDBOX_SETGID;
static gchar *optarg_chroot=CAPTIVE_SANDBOX_CHROOT;
+static gint optarg_no_rlimit=0;
static const struct poptOption popt_table[]={
#define SANDBOX_SERVER_POPT(longname,argInfoP,argP,descripP,argDescripP) \
argDescrip: (argDescripP), \
}
- SANDBOX_SERVER_POPT("setuid" ,POPT_ARG_STRING,&optarg_setuid,N_("Username or UID to become; \"-\" for disable"),N_("UID")),
- SANDBOX_SERVER_POPT("setgid" ,POPT_ARG_STRING,&optarg_setgid,N_("Groupname or GID to become; \"-\" for disable"),N_("GID")),
- SANDBOX_SERVER_POPT("chroot" ,POPT_ARG_STRING,&optarg_chroot,N_("Pathname to directory for chroot(2); \"-\" for disable"),N_("directory")),
+ SANDBOX_SERVER_POPT("setuid" ,POPT_ARG_STRING,&optarg_setuid,
+ N_("Username or UID to become; \"-\" for disable"),N_("UID")),
+ SANDBOX_SERVER_POPT("setgid" ,POPT_ARG_STRING,&optarg_setgid,
+ N_("Groupname or GID to become; \"-\" for disable"),N_("GID")),
+ SANDBOX_SERVER_POPT("chroot" ,POPT_ARG_STRING,&optarg_chroot,
+ N_("Pathname to directory for chroot(2); \"-\" for disable"),N_("directory")),
+ SANDBOX_SERVER_POPT("no-rlimit",POPT_ARG_NONE ,&optarg_no_rlimit,
+ N_("Disable setrlimit(2) restrictions"),NULL),
#undef SANDBOX_SERVER_POPT
POPT_AUTOHELP
fatal("Failed to chmod(\"%s\",0%o): %m",dir,0711);
}
+static void sandbox_server_rlimit(int resource,const gchar *resource_string,rlim_t rlim_max)
+{
+struct rlimit rlim;
+
+ rlim.rlim_cur=rlim.rlim_max=rlim_max;
+ if (setrlimit(resource,&rlim))
+ fatal("setrlimit(%s,%d): %m",resource_string,(int)rlim_max);
+ if (getrlimit(resource,&rlim))
+ fatal("getrlimit(%s,%d): %m",resource_string,(int)rlim_max);
+ if (rlim.rlim_cur!=rlim_max || rlim.rlim_max!=rlim_max)
+ fatal("Unsuccessful setrlimit(%s)",resource_string);
+}
+
static const gchar *chrooted_orbit_dir;
static void chroot_setup(gboolean fragile)
FILE *f;
if (!(f=fopen("/etc/passwd","w")))
fatal("Failed to fopen(\"%s\",\"w\"): %m","/etc/passwd");
- if (0>fprintf(f,"%s:*:%d:%d:%s:%s:/bin/false",want_uid_name,(int)want_uid,(int)want_gid,want_uid_name,optarg_chroot))
+ if (0>fprintf(f,"%s:*:%d:%d:%s:%s:/bin/false\n",want_uid_name,(int)want_uid,(int)want_gid,want_uid_name,optarg_chroot))
fatal("Failed to fprintf(\"%s\"): %m","/etc/passwd");
if (fclose(f))
fatal("Failed to fclose(\"%s\"): %m","/etc/passwd");
}
}
+ if (fragile || !optarg_no_rlimit) {
+#define SANDBOX_SERVER_RLIMIT(what,how) sandbox_server_rlimit((what),G_STRINGIFY(what),(how))
+ SANDBOX_SERVER_RLIMIT(RLIMIT_NPROC,0);
+ SANDBOX_SERVER_RLIMIT(RLIMIT_MEMLOCK,0);
+ SANDBOX_SERVER_RLIMIT(RLIMIT_CORE,0);
+ SANDBOX_SERVER_RLIMIT(RLIMIT_FSIZE,0);
+ SANDBOX_SERVER_RLIMIT(RLIMIT_NOFILE,6); /* >=6 */
+ /* FIXME: Why flock(dirfd,...) in chrooted_createdir() succeeds?: */
+ SANDBOX_SERVER_RLIMIT(RLIMIT_LOCKS,0);
+#undef SANDBOX_SERVER_RLIMIT
+ }
+
if (fragile) {
gid_t gid_list[2];
int gid_list_size,i;