smack: introduce new SmackProcessLabel option
In service file, if the file has some of special SMACK label in ExecStart= and systemd has no permission for the special SMACK label then permission error will occurred. To resolve this, systemd should be able to set its SMACK label to something accessible of ExecStart=. So introduce new SmackProcessLabel. If label is specified with SmackProcessLabel= then the child systemd will set its label to that. To successfully execute the ExecStart=, accessible label should be specified with SmackProcessLabel=. Additionally, by SMACK policy, if the file in ExecStart= has no SMACK64EXEC then the executed process will have given label by SmackProcessLabel=. But if the file has SMACK64EXEC then the SMACK64EXEC label will be overridden. [zj: reword man page]
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
8086ffacdb
commit
2ca620c4ed
@@ -508,6 +508,24 @@ static int property_get_apparmor_profile(
|
||||
return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
|
||||
}
|
||||
|
||||
static int property_get_smack_process_label(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = userdata;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(c);
|
||||
|
||||
return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
|
||||
}
|
||||
|
||||
static int property_get_personality(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -636,6 +654,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#include "af-list.h"
|
||||
#include "mkdir.h"
|
||||
#include "apparmor-util.h"
|
||||
#include "smack-util.h"
|
||||
#include "bus-kernel.h"
|
||||
#include "label.h"
|
||||
|
||||
@@ -1618,6 +1619,16 @@ static int exec_child(ExecCommand *command,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SMACK
|
||||
if (context->smack_process_label) {
|
||||
err = mac_smack_apply_pid(0, context->smack_process_label);
|
||||
if (err < 0) {
|
||||
*error = EXIT_SMACK_PROCESS_LABEL;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (context->user) {
|
||||
err = enforce_user(context, uid);
|
||||
if (err < 0) {
|
||||
|
||||
@@ -142,6 +142,9 @@ struct ExecContext {
|
||||
bool apparmor_profile_ignore;
|
||||
char *apparmor_profile;
|
||||
|
||||
bool smack_process_label_ignore;
|
||||
char *smack_process_label;
|
||||
|
||||
char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
|
||||
unsigned long mount_flags;
|
||||
|
||||
|
||||
@@ -95,8 +95,11 @@ m4_ifdef(`HAVE_SELINUX',
|
||||
`$1.SELinuxContext, config_parse_exec_selinux_context, 0, offsetof($1, exec_context)',
|
||||
`$1.SELinuxContext, config_parse_warn_compat, 0, 0')
|
||||
m4_ifdef(`HAVE_APPARMOR',
|
||||
`$1.AppArmorProfile, config_parse_exec_apparmor_profile,0, offsetof($1, exec_context)',
|
||||
`$1.AppArmorProfile, config_parse_warn_compat, 0, 0')'
|
||||
`$1.AppArmorProfile, config_parse_exec_apparmor_profile, 0, offsetof($1, exec_context)',
|
||||
`$1.AppArmorProfile, config_parse_warn_compat, 0, 0')
|
||||
m4_ifdef(`HAVE_SMACK',
|
||||
`$1.SmackProcessLabel, config_parse_exec_smack_process_label, 0, offsetof($1, exec_context)',
|
||||
`$1.SmackProcessLabel, config_parse_warn_compat, 0, 0')'
|
||||
)m4_dnl
|
||||
m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
|
||||
`$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, kill_context.send_sigkill)
|
||||
|
||||
@@ -1313,6 +1313,56 @@ int config_parse_exec_apparmor_profile(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_exec_smack_process_label(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
ExecContext *c = data;
|
||||
Unit *u = userdata;
|
||||
bool ignore;
|
||||
char *k;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
free(c->smack_process_label);
|
||||
c->smack_process_label = NULL;
|
||||
c->smack_process_label_ignore = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rvalue[0] == '-') {
|
||||
ignore = true;
|
||||
rvalue++;
|
||||
} else
|
||||
ignore = false;
|
||||
|
||||
r = unit_name_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, -r,
|
||||
"Failed to resolve specifiers, ignoring: %s", strerror(-r));
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(c->smack_process_label);
|
||||
c->smack_process_label = k;
|
||||
c->smack_process_label_ignore = ignore;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_timer(const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
|
||||
@@ -94,6 +94,7 @@ int config_parse_job_mode_isolate(const char *unit, const char *filename, unsign
|
||||
int config_parse_exec_selinux_context(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_personality(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_exec_apparmor_profile(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_exec_smack_process_label(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_address_families(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_runtime_directory(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_set_status(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
|
||||
Reference in New Issue
Block a user