From f08dc7e622b398b00d6916ead44a8c9058b5a17e Mon Sep 17 00:00:00 2001 Message-Id: From: Michal Privoznik Date: Tue, 25 Feb 2020 11:24:51 +0100 Subject: [PATCH] security: Don't remember seclabel for paths we haven't locked successfully There are some cases where we want to remember the original owner of a file but we fail to lock it for XATTR change (e.g. root squashed NFS). If that is the case we error out and refuse to start a domain. Well, we can do better if we disable remembering for paths we haven't locked successfully. Signed-off-by: Michal Privoznik Reviewed-by: Peter Krempa (cherry picked from commit 5fddf61351f44e4186c0313d81907024c574201b) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1804672 Signed-off-by: Michal Privoznik Message-Id: <4c2586a6da3b01adce09573a6123a15b3aea5ae6.1582626185.git.mprivozn@redhat.com> Reviewed-by: Jiri Denemark --- src/security/security_dac.c | 14 ++++++++++++++ src/security/security_manager.c | 7 ------- src/security/security_manager.h | 6 ++++++ src/security/security_selinux.c | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 2561ee440e..0cfe3626d4 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -240,6 +240,20 @@ virSecurityDACTransactionRun(pid_t pid G_GNUC_UNUSED, if (!(state = virSecurityManagerMetadataLock(list->manager, paths, npaths))) goto cleanup; + + for (i = 0; i < list->nItems; i++) { + virSecurityDACChownItemPtr item = list->items[i]; + size_t j; + + for (j = 0; j < state->nfds; j++) { + if (STREQ_NULLABLE(item->path, state->paths[j])) + break; + } + + /* If path wasn't locked, don't try to remember its label. */ + if (j == state->nfds) + item->remember = false; + } } for (i = 0; i < list->nItems; i++) { diff --git a/src/security/security_manager.c b/src/security/security_manager.c index 05d20e36af..9d06316a99 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -1245,13 +1245,6 @@ virSecurityManagerRestoreTPMLabels(virSecurityManagerPtr mgr, } -struct _virSecurityManagerMetadataLockState { - size_t nfds; /* Captures size of both @fds and @paths */ - int *fds; - const char **paths; -}; - - static int cmpstringp(const void *p1, const void *p2) { diff --git a/src/security/security_manager.h b/src/security/security_manager.h index f835356b7e..b92ea5dc87 100644 --- a/src/security/security_manager.h +++ b/src/security/security_manager.h @@ -203,6 +203,12 @@ int virSecurityManagerRestoreTPMLabels(virSecurityManagerPtr mgr, typedef struct _virSecurityManagerMetadataLockState virSecurityManagerMetadataLockState; typedef virSecurityManagerMetadataLockState *virSecurityManagerMetadataLockStatePtr; +struct _virSecurityManagerMetadataLockState { + size_t nfds; /* Captures size of both @fds and @paths */ + int *fds; + const char **paths; +}; + virSecurityManagerMetadataLockStatePtr virSecurityManagerMetadataLock(virSecurityManagerPtr mgr, diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 21279e7622..d7362327e6 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -271,6 +271,20 @@ virSecuritySELinuxTransactionRun(pid_t pid G_GNUC_UNUSED, if (!(state = virSecurityManagerMetadataLock(list->manager, paths, npaths))) goto cleanup; + + for (i = 0; i < list->nItems; i++) { + virSecuritySELinuxContextItemPtr item = list->items[i]; + size_t j; + + for (j = 0; j < state->nfds; j++) { + if (STREQ_NULLABLE(item->path, state->paths[j])) + break; + } + + /* If path wasn't locked, don't try to remember its label. */ + if (j == state->nfds) + item->remember = false; + } } rv = 0; -- 2.25.1