mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 22:05:36 +00:00
lsm: add a --lsm-profile flag
In LXD, we use the container name in the LSM profile. If the container name is changed on migrate (on the host side), we want to use a different LSM profile name (a. la. --cgroup-root). This flag adds that support. v2: remove unused field, add comment about double detection in kerndat_lsm() Signed-off-by: Tycho Andersen <tycho.andersen@canonical.com> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
c5e002d55a
commit
6af96c8404
36
cr-restore.c
36
cr-restore.c
@@ -2827,29 +2827,35 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
|
|||||||
if (!creds)
|
if (!creds)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (creds->lsm_profile) {
|
if (creds->lsm_profile || opts.lsm_supplied) {
|
||||||
char *rendered;
|
char *rendered, *profile;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (validate_lsm(creds) < 0)
|
profile = creds->lsm_profile;
|
||||||
|
if (opts.lsm_supplied)
|
||||||
|
profile = opts.lsm_profile;
|
||||||
|
|
||||||
|
if (validate_lsm(profile) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = render_lsm_profile(creds->lsm_profile, &rendered);
|
if (profile) {
|
||||||
if (ret < 0) {
|
ret = render_lsm_profile(profile, &rendered);
|
||||||
goto err_nv;
|
if (ret < 0) {
|
||||||
}
|
goto err_nv;
|
||||||
|
}
|
||||||
|
|
||||||
lsm_pos = rst_mem_cpos(RM_PRIVATE);
|
lsm_pos = rst_mem_cpos(RM_PRIVATE);
|
||||||
lsm_profile_len = strlen(rendered);
|
lsm_profile_len = strlen(rendered);
|
||||||
lsm = rst_mem_alloc(lsm_profile_len + 1, RM_PRIVATE);
|
lsm = rst_mem_alloc(lsm_profile_len + 1, RM_PRIVATE);
|
||||||
if (!lsm) {
|
if (!lsm) {
|
||||||
|
xfree(rendered);
|
||||||
|
goto err_nv;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(lsm, rendered, lsm_profile_len);
|
||||||
xfree(rendered);
|
xfree(rendered);
|
||||||
goto err_nv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(lsm, rendered, lsm_profile_len);
|
|
||||||
xfree(rendered);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seccomp_filters_get_rst_pos(core, &n_seccomp_filters, &seccomp_filter_pos) < 0)
|
if (seccomp_filters_get_rst_pos(core, &n_seccomp_filters, &seccomp_filter_pos) < 0)
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "irmap.h"
|
#include "irmap.h"
|
||||||
#include "fault-injection.h"
|
#include "fault-injection.h"
|
||||||
|
#include "lsm.h"
|
||||||
|
|
||||||
#include "setproctitle.h"
|
#include "setproctitle.h"
|
||||||
|
|
||||||
@@ -253,6 +254,7 @@ int main(int argc, char *argv[], char *envp[])
|
|||||||
{ "freeze-cgroup", required_argument, 0, 1068 },
|
{ "freeze-cgroup", required_argument, 0, 1068 },
|
||||||
{ "ghost-limit", required_argument, 0, 1069 },
|
{ "ghost-limit", required_argument, 0, 1069 },
|
||||||
{ "irmap-scan-path", required_argument, 0, 1070 },
|
{ "irmap-scan-path", required_argument, 0, 1070 },
|
||||||
|
{ "lsm-profile", required_argument, 0, 1071 },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -498,6 +500,10 @@ int main(int argc, char *argv[], char *envp[])
|
|||||||
if (irmap_scan_path_add(optarg))
|
if (irmap_scan_path_add(optarg))
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
case 1071:
|
||||||
|
if (parse_lsm_arg(optarg) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
{
|
{
|
||||||
char *aux;
|
char *aux;
|
||||||
|
@@ -95,6 +95,8 @@ struct cr_options {
|
|||||||
bool overlayfs;
|
bool overlayfs;
|
||||||
size_t ghost_limit;
|
size_t ghost_limit;
|
||||||
struct list_head irmap_scan_paths;
|
struct list_head irmap_scan_paths;
|
||||||
|
bool lsm_supplied;
|
||||||
|
char *lsm_profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct cr_options opts;
|
extern struct cr_options opts;
|
||||||
|
@@ -23,7 +23,7 @@ extern int collect_lsm_profile(pid_t, CredsEntry *);
|
|||||||
* Validate that the LSM profiles can be correctly applied (must happen after
|
* Validate that the LSM profiles can be correctly applied (must happen after
|
||||||
* pstree is set up).
|
* pstree is set up).
|
||||||
*/
|
*/
|
||||||
int validate_lsm(CredsEntry *ce);
|
int validate_lsm(char *profile);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Render the profile name in the way that the LSM wants it written to
|
* Render the profile name in the way that the LSM wants it written to
|
||||||
@@ -31,4 +31,5 @@ int validate_lsm(CredsEntry *ce);
|
|||||||
*/
|
*/
|
||||||
int render_lsm_profile(char *profile, char **val);
|
int render_lsm_profile(char *profile, char **val);
|
||||||
|
|
||||||
|
extern int parse_lsm_arg(char *arg);
|
||||||
#endif /* __CR_LSM_H__ */
|
#endif /* __CR_LSM_H__ */
|
||||||
|
54
lsm.c
54
lsm.c
@@ -7,6 +7,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "pstree.h"
|
#include "pstree.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "cr_options.h"
|
||||||
|
|
||||||
#include "protobuf.h"
|
#include "protobuf.h"
|
||||||
#include "protobuf/inventory.pb-c.h"
|
#include "protobuf/inventory.pb-c.h"
|
||||||
@@ -106,6 +107,14 @@ static int selinux_get_label(pid_t pid, char **output)
|
|||||||
|
|
||||||
void kerndat_lsm(void)
|
void kerndat_lsm(void)
|
||||||
{
|
{
|
||||||
|
/* On restore, if someone passes --lsm-profile, we might end up doing
|
||||||
|
* detection twice, once during flag parsing and once for
|
||||||
|
* kerndat_init_rst(). Let's detect when we've already done detection
|
||||||
|
* and not do it again.
|
||||||
|
*/
|
||||||
|
if (name)
|
||||||
|
return;
|
||||||
|
|
||||||
if (access("/sys/kernel/security/apparmor", F_OK) == 0) {
|
if (access("/sys/kernel/security/apparmor", F_OK) == 0) {
|
||||||
get_label = apparmor_get_label;
|
get_label = apparmor_get_label;
|
||||||
lsmtype = LSMTYPE__APPARMOR;
|
lsmtype = LSMTYPE__APPARMOR;
|
||||||
@@ -156,7 +165,7 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
|
|||||||
// in inventory.c
|
// in inventory.c
|
||||||
extern Lsmtype image_lsm;
|
extern Lsmtype image_lsm;
|
||||||
|
|
||||||
int validate_lsm(CredsEntry *ce)
|
int validate_lsm(char *lsm_profile)
|
||||||
{
|
{
|
||||||
if (image_lsm == LSMTYPE__NO_LSM || image_lsm == lsmtype)
|
if (image_lsm == LSMTYPE__NO_LSM || image_lsm == lsmtype)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -166,7 +175,7 @@ int validate_lsm(CredsEntry *ce)
|
|||||||
* specified an LSM profile. If not, we won't restore anything anyway,
|
* specified an LSM profile. If not, we won't restore anything anyway,
|
||||||
* so it's fine.
|
* so it's fine.
|
||||||
*/
|
*/
|
||||||
if (ce->lsm_profile) {
|
if (lsm_profile) {
|
||||||
pr_err("mismatched lsm types and lsm profile specified\n");
|
pr_err("mismatched lsm types and lsm profile specified\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -197,3 +206,44 @@ int render_lsm_profile(char *profile, char **val)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_lsm_arg(char *arg)
|
||||||
|
{
|
||||||
|
char *aux;
|
||||||
|
|
||||||
|
kerndat_lsm();
|
||||||
|
|
||||||
|
aux = strchr(arg, ':');
|
||||||
|
if (aux == NULL) {
|
||||||
|
pr_err("invalid argument %s for --lsm-profile", arg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aux = '\0';
|
||||||
|
aux++;
|
||||||
|
|
||||||
|
if (strcmp(arg, "apparmor") == 0) {
|
||||||
|
if (lsmtype != LSMTYPE__APPARMOR) {
|
||||||
|
pr_err("apparmor LSM specified but apparmor not supported by kernel\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.lsm_profile = aux;
|
||||||
|
} else if (strcmp(arg, "selinux") == 0) {
|
||||||
|
if (lsmtype != LSMTYPE__SELINUX) {
|
||||||
|
pr_err("selinux LSM specified but selinux not supported by kernel\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.lsm_profile = aux;
|
||||||
|
} else if (strcmp(arg, "none") == 0) {
|
||||||
|
opts.lsm_profile = NULL;
|
||||||
|
} else {
|
||||||
|
pr_err("unknown lsm %s\n", arg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.lsm_supplied = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user