libsemanage-3.3-3
- allow spaces in user/group names (#2049665) - Fall back to semanage_copy_dir when rename() fails (#2068085) Resolves: rhbz#2049665, rhbz#2068085
This commit is contained in:
parent
1256683730
commit
739e7477f9
362
0007-libsemanage-allow-spaces-in-user-group-names.patch
Normal file
362
0007-libsemanage-allow-spaces-in-user-group-names.patch
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
From 898d1e720a4cf1e0dfdb76e0c4b11d92031a8e1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Vit Mojzis <vmojzis@redhat.com>
|
||||||
|
Date: Thu, 17 Feb 2022 13:49:23 +0100
|
||||||
|
Subject: [PATCH] libsemanage: allow spaces in user/group names
|
||||||
|
Content-type: text/plain
|
||||||
|
|
||||||
|
"semanage login -a" accepts whitespaces in user/group name
|
||||||
|
(e.g. users/groups from Active Directory), which may lead to issues down
|
||||||
|
the line since libsemanage doesn't expect whitespaces in
|
||||||
|
/var/lib/selinux/targeted/active/seusers and other config files.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
Artificial but simple reproducer
|
||||||
|
# groupadd server_admins
|
||||||
|
# sed -i "s/^server_admins/server admins/" /etc/group
|
||||||
|
# semanage login -a -s staff_u %server\ admins
|
||||||
|
# semanage login -l (or "semodule -B")
|
||||||
|
libsemanage.parse_assert_ch: expected character ':', but found 'a' (/var/lib/selinux/targeted/active/seusers: 6):
|
||||||
|
%server admins:staff_u:s0-s0:c0.c1023 (No such file or directory).
|
||||||
|
libsemanage.seuser_parse: could not parse seuser record (No such file or directory).
|
||||||
|
libsemanage.dbase_file_cache: could not cache file database (No such file or directory).
|
||||||
|
libsemanage.enter_ro: could not enter read-only section (No such file or directory).
|
||||||
|
FileNotFoundError: [Errno 2] No such file or directory
|
||||||
|
|
||||||
|
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
|
||||||
|
---
|
||||||
|
libsemanage/src/booleans_file.c | 2 +-
|
||||||
|
libsemanage/src/fcontexts_file.c | 6 +++---
|
||||||
|
libsemanage/src/ibendports_file.c | 4 ++--
|
||||||
|
libsemanage/src/ibpkeys_file.c | 4 ++--
|
||||||
|
libsemanage/src/interfaces_file.c | 6 +++---
|
||||||
|
libsemanage/src/nodes_file.c | 8 ++++----
|
||||||
|
libsemanage/src/parse_utils.c | 6 +++---
|
||||||
|
libsemanage/src/parse_utils.h | 11 +++++------
|
||||||
|
libsemanage/src/ports_file.c | 4 ++--
|
||||||
|
libsemanage/src/seusers_file.c | 6 +++---
|
||||||
|
libsemanage/src/users_base_file.c | 7 +++----
|
||||||
|
libsemanage/src/users_extra_file.c | 4 ++--
|
||||||
|
12 files changed, 33 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsemanage/src/booleans_file.c b/libsemanage/src/booleans_file.c
|
||||||
|
index f79d0b44eb16..6d600bbc9421 100644
|
||||||
|
--- a/libsemanage/src/booleans_file.c
|
||||||
|
+++ b/libsemanage/src/booleans_file.c
|
||||||
|
@@ -48,7 +48,7 @@ static int bool_parse(semanage_handle_t * handle,
|
||||||
|
goto last;
|
||||||
|
|
||||||
|
/* Extract name */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, '=') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, '=', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (semanage_bool_set_name(handle, boolean, str) < 0)
|
||||||
|
diff --git a/libsemanage/src/fcontexts_file.c b/libsemanage/src/fcontexts_file.c
|
||||||
|
index 04cd365aa2df..f35794103a50 100644
|
||||||
|
--- a/libsemanage/src/fcontexts_file.c
|
||||||
|
+++ b/libsemanage/src/fcontexts_file.c
|
||||||
|
@@ -90,7 +90,7 @@ static int fcontext_parse(semanage_handle_t * handle,
|
||||||
|
goto last;
|
||||||
|
|
||||||
|
/* Regexp */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_fcontext_set_expr(handle, fcontext, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -100,7 +100,7 @@ static int fcontext_parse(semanage_handle_t * handle,
|
||||||
|
/* Type */
|
||||||
|
if (parse_assert_space(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (!strcasecmp(str, "-s"))
|
||||||
|
semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_SOCK);
|
||||||
|
@@ -124,7 +124,7 @@ static int fcontext_parse(semanage_handle_t * handle,
|
||||||
|
/* Context */
|
||||||
|
if (parse_assert_space(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
process_context:
|
||||||
|
diff --git a/libsemanage/src/ibendports_file.c b/libsemanage/src/ibendports_file.c
|
||||||
|
index bafa8c1d65bf..2fa2a67c5b40 100644
|
||||||
|
--- a/libsemanage/src/ibendports_file.c
|
||||||
|
+++ b/libsemanage/src/ibendports_file.c
|
||||||
|
@@ -75,7 +75,7 @@ static int ibendport_parse(semanage_handle_t *handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* IB Device Name */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_ibendport_set_ibdev_name(handle, ibendport, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -92,7 +92,7 @@ static int ibendport_parse(semanage_handle_t *handle,
|
||||||
|
/* context */
|
||||||
|
if (parse_assert_space(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_context_from_string(handle, str, &con) < 0) {
|
||||||
|
ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
|
||||||
|
diff --git a/libsemanage/src/ibpkeys_file.c b/libsemanage/src/ibpkeys_file.c
|
||||||
|
index 929bc31e612e..edde69f09f70 100644
|
||||||
|
--- a/libsemanage/src/ibpkeys_file.c
|
||||||
|
+++ b/libsemanage/src/ibpkeys_file.c
|
||||||
|
@@ -80,7 +80,7 @@ static int ibpkey_parse(semanage_handle_t *handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Subnet Prefix */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_ibpkey_set_subnet_prefix(handle, ibpkey, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -115,7 +115,7 @@ static int ibpkey_parse(semanage_handle_t *handle,
|
||||||
|
semanage_ibpkey_set_pkey(ibpkey, low);
|
||||||
|
}
|
||||||
|
/* Pkey context */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_context_from_string(handle, str, &con) < 0) {
|
||||||
|
ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
|
||||||
|
diff --git a/libsemanage/src/interfaces_file.c b/libsemanage/src/interfaces_file.c
|
||||||
|
index c19c8f949c91..244f0ae51eca 100644
|
||||||
|
--- a/libsemanage/src/interfaces_file.c
|
||||||
|
+++ b/libsemanage/src/interfaces_file.c
|
||||||
|
@@ -72,7 +72,7 @@ static int iface_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Name */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_iface_set_name(handle, iface, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -82,7 +82,7 @@ static int iface_parse(semanage_handle_t * handle,
|
||||||
|
/* Interface context */
|
||||||
|
if (parse_assert_space(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_context_from_string(handle, str, &con) < 0) {
|
||||||
|
ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
|
||||||
|
@@ -106,7 +106,7 @@ static int iface_parse(semanage_handle_t * handle,
|
||||||
|
/* Message context */
|
||||||
|
if (parse_assert_space(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_context_from_string(handle, str, &con) < 0) {
|
||||||
|
ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
|
||||||
|
diff --git a/libsemanage/src/nodes_file.c b/libsemanage/src/nodes_file.c
|
||||||
|
index c3647f2ad622..2d2b7fe023f5 100644
|
||||||
|
--- a/libsemanage/src/nodes_file.c
|
||||||
|
+++ b/libsemanage/src/nodes_file.c
|
||||||
|
@@ -77,7 +77,7 @@ static int node_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Protocol */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (!strcasecmp(str, "ipv4"))
|
||||||
|
proto = SEMANAGE_PROTO_IP4;
|
||||||
|
@@ -96,7 +96,7 @@ static int node_parse(semanage_handle_t * handle,
|
||||||
|
/* Address */
|
||||||
|
if (parse_assert_space(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_node_set_addr(handle, node, proto, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -106,7 +106,7 @@ static int node_parse(semanage_handle_t * handle,
|
||||||
|
str = NULL;
|
||||||
|
|
||||||
|
/* Netmask */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_node_set_mask(handle, node, proto, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -116,7 +116,7 @@ static int node_parse(semanage_handle_t * handle,
|
||||||
|
str = NULL;
|
||||||
|
|
||||||
|
/* Port context */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_context_from_string(handle, str, &con) < 0) {
|
||||||
|
ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
|
||||||
|
diff --git a/libsemanage/src/parse_utils.c b/libsemanage/src/parse_utils.c
|
||||||
|
index 4fb54fc3d831..918dee439582 100644
|
||||||
|
--- a/libsemanage/src/parse_utils.c
|
||||||
|
+++ b/libsemanage/src/parse_utils.c
|
||||||
|
@@ -239,7 +239,7 @@ int parse_fetch_int(semanage_handle_t * handle,
|
||||||
|
char *test = NULL;
|
||||||
|
int value = 0;
|
||||||
|
|
||||||
|
- if (parse_fetch_string(handle, info, &str, delim) < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, delim, 0) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!isdigit((int)*str)) {
|
||||||
|
@@ -267,7 +267,7 @@ int parse_fetch_int(semanage_handle_t * handle,
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_fetch_string(semanage_handle_t * handle,
|
||||||
|
- parse_info_t * info, char **str, char delim)
|
||||||
|
+ parse_info_t * info, char **str, char delim, int allow_spaces)
|
||||||
|
{
|
||||||
|
|
||||||
|
char *start = info->ptr;
|
||||||
|
@@ -277,7 +277,7 @@ int parse_fetch_string(semanage_handle_t * handle,
|
||||||
|
if (parse_assert_noeof(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- while (*(info->ptr) && !isspace(*(info->ptr)) &&
|
||||||
|
+ while (*(info->ptr) && (allow_spaces || !isspace(*(info->ptr))) &&
|
||||||
|
(*(info->ptr) != delim)) {
|
||||||
|
info->ptr++;
|
||||||
|
len++;
|
||||||
|
diff --git a/libsemanage/src/parse_utils.h b/libsemanage/src/parse_utils.h
|
||||||
|
index 0f3348601828..3e44aca10d1c 100644
|
||||||
|
--- a/libsemanage/src/parse_utils.h
|
||||||
|
+++ b/libsemanage/src/parse_utils.h
|
||||||
|
@@ -71,12 +71,11 @@ extern int parse_optional_str(parse_info_t * info, const char *str);
|
||||||
|
int parse_fetch_int(semanage_handle_t * hgandle,
|
||||||
|
parse_info_t * info, int *num, char delim);
|
||||||
|
|
||||||
|
-/* Extract the next string (delimited by
|
||||||
|
- * whitespace), and move the read pointer past it.
|
||||||
|
- * Stop of the optional character delim is encountered,
|
||||||
|
- * or if whitespace/eof is encountered. Fail if the
|
||||||
|
- * string is of length 0. */
|
||||||
|
+/* Extract the next string and move the read pointer past it.
|
||||||
|
+ * Stop if the optional character delim (or eof) is encountered,
|
||||||
|
+ * or if whitespace is encountered and allow_spaces is 0.
|
||||||
|
+ * Fail if the string is of length 0. */
|
||||||
|
extern int parse_fetch_string(semanage_handle_t * handle,
|
||||||
|
- parse_info_t * info, char **str_ptr, char delim);
|
||||||
|
+ parse_info_t * info, char **str_ptr, char delim, int allow_spaces);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/libsemanage/src/ports_file.c b/libsemanage/src/ports_file.c
|
||||||
|
index ade4102f0e0d..1356021aaaac 100644
|
||||||
|
--- a/libsemanage/src/ports_file.c
|
||||||
|
+++ b/libsemanage/src/ports_file.c
|
||||||
|
@@ -77,7 +77,7 @@ static int port_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Protocol */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (!strcasecmp(str, "tcp"))
|
||||||
|
semanage_port_set_proto(port, SEMANAGE_PROTO_TCP);
|
||||||
|
@@ -123,7 +123,7 @@ static int port_parse(semanage_handle_t * handle,
|
||||||
|
semanage_port_set_port(port, low);
|
||||||
|
|
||||||
|
/* Port context */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_context_from_string(handle, str, &con) < 0) {
|
||||||
|
ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
|
||||||
|
diff --git a/libsemanage/src/seusers_file.c b/libsemanage/src/seusers_file.c
|
||||||
|
index 910bedf47a81..21b970acd417 100644
|
||||||
|
--- a/libsemanage/src/seusers_file.c
|
||||||
|
+++ b/libsemanage/src/seusers_file.c
|
||||||
|
@@ -53,7 +53,7 @@ static int seuser_parse(semanage_handle_t * handle,
|
||||||
|
goto last;
|
||||||
|
|
||||||
|
/* Extract name */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ':') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ':', 1) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_seuser_set_name(handle, seuser, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -68,7 +68,7 @@ static int seuser_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Extract sename */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ':') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ':', 1) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_seuser_set_sename(handle, seuser, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -83,7 +83,7 @@ static int seuser_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* NOTE: does not allow spaces/multiline */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (semanage_seuser_set_mlsrange(handle, seuser, str) < 0)
|
||||||
|
diff --git a/libsemanage/src/users_base_file.c b/libsemanage/src/users_base_file.c
|
||||||
|
index 0f0a8fdb7973..a0f8cd7e1c5b 100644
|
||||||
|
--- a/libsemanage/src/users_base_file.c
|
||||||
|
+++ b/libsemanage/src/users_base_file.c
|
||||||
|
@@ -83,7 +83,7 @@ static int user_base_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Parse user name */
|
||||||
|
- if (parse_fetch_string(handle, info, &name_str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &name_str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (semanage_user_base_set_name(handle, user, name_str) < 0) {
|
||||||
|
@@ -150,7 +150,7 @@ static int user_base_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* NOTE: does not allow spaces/multiline */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_user_base_set_mlslevel(handle, user, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -165,8 +165,7 @@ static int user_base_parse(semanage_handle_t * handle,
|
||||||
|
if (parse_assert_space(handle, info) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- /* NOTE: does not allow spaces/multiline */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ';') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ';', 1) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_user_base_set_mlsrange(handle, user, str) < 0)
|
||||||
|
goto err;
|
||||||
|
diff --git a/libsemanage/src/users_extra_file.c b/libsemanage/src/users_extra_file.c
|
||||||
|
index 8f2bebd687b9..7aa9df3c6ba6 100644
|
||||||
|
--- a/libsemanage/src/users_extra_file.c
|
||||||
|
+++ b/libsemanage/src/users_extra_file.c
|
||||||
|
@@ -57,7 +57,7 @@ static int user_extra_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Extract name */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_user_extra_set_name(handle, user_extra, str) < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -73,7 +73,7 @@ static int user_extra_parse(semanage_handle_t * handle,
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Extract prefix */
|
||||||
|
- if (parse_fetch_string(handle, info, &str, ';') < 0)
|
||||||
|
+ if (parse_fetch_string(handle, info, &str, ';', 1) < 0)
|
||||||
|
goto err;
|
||||||
|
if (semanage_user_extra_set_prefix(handle, user_extra, str) < 0)
|
||||||
|
goto err;
|
||||||
|
--
|
||||||
|
2.36.0
|
||||||
|
|
135
0008-libsemanage-Fall-back-to-semanage_copy_dir-when-rena.patch
Normal file
135
0008-libsemanage-Fall-back-to-semanage_copy_dir-when-rena.patch
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
From b05fd4edd27fae3d00cc31e9d24910ef4925f8c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
Date: Thu, 24 Mar 2022 13:00:34 +0100
|
||||||
|
Subject: [PATCH] libsemanage: Fall back to semanage_copy_dir when rename()
|
||||||
|
fails
|
||||||
|
Content-type: text/plain
|
||||||
|
|
||||||
|
In some circumstances, like semanage-store being on overlayfs, rename()
|
||||||
|
could fail with EXDEV - Invalid cross-device link. This is due to the
|
||||||
|
fact that overlays doesn't support rename() if source and target are not
|
||||||
|
on the same layer, e.g. in containers built from several layers. Even
|
||||||
|
though it's not atomic operation, it's better to try to copy files from
|
||||||
|
src to dst on our own in this case. Next rebuild will probably not fail
|
||||||
|
as the new directories will be on the same layer.
|
||||||
|
|
||||||
|
Fixes: https://github.com/SELinuxProject/selinux/issues/343
|
||||||
|
|
||||||
|
Reproducer:
|
||||||
|
|
||||||
|
$ cd selinux1
|
||||||
|
|
||||||
|
$ cat Dockerfile
|
||||||
|
FROM fedora:35
|
||||||
|
RUN dnf install -y selinux-policy selinux-policy-targeted
|
||||||
|
|
||||||
|
$ podman build -t localhost/selinux . --no-cache
|
||||||
|
|
||||||
|
$ cd ../selinux2
|
||||||
|
|
||||||
|
$ cat Dockerfile
|
||||||
|
FROM localhost/selinux
|
||||||
|
RUN semodule -B
|
||||||
|
|
||||||
|
$ podman build -t localhost/selinux2 . --no-cache
|
||||||
|
STEP 2/2: RUN semodule -B
|
||||||
|
libsemanage.semanage_commit_sandbox: Error while renaming /var/lib/selinux/targeted/active to /var/lib/selinux/targeted/previous. (Invalid cross-device link).
|
||||||
|
semodule: Failed!
|
||||||
|
Error: error building at STEP "RUN semodule -B": error while running runtime: exit status 1
|
||||||
|
|
||||||
|
With the fix:
|
||||||
|
|
||||||
|
$ podman build -t localhost/selinux2 . --no-cache
|
||||||
|
STEP 2/2: RUN semodule -B
|
||||||
|
libsemanage.semanage_rename: Warning: rename(/var/lib/selinux/targeted/active, /var/lib/selinux/targeted/previous) failed: Invalid cross-device link, fall back to non-atomic semanage_copy_dir_flags()
|
||||||
|
|
||||||
|
COMMIT localhost/selinux2
|
||||||
|
--> d2cfcebc1a1
|
||||||
|
Successfully tagged localhost/selinux2:latest
|
||||||
|
d2cfcebc1a1b34f1c2cd661ac18292b0612c3e5fa71d6fa1441be244da91b1af
|
||||||
|
|
||||||
|
Reported-by: Joseph Marrero Corchado <jmarrero@redhat.com>
|
||||||
|
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||||
|
---
|
||||||
|
libsemanage/src/semanage_store.c | 30 ++++++++++++++++++++++++------
|
||||||
|
1 file changed, 24 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
|
||||||
|
index 767f05cb2853..c6d2c5e72709 100644
|
||||||
|
--- a/libsemanage/src/semanage_store.c
|
||||||
|
+++ b/libsemanage/src/semanage_store.c
|
||||||
|
@@ -697,6 +697,10 @@ int semanage_store_access_check(void)
|
||||||
|
|
||||||
|
/********************* other I/O functions *********************/
|
||||||
|
|
||||||
|
+static int semanage_rename(semanage_handle_t * sh, const char *tmp, const char *dst);
|
||||||
|
+int semanage_remove_directory(const char *path);
|
||||||
|
+static int semanage_copy_dir_flags(const char *src, const char *dst, int flag);
|
||||||
|
+
|
||||||
|
/* Callback used by scandir() to select files. */
|
||||||
|
static int semanage_filename_select(const struct dirent *d)
|
||||||
|
{
|
||||||
|
@@ -768,7 +772,21 @@ out:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int semanage_copy_dir_flags(const char *src, const char *dst, int flag);
|
||||||
|
+static int semanage_rename(semanage_handle_t * sh, const char *src, const char *dst) {
|
||||||
|
+ int retval;
|
||||||
|
+
|
||||||
|
+ retval = rename(src, dst);
|
||||||
|
+ if (retval == 0 || errno != EXDEV)
|
||||||
|
+ return retval;
|
||||||
|
+
|
||||||
|
+ /* we can't use rename() due to filesystem limitation, lets try to copy files manually */
|
||||||
|
+ WARN(sh, "WARNING: rename(%s, %s) failed: %s, fall back to non-atomic semanage_copy_dir_flags()",
|
||||||
|
+ src, dst, strerror(errno));
|
||||||
|
+ if (semanage_copy_dir_flags(src, dst, 1) == -1) {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return semanage_remove_directory(src);
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* Copies all of the files from src to dst, recursing into
|
||||||
|
* subdirectories. Returns 0 on success, -1 on error. */
|
||||||
|
@@ -1770,7 +1788,7 @@ static int semanage_commit_sandbox(semanage_handle_t * sh)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (rename(active, backup) == -1) {
|
||||||
|
+ if (semanage_rename(sh, active, backup) == -1) {
|
||||||
|
ERR(sh, "Error while renaming %s to %s.", active, backup);
|
||||||
|
retval = -1;
|
||||||
|
goto cleanup;
|
||||||
|
@@ -1779,12 +1797,12 @@ static int semanage_commit_sandbox(semanage_handle_t * sh)
|
||||||
|
/* clean up some files from the sandbox before install */
|
||||||
|
/* remove homedir_template from sandbox */
|
||||||
|
|
||||||
|
- if (rename(sandbox, active) == -1) {
|
||||||
|
+ if (semanage_rename(sh, sandbox, active) == -1) {
|
||||||
|
ERR(sh, "Error while renaming %s to %s.", sandbox, active);
|
||||||
|
/* note that if an error occurs during the next
|
||||||
|
* function then the store will be left in an
|
||||||
|
* inconsistent state */
|
||||||
|
- if (rename(backup, active) < 0)
|
||||||
|
+ if (semanage_rename(sh, backup, active) < 0)
|
||||||
|
ERR(sh, "Error while renaming %s back to %s.", backup,
|
||||||
|
active);
|
||||||
|
retval = -1;
|
||||||
|
@@ -1795,10 +1813,10 @@ static int semanage_commit_sandbox(semanage_handle_t * sh)
|
||||||
|
* function then the store will be left in an
|
||||||
|
* inconsistent state */
|
||||||
|
int errsv = errno;
|
||||||
|
- if (rename(active, sandbox) < 0)
|
||||||
|
+ if (semanage_rename(sh, active, sandbox) < 0)
|
||||||
|
ERR(sh, "Error while renaming %s back to %s.", active,
|
||||||
|
sandbox);
|
||||||
|
- else if (rename(backup, active) < 0)
|
||||||
|
+ else if (semanage_rename(sh, backup, active) < 0)
|
||||||
|
ERR(sh, "Error while renaming %s back to %s.", backup,
|
||||||
|
active);
|
||||||
|
else
|
||||||
|
--
|
||||||
|
2.36.0
|
||||||
|
|
@ -4,10 +4,10 @@
|
|||||||
Summary: SELinux binary policy manipulation library
|
Summary: SELinux binary policy manipulation library
|
||||||
Name: libsemanage
|
Name: libsemanage
|
||||||
Version: 3.3
|
Version: 3.3
|
||||||
Release: 2%{?dist}
|
Release: 3%{?dist}
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
Source0: https://github.com/SELinuxProject/selinux/releases/download/3.3/libsemanage-3.3.tar.gz
|
Source0: https://github.com/SELinuxProject/selinux/releases/download/3.3/libsemanage-3.3.tar.gz
|
||||||
# fedora-selinux/selinux: git format-patch -N 3.3 -- libsemanage
|
# fedora-selinux/selinux: git checkout c9s; git format-patch -N 3.3 -- libsemanage
|
||||||
# i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done
|
# i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done
|
||||||
# Patch list start
|
# Patch list start
|
||||||
Patch0001: 0001-libsemanage-Fix-RESOURCE_LEAK-and-USE_AFTER_FREE-cov.patch
|
Patch0001: 0001-libsemanage-Fix-RESOURCE_LEAK-and-USE_AFTER_FREE-cov.patch
|
||||||
@ -16,6 +16,8 @@ Patch0003: 0003-semodule-libsemanage-move-module-hashing-into-libsem.patch
|
|||||||
Patch0004: 0004-libsemanage-move-compressed-file-handling-into-a-sep.patch
|
Patch0004: 0004-libsemanage-move-compressed-file-handling-into-a-sep.patch
|
||||||
Patch0005: 0005-libsemanage-clean-up-semanage_direct_commit-a-bit.patch
|
Patch0005: 0005-libsemanage-clean-up-semanage_direct_commit-a-bit.patch
|
||||||
Patch0006: 0006-libsemanage-optionally-rebuild-policy-when-modules-a.patch
|
Patch0006: 0006-libsemanage-optionally-rebuild-policy-when-modules-a.patch
|
||||||
|
Patch0007: 0007-libsemanage-allow-spaces-in-user-group-names.patch
|
||||||
|
Patch0008: 0008-libsemanage-Fall-back-to-semanage_copy_dir-when-rena.patch
|
||||||
# Patch list end
|
# Patch list end
|
||||||
URL: https://github.com/SELinuxProject/selinux/wiki
|
URL: https://github.com/SELinuxProject/selinux/wiki
|
||||||
Source1: semanage.conf
|
Source1: semanage.conf
|
||||||
@ -159,6 +161,10 @@ cp %{SOURCE1} ${RPM_BUILD_ROOT}%{_sysconfdir}/selinux/semanage.conf
|
|||||||
%{_libexecdir}/selinux/semanage_migrate_store
|
%{_libexecdir}/selinux/semanage_migrate_store
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Apr 27 2022 Petr Lautrbach <plautrba@redhat.com> - 3.3-3
|
||||||
|
- allow spaces in user/group names (#2049665)
|
||||||
|
- Fall back to semanage_copy_dir when rename() fails (#2068085)
|
||||||
|
|
||||||
* Tue Feb 15 2022 Petr Lautrbach <plautrba@redhat.com> - 3.3-2
|
* Tue Feb 15 2022 Petr Lautrbach <plautrba@redhat.com> - 3.3-2
|
||||||
- optionally rebuild policy when modules are changed externally
|
- optionally rebuild policy when modules are changed externally
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user