<command>confext</command> will extend only <filename>/etc</filename>. Files and directories contained
in the confext images outside of the <filename>/etc/</filename> hierarchy are <emphasis>not</emphasis>
merged, and hence have no effect when included in the image. Formats for these images are of the
- same as sysext images.</para>
+ same as sysext images. The merged hierarchy will be mounted with <literal>nosuid</literal> and
+ (if not disabled via <option>--noexec=false</option>) <literal>noexec</literal>.</para>
<para>Confexts are looked for in the directories <filename>/run/confexts/</filename>,
<filename>/var/lib/confexts/</filename>, <filename>/usr/lib/confexts/</filename> and
see above for details.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--noexec=</option><replaceable>BOOL</replaceable></term>
+
+ <listitem><para>When merging configuration extensions into <filename>/etc/</filename> the
+ <literal>MS_NOEXEC</literal> mount flag is used by default. This option can be used to disable
+ it.</para></listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="no-pager" />
<xi:include href="standard-options.xml" xpointer="no-legend" />
<xi:include href="standard-options.xml" xpointer="json" />
static PagerFlags arg_pager_flags = 0;
static bool arg_legend = true;
static bool arg_force = false;
+static int arg_noexec = -1;
static ImagePolicy *arg_image_policy = NULL;
/* Is set to IMAGE_CONFEXT when systemd is called with the confext functionality instead of the default */
const char *scope_env;
const char *name_env;
const ImagePolicy *default_image_policy;
+ unsigned long default_mount_flags;
} image_class_info[_IMAGE_CLASS_MAX] = {
[IMAGE_SYSEXT] = {
.dot_directory_name = ".systemd-sysext",
.scope_env = "SYSEXT_SCOPE",
.name_env = "SYSTEMD_SYSEXT_HIERARCHIES",
.default_image_policy = &image_policy_sysext,
+ .default_mount_flags = MS_RDONLY|MS_NODEV,
},
[IMAGE_CONFEXT] = {
.dot_directory_name = ".systemd-confext",
.scope_env = "CONFEXT_SCOPE",
.name_env = "SYSTEMD_CONFEXT_HIERARCHIES",
.default_image_policy = &image_policy_confext,
+ .default_mount_flags = MS_RDONLY|MS_NODEV|MS_NOSUID|MS_NOEXEC,
}
};
_cleanup_free_ char *options = NULL;
bool separator = false;
+ unsigned long flags;
int r;
assert(where);
separator = true;
}
+ flags = image_class_info[arg_image_class].default_mount_flags;
+ if (arg_noexec >= 0)
+ SET_FLAG(flags, MS_NOEXEC, arg_noexec);
+
/* Now mount the actual overlayfs */
- r = mount_nofollow_verbose(LOG_ERR, image_class_info[arg_image_class].short_identifier, where, "overlay", MS_RDONLY, options);
+ r = mount_nofollow_verbose(LOG_ERR, image_class_info[arg_image_class].short_identifier, where, "overlay", flags, options);
if (r < 0)
return r;
" --force Ignore version incompatibilities\n"
" --image-policy=POLICY\n"
" Specify disk image dissection policy\n"
+ " --noexec=BOOL Whether to mount extension overlay with noexec\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,
ARG_JSON,
ARG_FORCE,
ARG_IMAGE_POLICY,
+ ARG_NOEXEC,
};
static const struct option options[] = {
{ "json", required_argument, NULL, ARG_JSON },
{ "force", no_argument, NULL, ARG_FORCE },
{ "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
+ { "noexec", required_argument, NULL, ARG_NOEXEC },
{}
};
return r;
break;
+ case ARG_NOEXEC:
+ r = parse_boolean_argument("--noexec", optarg, NULL);
+ if (r < 0)
+ return r;
+
+ arg_noexec = r;
+ break;
+
case '?':
return -EINVAL;