!40 [sync] PR-38: backport upstream patches

From: @openeuler-sync-bot 
Reviewed-by: @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
This commit is contained in:
openeuler-ci-bot 2023-06-13 12:34:01 +00:00 committed by Gitee
commit 4d1498e842
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
13 changed files with 1078 additions and 1 deletions

View File

@ -0,0 +1,50 @@
From 2f71384f233aa544cf0cf50be7e83c7762ad1c15 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Mon, 31 Oct 2022 17:46:17 +0100
Subject: [PATCH] libselinux: Ignore missing directories when -i is used
Currently "-i" only ignores a file whose parent directory exists. Start also
ignoring paths with missing components.
Fixes:
# restorecon -i -v -R /var/log/missingdir/missingfile; echo $?
255
restorecon: SELinux: Could not get canonical path for /var/log/missingdir/missingfile restorecon: No such file or directory.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference:https://github.com/SELinuxProject/selinux/commit/2f71384f233aa544cf0cf50be7e83c7762ad1c15
Confilct: modify state.flags. to flags.
---
libselinux/src/selinux_restorecon.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/selinux_restorecon.c b/src/selinux_restorecon.c
index 2d24559f..6b5f6921 100644
--- a/src/selinux_restorecon.c
+++ b/src/selinux_restorecon.c
@@ -1108,6 +1108,10 @@ static int selinux_restorecon_common(const char *pathname_orig,
pathname = realpath(pathname_orig, NULL);
if (!pathname) {
free(basename_cpy);
+ /* missing parent directory */
+ if (flags.ignore_noent && errno == ENOENT) {
+ return 0;
+ }
goto realpatherr;
}
} else {
@@ -1121,6 +1125,9 @@ static int selinux_restorecon_common(const char *pathname_orig,
free(dirname_cpy);
if (!pathdnamer) {
free(basename_cpy);
+ if (flags.ignore_noent && errno == ENOENT) {
+ return 0;
+ }
goto realpatherr;
}
if (!strcmp(pathdnamer, "/"))
--
2.27.0

View File

@ -0,0 +1,40 @@
From 4c47f92758df0ad266e8306bbec7b2798a4be3ea Mon Sep 17 00:00:00 2001
From: Jie Lu <lujie54@huawei.com>
Date: Tue, 29 Nov 2022 20:00:20 +0800
Subject: [PATCH] libselinux:add check for malloc
Add return check for regex_data_create() to avoid NULL reference of regex_data
(gdb) bt
#0 0x00007fbde5caec14 in pthread_mutex_init () from /usr/lib64/libc.so.6
#1 0x00007fbde5e3a489 in regex_data_create () at regex.c:260
#2 0x00007fbde5e3a4af in regex_prepare_data (regex=regex@entry=0x7fbde4613770, pattern_string=pattern_string@entry=0x563c6799a820 "^/home$", errordata=errordata@entry=0x7ffeb83fa950) at regex.c:76
#3 0x00007fbde5e32fe6 in compile_regex (errbuf=0x0, spec=0x7fbde4613748) at label_file.h:407
#4 lookup_all (key=0x563c679974e5 "/var/log/kadmind.log", type=<optimized out>, partial=partial@entry=false, match_count=match_count@entry=0x0, rec=<optimized out>, rec=<optimized out>)
at label_file.c:949
#5 0x00007fbde5e33350 in lookup (rec=<optimized out>, key=<optimized out>, type=<optimized out>) at label_file.c:1092
#6 0x00007fbde5e31878 in selabel_lookup_common (rec=0x563c67998cc0, translating=1, key=<optimized out>, type=<optimized out>) at label.c:167
Signed-off-by: Jie Lu <lujie54@huawei.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libselinux/src/regex.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/regex.c b/src/regex.c
index 73987d9f..149a7973 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -257,6 +257,9 @@ struct regex_data *regex_data_create(void)
{
struct regex_data *regex_data =
(struct regex_data *)calloc(1, sizeof(struct regex_data));
+ if (!regex_data)
+ return NULL;
+
__pthread_mutex_init(&regex_data->match_mutex, NULL);
return regex_data;
}
--
2.27.0

View File

@ -0,0 +1,124 @@
From d97c34efa5b95d8ec7c0445aa4f87eacf980bab6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 10 Nov 2022 19:23:42 +0100
Subject: [PATCH] libselinux: bail out on path truncations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bail out if computed paths based on user input are being truncated, to
avoid wrong files to be opened.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libselinux/src/booleans.c | 9 +++------
libselinux/src/get_initial_context.c | 8 ++++++--
libselinux/src/stringrep.c | 15 ++++++++++++---
3 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/booleans.c b/src/booleans.c
index ef1f64a0..dbcccd70 100644
--- a/src/booleans.c
+++ b/src/booleans.c
@@ -7,7 +7,6 @@
#ifndef DISABLE_BOOL
-#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -147,7 +146,7 @@ out:
static int bool_open(const char *name, int flag) {
char *fname = NULL;
char *alt_name = NULL;
- int len;
+ size_t len;
int fd = -1;
int ret;
char *ptr;
@@ -164,9 +163,8 @@ static int bool_open(const char *name, int flag) {
return -1;
ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name);
- if (ret < 0)
+ if (ret < 0 || (size_t)ret >= len)
goto out;
- assert(ret < len);
fd = open(fname, flag);
if (fd >= 0 || errno != ENOENT)
@@ -184,9 +182,8 @@ static int bool_open(const char *name, int flag) {
fname = ptr;
ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, alt_name);
- if (ret < 0)
+ if (ret < 0 || (size_t)ret >= len)
goto out;
- assert(ret < len);
fd = open(fname, flag);
out:
diff --git a/src/get_initial_context.c b/src/get_initial_context.c
index 97ae3dcf..87c8adfa 100644
--- a/src/get_initial_context.c
+++ b/src/get_initial_context.c
@@ -23,8 +23,12 @@ int security_get_initial_context_raw(const char * name, char ** con)
return -1;
}
- snprintf(path, sizeof path, "%s%s%s",
- selinux_mnt, SELINUX_INITCON_DIR, name);
+ ret = snprintf(path, sizeof path, "%s%s%s", selinux_mnt, SELINUX_INITCON_DIR, name);
+ if (ret < 0 || (size_t)ret >= sizeof path) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return -1;
diff --git a/src/stringrep.c b/src/stringrep.c
index 592410e5..d2237d1c 100644
--- a/src/stringrep.c
+++ b/src/stringrep.c
@@ -82,7 +82,10 @@ static struct discover_class_node * discover_class(const char *s)
goto err2;
/* load up class index */
- snprintf(path, sizeof path, "%s/class/%s/index", selinux_mnt,s);
+ ret = snprintf(path, sizeof path, "%s/class/%s/index", selinux_mnt,s);
+ if (ret < 0 || (size_t)ret >= sizeof path)
+ goto err3;
+
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
goto err3;
@@ -97,7 +100,10 @@ static struct discover_class_node * discover_class(const char *s)
goto err3;
/* load up permission indices */
- snprintf(path, sizeof path, "%s/class/%s/perms",selinux_mnt,s);
+ ret = snprintf(path, sizeof path, "%s/class/%s/perms",selinux_mnt,s);
+ if (ret < 0 || (size_t)ret >= sizeof path)
+ goto err3;
+
dir = opendir(path);
if (dir == NULL)
goto err3;
@@ -107,7 +113,10 @@ static struct discover_class_node * discover_class(const char *s)
unsigned int value;
struct stat m;
- snprintf(path, sizeof path, "%s/class/%s/perms/%s", selinux_mnt,s,dentry->d_name);
+ ret = snprintf(path, sizeof path, "%s/class/%s/perms/%s", selinux_mnt,s,dentry->d_name);
+ if (ret < 0 || (size_t)ret >= sizeof path)
+ goto err4;
+
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
goto err4;
--
2.27.0

View File

@ -0,0 +1,77 @@
From e17619792fa1e342c7f0a819077129adff438cd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Wed, 13 Apr 2022 17:56:33 +0200
Subject: [PATCH] libselinux: correctly hash specfiles larger than 4G
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The internal Sha1Update() functions only handles buffers up to a size of
UINT32_MAX, due to its usage of the type uint32_t. This causes issues
when processing more than UINT32_MAX bytes, e.g. with a specfile larger
than 4G. 0aa974a4 ("libselinux: limit has buffer size") tried to
address this issue, but failed since the overflow check
if (digest->hashbuf_size + buf_len < digest->hashbuf_size) {
will be done in the widest common type, which is size_t, the type of
`buf_len`.
Revert the type of `hashbuf_size` to size_t and instead process the data
in blocks of supported size.
Acked-by: James Carter <jwcart2@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reverts: 0aa974a4 ("libselinux: limit has buffer size")
---
libselinux/src/label_internal.h | 2 +-
libselinux/src/label_support.c | 14 +++++++++++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/label_internal.h b/src/label_internal.h
index 82a762f7..782c6aa8 100644
--- a/src/label_internal.h
+++ b/src/label_internal.h
@@ -57,7 +57,7 @@ int selabel_service_init(struct selabel_handle *rec,
struct selabel_digest {
unsigned char *digest; /* SHA1 digest of specfiles */
unsigned char *hashbuf; /* buffer to hold specfiles */
- uint32_t hashbuf_size; /* buffer size */
+ size_t hashbuf_size; /* buffer size */
size_t specfile_cnt; /* how many specfiles processed */
char **specfile_list; /* and their names */
};
diff --git a/src/label_support.c b/src/label_support.c
index 94ed6e42..54fd49a5 100644
--- a/src/label_support.c
+++ b/src/label_support.c
@@ -116,13 +116,25 @@ int read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...)
void digest_gen_hash(struct selabel_digest *digest)
{
Sha1Context context;
+ size_t remaining_size;
+ const unsigned char *ptr;
/* If SELABEL_OPT_DIGEST not set then just return */
if (!digest)
return;
Sha1Initialise(&context);
- Sha1Update(&context, digest->hashbuf, digest->hashbuf_size);
+
+ /* Process in blocks of UINT32_MAX bytes */
+ remaining_size = digest->hashbuf_size;
+ ptr = digest->hashbuf;
+ while (remaining_size > UINT32_MAX) {
+ Sha1Update(&context, ptr, UINT32_MAX);
+ remaining_size -= UINT32_MAX;
+ ptr += UINT32_MAX;
+ }
+ Sha1Update(&context, ptr, remaining_size);
+
Sha1Finalise(&context, (SHA1_HASH *)digest->digest);
free(digest->hashbuf);
digest->hashbuf = NULL;
--
2.27.0

View File

@ -0,0 +1,322 @@
From c8ba7968b3abb1e17edd400bb795d5e452b57935 Mon Sep 17 00:00:00 2001
From: Nicolas Iooss <nicolas.iooss@m4x.org>
Date: Sun, 29 May 2022 20:01:11 +0200
Subject: [PATCH] libselinux: do not return the cached prev_current value when
using getpidcon()
libselinux implements a cache mechanism for get*con() functions, such
that when a thread calls setcon(...) then getcon(...), the context is
directly returned. Unfortunately, getpidcon(pid, &context) uses the same
cached variable, so when a program uses setcon("something"), all later
calls to getpidcon(pid, ...) returns "something". This is a bug.
Here is a program which illustrates this bug:
#include <stdio.h>
#include <selinux/selinux.h>
int main() {
char *context = "";
if (getpidcon(1, &context) < 0) {
perror("getpidcon(1)");
}
printf("getpidcon(1) = %s\n", context);
if (getcon(&context) < 0) {
perror("getcon()");
}
printf("getcon() = %s\n", context);
if (setcon(context) < 0) {
perror("setcon()");
}
if (getpidcon(1, &context) < 0) {
perror("getpidcon(1)");
}
printf("getpidcon(1) = %s\n", context);
return 0;
}
On an Arch Linux system using unconfined user, this program displays:
getpidcon(1) = system_u:system_r:init_t
getcon() = unconfined_u:unconfined_r:unconfined_t
getpidcon(1) = unconfined_u:unconfined_r:unconfined_t
With this commit, this program displays:
getpidcon(1) = system_u:system_r:init_t
getcon() = unconfined_u:unconfined_r:unconfined_t
getpidcon(1) = system_u:system_r:init_t
This bug was present in the first commit of
https://github.com/SELinuxProject/selinux git history. It was reported
in https://lore.kernel.org/selinux/20220121084012.GS7643@suse.com/ and a
patch to fix it was sent in
https://patchwork.kernel.org/project/selinux/patch/20220127130741.31940-1-jsegitz@suse.de/
without a clear explanation. This patch added pid checks, which made
sense but were difficult to read. Instead, it is possible to change the
way the functions are called so that they directly know which cache
variable to use.
Moreover, as the code is not clear at all (I spent too much time trying
to understand what the switch did and what the thread-local variable
contained), this commit also reworks libselinux/src/procattr.c to:
- not use hard-to-understand switch/case constructions on strings (they
are replaced by a new argument filled by macros)
- remove getpidattr_def macro (it was only used once, for pidcon, and
the code is clearer with one less macro)
- remove the pid parameter of setprocattrcon() and setprocattrcon_raw()
(it is always zero)
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Cc: Johannes Segitz <jsegitz@suse.de>
---
libselinux/src/procattr.c | 147 +++++++++++++-------------------------
1 file changed, 50 insertions(+), 97 deletions(-)
diff --git a/src/procattr.c b/src/procattr.c
index 142fbf3a..6f4cfb82 100644
--- a/src/procattr.c
+++ b/src/procattr.c
@@ -11,11 +11,14 @@
#define UNSET (char *) -1
+/* Cached values so that when a thread calls set*con() then gen*con(), the value
+ * which was set is directly returned.
+ */
static __thread char *prev_current = UNSET;
-static __thread char * prev_exec = UNSET;
-static __thread char * prev_fscreate = UNSET;
-static __thread char * prev_keycreate = UNSET;
-static __thread char * prev_sockcreate = UNSET;
+static __thread char *prev_exec = UNSET;
+static __thread char *prev_fscreate = UNSET;
+static __thread char *prev_keycreate = UNSET;
+static __thread char *prev_sockcreate = UNSET;
static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t destructor_key;
@@ -111,43 +114,18 @@ out:
return fd;
}
-static int getprocattrcon_raw(char ** context,
- pid_t pid, const char *attr)
+static int getprocattrcon_raw(char **context, pid_t pid, const char *attr,
+ const char *prev_context)
{
char *buf;
size_t size;
int fd;
ssize_t ret;
int errno_hold;
- char * prev_context;
__selinux_once(once, init_procattr);
init_thread_destructor();
- switch (attr[0]) {
- case 'c':
- prev_context = prev_current;
- break;
- case 'e':
- prev_context = prev_exec;
- break;
- case 'f':
- prev_context = prev_fscreate;
- break;
- case 'k':
- prev_context = prev_keycreate;
- break;
- case 's':
- prev_context = prev_sockcreate;
- break;
- case 'p':
- prev_context = NULL;
- break;
- default:
- errno = ENOENT;
- return -1;
- }
-
if (prev_context && prev_context != UNSET) {
*context = strdup(prev_context);
if (!(*context)) {
@@ -194,13 +172,13 @@ static int getprocattrcon_raw(char ** context,
return ret;
}
-static int getprocattrcon(char ** context,
- pid_t pid, const char *attr)
+static int getprocattrcon(char **context, pid_t pid, const char *attr,
+ const char *prev_context)
{
int ret;
char * rcontext;
- ret = getprocattrcon_raw(&rcontext, pid, attr);
+ ret = getprocattrcon_raw(&rcontext, pid, attr, prev_context);
if (!ret) {
ret = selinux_raw_to_trans_context(rcontext, context);
@@ -210,45 +188,24 @@ static int getprocattrcon(char ** context,
return ret;
}
-static int setprocattrcon_raw(const char * context,
- pid_t pid, const char *attr)
+static int setprocattrcon_raw(const char *context, const char *attr,
+ char **prev_context)
{
int fd;
ssize_t ret;
int errno_hold;
- char **prev_context, *context2 = NULL;
+ char *context2 = NULL;
__selinux_once(once, init_procattr);
init_thread_destructor();
- switch (attr[0]) {
- case 'c':
- prev_context = &prev_current;
- break;
- case 'e':
- prev_context = &prev_exec;
- break;
- case 'f':
- prev_context = &prev_fscreate;
- break;
- case 'k':
- prev_context = &prev_keycreate;
- break;
- case 's':
- prev_context = &prev_sockcreate;
- break;
- default:
- errno = ENOENT;
- return -1;
- }
-
if (!context && !*prev_context)
return 0;
if (context && *prev_context && *prev_context != UNSET
&& !strcmp(context, *prev_context))
return 0;
- fd = openattr(pid, attr, O_RDWR | O_CLOEXEC);
+ fd = openattr(0, attr, O_RDWR | O_CLOEXEC);
if (fd < 0)
return -1;
if (context) {
@@ -279,8 +236,8 @@ out:
}
}
-static int setprocattrcon(const char * context,
- pid_t pid, const char *attr)
+static int setprocattrcon(const char *context, const char *attr,
+ char **prev_context)
{
int ret;
char * rcontext;
@@ -288,62 +245,58 @@ static int setprocattrcon(const char * context,
if (selinux_trans_to_raw_context(context, &rcontext))
return -1;
- ret = setprocattrcon_raw(rcontext, pid, attr);
+ ret = setprocattrcon_raw(rcontext, attr, prev_context);
freecon(rcontext);
return ret;
}
-#define getselfattr_def(fn, attr) \
+#define getselfattr_def(fn, attr, prev_context) \
int get##fn##_raw(char **c) \
{ \
- return getprocattrcon_raw(c, 0, #attr); \
+ return getprocattrcon_raw(c, 0, attr, prev_context); \
} \
int get##fn(char **c) \
{ \
- return getprocattrcon(c, 0, #attr); \
+ return getprocattrcon(c, 0, attr, prev_context); \
}
-#define setselfattr_def(fn, attr) \
+#define setselfattr_def(fn, attr, prev_context) \
int set##fn##_raw(const char * c) \
{ \
- return setprocattrcon_raw(c, 0, #attr); \
+ return setprocattrcon_raw(c, attr, &prev_context); \
} \
int set##fn(const char * c) \
{ \
- return setprocattrcon(c, 0, #attr); \
+ return setprocattrcon(c, attr, &prev_context); \
}
-#define all_selfattr_def(fn, attr) \
- getselfattr_def(fn, attr) \
- setselfattr_def(fn, attr)
+#define all_selfattr_def(fn, attr, prev_context) \
+ getselfattr_def(fn, attr, prev_context) \
+ setselfattr_def(fn, attr, prev_context)
-#define getpidattr_def(fn, attr) \
- int get##fn##_raw(pid_t pid, char **c) \
- { \
- if (pid <= 0) { \
- errno = EINVAL; \
- return -1; \
- } else { \
- return getprocattrcon_raw(c, pid, #attr); \
- } \
- } \
- int get##fn(pid_t pid, char **c) \
- { \
- if (pid <= 0) { \
- errno = EINVAL; \
- return -1; \
- } else { \
- return getprocattrcon(c, pid, #attr); \
- } \
- }
+all_selfattr_def(con, "current", prev_current)
+ getselfattr_def(prevcon, "prev", NULL)
+ all_selfattr_def(execcon, "exec", prev_exec)
+ all_selfattr_def(fscreatecon, "fscreate", prev_fscreate)
+ all_selfattr_def(sockcreatecon, "sockcreate", prev_sockcreate)
+ all_selfattr_def(keycreatecon, "keycreate", prev_keycreate)
-all_selfattr_def(con, current)
- getpidattr_def(pidcon, current)
- getselfattr_def(prevcon, prev)
- all_selfattr_def(execcon, exec)
- all_selfattr_def(fscreatecon, fscreate)
- all_selfattr_def(sockcreatecon, sockcreate)
- all_selfattr_def(keycreatecon, keycreate)
+int getpidcon_raw(pid_t pid, char **c)
+{
+ if (pid <= 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ return getprocattrcon_raw(c, pid, "current", NULL);
+}
+int getpidcon(pid_t pid, char **c)
+{
+ if (pid <= 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ return getprocattrcon(c, pid, "current", NULL);
+}
--
2.27.0

View File

@ -0,0 +1,63 @@
From d31280c26e066d68c3061fc24f5951829f641e81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 14 Nov 2022 20:32:08 +0100
Subject: [PATCH] libselinux: filter arguments with path separators
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Boolean names, taken by security_get_boolean_pending(3),
security_get_boolean_active(3) and security_set_boolean(3), as well as
user names, taken by security_get_initial_context(3), are used in path
constructions. Ensure they do not contain path separators to avoid
unwanted path traversal.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libselinux/src/booleans.c | 5 +++--
libselinux/src/get_initial_context.c | 5 +++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/booleans.c b/src/booleans.c
index dbcccd70..e34b39ff 100644
--- a/src/booleans.c
+++ b/src/booleans.c
@@ -131,7 +131,8 @@ char *selinux_boolean_sub(const char *name)
ptr++;
*ptr = '\0';
- sub = strdup(dst);
+ if (!strchr(dst, '/'))
+ sub = strdup(dst);
break;
}
@@ -151,7 +152,7 @@ static int bool_open(const char *name, int flag) {
int ret;
char *ptr;
- if (!name) {
+ if (!name || strchr(name, '/')) {
errno = EINVAL;
return -1;
}
diff --git a/src/get_initial_context.c b/src/get_initial_context.c
index 87c8adfa..0f25ba3f 100644
--- a/src/get_initial_context.c
+++ b/src/get_initial_context.c
@@ -23,6 +23,11 @@ int security_get_initial_context_raw(const char * name, char ** con)
return -1;
}
+ if (strchr(name, '/')) {
+ errno = EINVAL;
+ return -1;
+ }
+
ret = snprintf(path, sizeof path, "%s%s%s", selinux_mnt, SELINUX_INITCON_DIR, name);
if (ret < 0 || (size_t)ret >= sizeof path) {
errno = EOVERFLOW;
--
2.27.0

View File

@ -0,0 +1,94 @@
From 42f7f2fdcf1a38b6018933132ea6a35dc41bdeff Mon Sep 17 00:00:00 2001
From: Jie Lu <lujie54@huawei.com>
Date: Tue, 15 Nov 2022 19:55:36 +0800
Subject: [PATCH] libselinux: fix memory leaks on the audit2why module init
Signed-off-by: Jie Lu <lujie54@huawei.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libselinux/src/audit2why.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/src/audit2why.c b/src/audit2why.c
index 44a9a341..ba1a66eb 100644
--- a/src/audit2why.c
+++ b/src/audit2why.c
@@ -191,7 +191,7 @@ static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args)
static int __policy_init(const char *init_path)
{
- FILE *fp;
+ FILE *fp = NULL;
const char *curpolicy;
char errormsg[PATH_MAX+1024+20];
struct sepol_policy_file *pf = NULL;
@@ -235,18 +235,17 @@ static int __policy_init(const char *init_path)
snprintf(errormsg, sizeof(errormsg),
"policydb_init failed: %m\n");
PyErr_SetString( PyExc_RuntimeError, errormsg);
- fclose(fp);
- return 1;
+ goto err;
}
sepol_policy_file_set_fp(pf, fp);
if (sepol_policydb_read(avc->policydb, pf)) {
snprintf(errormsg, sizeof(errormsg),
"invalid binary policy %s\n", curpolicy);
PyErr_SetString( PyExc_ValueError, errormsg);
- fclose(fp);
- return 1;
+ goto err;
}
fclose(fp);
+ fp = NULL;
sepol_set_policydb(&avc->policydb->p);
avc->handle = sepol_handle_create();
/* Turn off messages */
@@ -256,13 +255,13 @@ static int __policy_init(const char *init_path)
avc->policydb, &cnt);
if (rc < 0) {
PyErr_SetString( PyExc_RuntimeError, "unable to get bool count\n");
- return 1;
+ goto err;
}
boollist = calloc(cnt, sizeof(*boollist));
if (!boollist) {
PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
- return 1;
+ goto err;
}
sepol_bool_iterate(avc->handle, avc->policydb,
@@ -273,11 +272,26 @@ static int __policy_init(const char *init_path)
rc = sepol_sidtab_init(&sidtab);
if (rc < 0) {
PyErr_SetString( PyExc_RuntimeError, "unable to init sidtab\n");
- free(boollist);
- return 1;
+ goto err;
}
sepol_set_sidtab(&sidtab);
return 0;
+
+err:
+ if (boollist)
+ free(boollist);
+ if (avc){
+ if (avc->handle)
+ sepol_handle_destroy(avc->handle);
+ if (avc->policydb)
+ sepol_policydb_free(avc->policydb);
+ free(avc);
+ }
+ if (pf)
+ sepol_policy_file_free(pf);
+ if (fp)
+ fclose(fp);
+ return 1;
}
static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) {
--
2.27.0

View File

@ -0,0 +1,54 @@
From 001af27a6d32e5b3d1f7410f0007687d7e3c07f5 Mon Sep 17 00:00:00 2001
From: Jie Lu <lujie54@huawei.com>
Date: Tue, 22 Nov 2022 13:21:10 +0800
Subject: [PATCH] libselinux: fix some memory issues in db_init
1. check the return of strdup to avoid a potential NULL reference.
2. make sure line_buf is freed.
Signed-off-by: Jie Lu <lujie54@huawei.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libselinux/src/label_db.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/label_db.c b/src/label_db.c
index 94c05c6d..bd73201c 100644
--- a/src/label_db.c
+++ b/src/label_db.c
@@ -293,6 +293,11 @@ db_init(const struct selinux_opt *opts, unsigned nopts,
return NULL;
}
rec->spec_file = strdup(path);
+ if (!rec->spec_file) {
+ free(catalog);
+ fclose(filp);
+ return NULL;
+ }
/*
* Parse for each lines
@@ -322,18 +327,19 @@ db_init(const struct selinux_opt *opts, unsigned nopts,
if (process_line(path, line_buf, ++line_num, catalog) < 0)
goto out_error;
}
- free(line_buf);
if (digest_add_specfile(rec->digest, filp, NULL, sb.st_size, path) < 0)
goto out_error;
digest_gen_hash(rec->digest);
+ free(line_buf);
fclose(filp);
return catalog;
out_error:
+ free(line_buf);
for (i = 0; i < catalog->nspec; i++) {
spec_t *spec = &catalog->specs[i];
--
2.27.0

View File

@ -0,0 +1,43 @@
From f56a72ac9e86ddfbefedc41080f33fb06639f96b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thi=C3=A9baud=20Weksteen?= <tweek@google.com>
Date: Mon, 24 Oct 2022 20:13:54 +1100
Subject: [PATCH] libselinux: ignore invalid class name lookup
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
selinux_check_access relies on string_to_security_class to resolve the
class index from its char* argument. There is no input validation done
on the string provided. It is possible to supply an argument containing
trailing backslashes (i.e., "sock_file//////") so that the paths built
in discover_class get truncated. The processing will then reference the
same permission file multiple time (e.g., perms/watch_reads will be
truncated to perms/watch). This will leak the memory allocated when
strdup'ing the permission name. The discover_class_cache will end up in
an invalid state (but not corrupted).
Ensure that the class provided does not contain any path separator.
Signed-off-by: Thiébaud Weksteen <tweek@google.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libselinux/src/stringrep.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/stringrep.c b/src/stringrep.c
index 2fe69f43..592410e5 100644
--- a/src/stringrep.c
+++ b/src/stringrep.c
@@ -63,6 +63,9 @@ static struct discover_class_node * discover_class(const char *s)
return NULL;
}
+ if (strchr(s, '/') != NULL)
+ return NULL;
+
/* allocate a node */
node = malloc(sizeof(struct discover_class_node));
if (node == NULL)
--
2.27.0

View File

@ -0,0 +1,41 @@
From 0aa974a439c60bd19e504d6a583cbae770de3701 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 8 Apr 2022 15:10:53 +0200
Subject: [PATCH] libselinux: limit has buffer size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The `struct selabel_digest` member `hashbuf_size` is used to compute
hashes via `Sha1Update()`, which takes uint32_t as length parameter
type. Use that same type for `hashbuf_size` to avoid potential value
truncations, as the overflow check in `digest_add_specfile()` on
`hashbuf_size` is based on it.
label_support.c: In function digest_gen_hash:
label_support.c:125:53: warning: conversion from size_t {aka long unsigned int} to uint32_t {aka unsigned int} may change value [-Wconversion]
125 | Sha1Update(&context, digest->hashbuf, digest->hashbuf_size);
| ~~~~~~^~~~~~~~~~~~~~
Acked-by: James Carter <jwcart2@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
libselinux/src/label_internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/label_internal.h b/src/label_internal.h
index 782c6aa8..82a762f7 100644
--- a/src/label_internal.h
+++ b/src/label_internal.h
@@ -57,7 +57,7 @@ int selabel_service_init(struct selabel_handle *rec,
struct selabel_digest {
unsigned char *digest; /* SHA1 digest of specfiles */
unsigned char *hashbuf; /* buffer to hold specfiles */
- size_t hashbuf_size; /* buffer size */
+ uint32_t hashbuf_size; /* buffer size */
size_t specfile_cnt; /* how many specfiles processed */
char **specfile_list; /* and their names */
};
--
2.27.0

View File

@ -0,0 +1,66 @@
From 1609b9fdfddc1f6baa1b38b57018b16af9c5471a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Wed, 1 Feb 2023 11:55:10 +0100
Subject: [PATCH] libselinux: restore: use fixed sized integer for hash index
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The hash mask is set to 2^16 - 1, which does not fit into a signed 16
bit integer. Use uint32_t to be on the safe side. Also use size_t for
counting in debug function.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Jason Zaman <jason@perfinion.com>
Reference:https://github.com/SELinuxProject/selinux/commit/1609b9fdfddc1f6baa1b38b57018b16af9c5471a
Conflict:context adapt
---
libselinux/src/selinux_restorecon.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/selinux_restorecon.c b/src/selinux_restorecon.c
index 40a759f0..7ef2d45d 100644
--- a/src/selinux_restorecon.c
+++ b/src/selinux_restorecon.c
@@ -429,7 +429,8 @@ static int filespec_add(ino_t ino, const char *con, const char *file,
struct rest_flags *flags)
{
file_spec_t *prevfl, *fl;
- int h, ret;
+ uint32_t h;
+ int ret;
struct stat64 sb;
if (!fl_head) {
@@ -524,7 +525,8 @@ unlock_1:
static void filespec_eval(void)
{
file_spec_t *fl;
- int h, used, nel, len, longest;
+ uint32_t h;
+ size_t used, nel, len, longest;
if (!fl_head)
return;
@@ -544,7 +546,7 @@ static void filespec_eval(void)
}
selinux_log(SELINUX_INFO,
- "filespec hash table stats: %d elements, %d/%d buckets used, longest chain length %d\n",
+ "filespec hash table stats: %zu elements, %zu/%zu buckets used, longest chain length %zu\n",
nel, used, HASH_BUCKETS, longest);
}
#else
@@ -559,7 +561,7 @@ static void filespec_eval(void)
static void filespec_destroy(void)
{
file_spec_t *fl, *tmp;
- int h;
+ uint32_t h;
if (!fl_head)
return;
--
2.27.0

View File

@ -0,0 +1,88 @@
From 31e3537624ad2d07271d4c02925ebc6cb942e0c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 10 May 2022 20:20:36 +0200
Subject: [PATCH] libselinux: simplify policy path logic to avoid uninitialized
read
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case the function __policy_init() gets called with a NULL pointer,
the stack variable path remains uninitialized (except at its last
index). If parsing the binary policy fails in sepol_policydb_read() the
error branch would access those uninitialized memory.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
libselinux/src/audit2why.c | 34 +++++++++++++---------------------
1 file changed, 13 insertions(+), 21 deletions(-)
diff --git a/src/audit2why.c b/src/audit2why.c
index ca38e13c..44a9a341 100644
--- a/src/audit2why.c
+++ b/src/audit2why.c
@@ -192,25 +192,16 @@ static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args)
static int __policy_init(const char *init_path)
{
FILE *fp;
- char path[PATH_MAX];
+ const char *curpolicy;
char errormsg[PATH_MAX+1024+20];
struct sepol_policy_file *pf = NULL;
int rc;
unsigned int cnt;
- path[PATH_MAX-1] = '\0';
if (init_path) {
- strncpy(path, init_path, PATH_MAX-1);
- fp = fopen(path, "re");
- if (!fp) {
- snprintf(errormsg, sizeof(errormsg),
- "unable to open %s: %m\n",
- path);
- PyErr_SetString( PyExc_ValueError, errormsg);
- return 1;
- }
+ curpolicy = init_path;
} else {
- const char *curpolicy = selinux_current_policy_path();
+ curpolicy = selinux_current_policy_path();
if (!curpolicy) {
/* SELinux disabled, must use -p option. */
snprintf(errormsg, sizeof(errormsg),
@@ -218,14 +209,15 @@ static int __policy_init(const char *init_path)
PyErr_SetString( PyExc_ValueError, errormsg);
return 1;
}
- fp = fopen(curpolicy, "re");
- if (!fp) {
- snprintf(errormsg, sizeof(errormsg),
- "unable to open %s: %m\n",
- curpolicy);
- PyErr_SetString( PyExc_ValueError, errormsg);
- return 1;
- }
+ }
+
+ fp = fopen(curpolicy, "re");
+ if (!fp) {
+ snprintf(errormsg, sizeof(errormsg),
+ "unable to open %s: %m\n",
+ curpolicy);
+ PyErr_SetString( PyExc_ValueError, errormsg);
+ return 1;
}
avc = calloc(sizeof(struct avc_t), 1);
@@ -249,7 +241,7 @@ static int __policy_init(const char *init_path)
sepol_policy_file_set_fp(pf, fp);
if (sepol_policydb_read(avc->policydb, pf)) {
snprintf(errormsg, sizeof(errormsg),
- "invalid binary policy %s\n", path);
+ "invalid binary policy %s\n", curpolicy);
PyErr_SetString( PyExc_ValueError, errormsg);
fclose(fp);
return 1;
--
2.27.0

View File

@ -3,7 +3,7 @@
Name: libselinux
Version: 3.3
Release: 2
Release: 3
License: Public Domain
Summary: SELinux library and simple utilities
Url: https://github.com/SELinuxProject/selinux/wiki
@ -14,6 +14,18 @@ Patch6001: backport-libselinux-free-memory-on-selabel_open-3-failure.patch
Patch6002: backport-libselinux-restorecon-misc-tweaks.patch
Patch6003: backport-libselinux-free-memory-in-error-branch.patch
Patch6004: backport-libselinux-restorecon-avoid-printing-NULL-pointer.patch
Patch6005: backport-libselinux-limit-has-buffer-size.patch
Patch6006: backport-libselinux-correctly-hash-specfiles-larger-than-4G.patch
Patch6007: backport-libselinux-simplify-policy-path-logic-to-avoid-uninitialized-read.patch
Patch6008: backport-libselinux-do-not-return-the-cached-prev_current-value-when-using-getpidcon.patch
Patch6009: backport-libselinux-Ignore-missing-directories-when-i-is-used.patch
Patch6010: backport-libselinux-ignore-invalid-class-name-lookup.patch
Patch6011: backport-libselinux-fix-memory-leaks-on-the-audit2why-module-init.patch
Patch6012: backport-libselinux-bail-out-on-path-truncations.patch
Patch6013: backport-libselinux-filter-arguments-with-path-separators.patch
Patch6014: backport-libselinux-fix-some-memory-issues-in-db_init.patch
Patch6015: backport-libselinux-add-check-for-malloc.patch
Patch6016: backport-libselinux-restore-use-fixed-sized-integer-for-hash-index.patch
Patch9000: do-malloc-trim-after-load-policy.patch
@ -134,6 +146,9 @@ mv %{buildroot}%{_sbindir}/getconlist %{buildroot}%{_sbindir}/selinuxconlist
%{_mandir}/ru/man8/*
%changelog
* Tue Jun 13 2023 zhangguangzhi <zhangguangzhi3@huawei.com> - 3.3-3
- backport upstream patches
* Sun Oct 9 2022 lujie <lujie54@huawei.com> - 3.3-2
- backport upstream patches