libselinux: avoid errno modification by fclose(3)

In case fclose(3) might modify the global variable errno, use a wrapper
retaining the errno value.  In the affected cases the success of
fclose(3) itself is not important, since the underlying descriptor is
only read from.

Reported-by: clang-analyzer
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
Christian Göttsche 2024-10-18 17:12:57 +02:00 committed by James Carter
parent e38815d7b4
commit 6376f90d5e
3 changed files with 15 additions and 4 deletions

View File

@ -438,7 +438,7 @@ int get_ordered_context_list(const char *user,
__fsetlocking(fp, FSETLOCKING_BYCALLER); __fsetlocking(fp, FSETLOCKING_BYCALLER);
rc = get_context_user(fp, con, user, &reachable, &nreachable); rc = get_context_user(fp, con, user, &reachable, &nreachable);
fclose(fp); fclose_errno_safe(fp);
if (rc < 0 && errno != ENOENT) { if (rc < 0 && errno != ENOENT) {
selinux_log(SELINUX_ERROR, selinux_log(SELINUX_ERROR,
"%s: error in processing configuration file %s\n", "%s: error in processing configuration file %s\n",
@ -451,7 +451,7 @@ int get_ordered_context_list(const char *user,
if (fp) { if (fp) {
__fsetlocking(fp, FSETLOCKING_BYCALLER); __fsetlocking(fp, FSETLOCKING_BYCALLER);
rc = get_context_user(fp, con, user, &reachable, &nreachable); rc = get_context_user(fp, con, user, &reachable, &nreachable);
fclose(fp); fclose_errno_safe(fp);
if (rc < 0 && errno != ENOENT) { if (rc < 0 && errno != ENOENT) {
selinux_log(SELINUX_ERROR, selinux_log(SELINUX_ERROR,
"%s: error in processing configuration file %s\n", "%s: error in processing configuration file %s\n",

View File

@ -628,7 +628,7 @@ static int process_file(const char *path, const char *suffix,
rc = fcontext_is_binary(fp); rc = fcontext_is_binary(fp);
if (rc < 0) { if (rc < 0) {
(void) fclose(fp); fclose_errno_safe(fp);
return -1; return -1;
} }
@ -639,7 +639,7 @@ static int process_file(const char *path, const char *suffix,
rc = digest_add_specfile(digest, fp, NULL, sb.st_size, rc = digest_add_specfile(digest, fp, NULL, sb.st_size,
found_path); found_path);
fclose(fp); fclose_errno_safe(fp);
if (!rc) if (!rc)
return 0; return 0;

View File

@ -2,7 +2,9 @@
#define SELINUX_INTERNAL_H_ #define SELINUX_INTERNAL_H_
#include <selinux/selinux.h> #include <selinux/selinux.h>
#include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h>
extern int require_seusers ; extern int require_seusers ;
@ -131,4 +133,13 @@ void *reallocarray(void *ptr, size_t nmemb, size_t size);
#define IGNORE_DEPRECATED_DECLARATION_END #define IGNORE_DEPRECATED_DECLARATION_END
#endif #endif
static inline void fclose_errno_safe(FILE *stream)
{
int saved_errno;
saved_errno = errno;
(void) fclose(stream);
errno = saved_errno;
}
#endif /* SELINUX_INTERNAL_H_ */ #endif /* SELINUX_INTERNAL_H_ */