-->
+
<!DOCTYPE refentry PUBLIC @docdtd@ [
<!ENTITY commonoptions SYSTEM "@builddir@/common_options.sgml">
<varlistentry>
<term>
- <option>-e, --elevated-privileges</option>
+ <option>
+ -e, --elevated-privileges <replaceable>privileges</replaceable>
+ </option>
</term>
<listitem>
<para>
<emphasis>not</emphasis> be added to the container's cgroup(s)
and it will not drop its capabilities before executing.
</para>
+ <para>
+ You may specify privileges, in case you do not want to elevate all of
+ them, as a pipe-separated list, e.g.
+ <replaceable>CGROUP|LSM</replaceable>. Allowed values are
+ <replaceable>CGROUP</replaceable>, <replaceable>CAP</replaceable> and
+ <replaceable>LSM</replaceable> representing cgroup, capabilities and
+ restriction privileges respectively.
+ </para>
<para>
<emphasis>Warning:</emphasis> This may leak privileges into the
container if the command starts subprocesses that remain active
return -1;
}
+int lxc_fill_elevated_privileges(char *flaglist, int *flags)
+{
+ char *token, *saveptr = NULL;
+ int i, aflag;
+ struct { const char *token; int flag; } all_privs[] = {
+ { "CGROUP", LXC_ATTACH_MOVE_TO_CGROUP },
+ { "CAP", LXC_ATTACH_DROP_CAPABILITIES },
+ { "LSM", LXC_ATTACH_LSM_EXEC },
+ { NULL, 0 }
+ };
+
+ if (!flaglist) {
+ /* for the sake of backward compatibility, drop all privileges
+ if none is specified */
+ for (i = 0; all_privs[i].token; i++) {
+ *flags |= all_privs[i].flag;
+ }
+ return 0;
+ }
+
+ token = strtok_r(flaglist, "|", &saveptr);
+ while (token) {
+ aflag = -1;
+ for (i = 0; all_privs[i].token; i++) {
+ if (!strcmp(all_privs[i].token, token))
+ aflag = all_privs[i].flag;
+ }
+ if (aflag < 0)
+ return -1;
+
+ *flags |= aflag;
+
+ token = strtok_r(NULL, "|", &saveptr);
+ }
+ return 0;
+}
+
static int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v)
{
if (!retv)
lxc_log_define(lxc_attach_ui, lxc);
static const struct option my_longopts[] = {
- {"elevated-privileges", no_argument, 0, 'e'},
+ {"elevated-privileges", optional_argument, 0, 'e'},
{"arch", required_argument, 0, 'a'},
{"namespaces", required_argument, 0, 's'},
{"remount-sys-proc", no_argument, 0, 'R'},
int ret;
switch (c) {
- case 'e': elevated_privileges = 1; break;
+ case 'e':
+ ret = lxc_fill_elevated_privileges(arg, &elevated_privileges);
+ if (ret)
+ return -1;
+ break;
case 'R': remount_sys_proc = 1; break;
case 'a':
new_personality = lxc_config_parse_arch(arg);
if (ret)
return -1;
/* -s implies -e */
- elevated_privileges = 1;
+ lxc_fill_elevated_privileges(NULL, &elevated_privileges);
break;
case 500: /* clear-env */
env_policy = LXC_ATTACH_CLEAR_ENV;
\n\
Options :\n\
-n, --name=NAME NAME for name of the container\n\
- -e, --elevated-privileges\n\
- Use elevated privileges (capabilities, cgroup\n\
- restrictions) instead of those of the container.\n\
+ -e, --elevated-privileges=PRIVILEGES\n\
+ Use elevated privileges instead of those of the\n\
+ container. If you don't specify privileges to be\n\
+ elevated as OR'd list: CAP, CGROUP and LSM (capabilities,\n\
+ cgroup and restrictions, respectively) then all of them\n\
+ will be elevated.\n\
WARNING: This may leak privileges into the container.\n\
Use with care.\n\
-a, --arch=ARCH Use ARCH for program instead of container's own\n\
-s, --namespaces=FLAGS\n\
Don't attach to all the namespaces of the container\n\
but just to the following OR'd list of flags:\n\
- MOUNT, PID, UTSNAME, IPC, USER or NETWORK\n\
- WARNING: Using -s implies -e, it may therefore\n\
- leak privileges into the container. Use with care.\n\
+ MOUNT, PID, UTSNAME, IPC, USER or NETWORK.\n\
+ WARNING: Using -s implies -e with all privileges\n\
+ elevated, it may therefore leak privileges into the\n\
+ container. Use with care.\n\
-R, --remount-sys-proc\n\
Remount /sys and /proc if not attaching to the\n\
mount namespace when using -s in order to properly\n\
if (remount_sys_proc)
attach_options.attach_flags |= LXC_ATTACH_REMOUNT_PROC_SYS;
if (elevated_privileges)
- attach_options.attach_flags &= ~(LXC_ATTACH_MOVE_TO_CGROUP | LXC_ATTACH_DROP_CAPABILITIES | LXC_ATTACH_LSM_EXEC);
+ attach_options.attach_flags &= ~(elevated_privileges);
attach_options.namespaces = namespace_flags;
attach_options.personality = new_personality;
attach_options.env_policy = env_policy;