Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PGP: Set a default creation SELinux labels on GnuPG directories #290

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ OPTION (ENABLE_TESTS "Build test?" ON)
OPTION (ENABLE_DOCS "Build docs?" ON)
OPTION (WITH_ZCHUNK "Build with zchunk support" ON)
OPTION (ENABLE_PYTHON "Build Python bindings" ON)
OPTION (ENABLE_SELINUX "Restore SELinux labels on GnuPG directories" ON)

INCLUDE (${CMAKE_SOURCE_DIR}/VERSION.cmake)
SET (VERSION "${LIBREPO_MAJOR}.${LIBREPO_MINOR}.${LIBREPO_PATCH}")
Expand Down Expand Up @@ -33,6 +34,9 @@ PKG_SEARCH_MODULE(LIBCRYPTO REQUIRED libcrypto openssl)
PKG_CHECK_MODULES(LIBXML2 libxml-2.0 REQUIRED)
FIND_PACKAGE(CURL 7.52.0 REQUIRED)
FIND_PACKAGE(Gpgme REQUIRED)
IF (ENABLE_SELINUX)
PKG_CHECK_MODULES(SELINUX REQUIRED libselinux)
ENDIF(ENABLE_SELINUX)


IF (WITH_ZCHUNK)
Expand Down Expand Up @@ -63,6 +67,10 @@ ENDIF (NOT CURL_FOUND)
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR})
#INCLUDE_DIRECTORIES(${CHECK_INCLUDE_DIR})
IF (ENABLE_SELINUX)
INCLUDE_DIRECTORIES(${SELINUX_INCLUDE_DIRS})
ADD_DEFINITIONS(-DENABLE_SELINUX=1)
ENDIF (ENABLE_SELINUX)

include (GNUInstallDirs)
# Python stuff
Expand Down
9 changes: 8 additions & 1 deletion librepo.spec
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
%bcond_without zchunk
%endif

%bcond_without selinux

%global dnf_conflict 2.8.8

Name: librepo
Expand All @@ -29,6 +31,9 @@ BuildRequires: libattr-devel
BuildRequires: libcurl-devel >= %{libcurl_version}
BuildRequires: pkgconfig(libxml-2.0)
BuildRequires: pkgconfig(libcrypto)
%if %{with selinux}
BuildRequires: pkgconfig(libselinux)
%endif
BuildRequires: pkgconfig(openssl)
%if %{with zchunk}
BuildRequires: pkgconfig(zck) >= 0.9.11
Expand Down Expand Up @@ -66,7 +71,9 @@ Python 3 bindings for the librepo library.
%autosetup -p1

%build
%cmake %{!?with_zchunk:-DWITH_ZCHUNK=OFF}
%cmake \
%{!?with_zchunk:-DWITH_ZCHUNK=OFF} \
-DENABLE_SELINUX=%{?with_selinux:ON}%{!?with_selinux:OFF}
%cmake_build

%check
Expand Down
4 changes: 4 additions & 0 deletions librepo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ TARGET_LINK_LIBRARIES(librepo
${GPGME_VANILLA_LIBRARIES}
${GLIB2_LIBRARIES}
)
IF (ENABLE_SELINUX)
TARGET_LINK_LIBRARIES(librepo ${SELINUX_LIBRARIES})
ENDIF(ENABLE_SELINUX)

IF (WITH_ZCHUNK)
TARGET_LINK_LIBRARIES(librepo ${ZCHUNKLIB_LIBRARIES})
ENDIF (WITH_ZCHUNK)
Expand Down
64 changes: 64 additions & 0 deletions librepo/gpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
#include <gpgme.h>
#include <unistd.h>

#if ENABLE_SELINUX
#include <selinux/selinux.h>
#include <selinux/label.h>
#endif

#include "rcodes.h"
#include "util.h"
#include "gpg.h"
Expand All @@ -44,21 +49,80 @@
* Previous solution was to send the agent a "KILLAGENT" message, but that
* would cause a race condition with calling gpgme_release(), see [2], [3].
*
* Current solution with precreating /run/user/$UID showed problematic when
* this library was used out of an systemd-logind session. Then
* /run/user/$UID, normally maintained by systemd, was assigned a SELinux
* label unexpected by systemd causing errors on a user logout [4].
*
* We remedy it by choosing the label according to a default file context
* policy (ENABLE_SELINUX macro).
*
* Since the agent doesn't clean up its sockets properly, by creating this
* directory we make sure they are in a place that is not causing trouble with
* container images.
*
* [1] https://bugzilla.redhat.com/show_bug.cgi?id=1650266
* [2] https://bugzilla.redhat.com/show_bug.cgi?id=1769831
* [3] https://github.com/rpm-software-management/microdnf/issues/50
* [4] https://issues.redhat.com/browse/RHEL-10720
*/
void ensure_socket_dir_exists() {
char dirname[32];
#if ENABLE_SELINUX
char *old_default_context = NULL;
int old_default_context_was_retrieved = 0;
struct selabel_handle *labeling_handle = NULL;

/* A purpose of this piece of code is to deal with applications whose
* security policy overrides a file context for temporary files but don't
* know that librepo executes GnuPG which expects a default file context. */
if (0 == getfscreatecon(&old_default_context)) {
old_default_context_was_retrieved = 1;
} else {
g_debug("Failed to retrieve a default SELinux context");
}
labeling_handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
if (labeling_handle == NULL) {
g_debug("Failed to open a SELinux labeling handle: %s", strerror(errno));
}
#endif

snprintf(dirname, sizeof(dirname), "/run/user/%u", getuid());

#if ENABLE_SELINUX
if (labeling_handle != NULL) {
char *new_default_context = NULL;
if (selabel_lookup(labeling_handle, &new_default_context, dirname, 0700)) {
/* Here we could hard-code "system_u:object_r:user_tmp_t:s0", but
* that value should be really defined in default file context
* SELinux policy. Only log that the policy is incomplete. */
g_debug("Failed to look up a default SELinux label for \"%s\"", dirname);
} else {
if (setfscreatecon(new_default_context)) {
g_debug("Failed to set default SELinux context to \"%s\"",
new_default_context);
}
freecon(new_default_context);
}
}
#endif

int res = mkdir(dirname, 0700);
if (res != 0 && errno != EEXIST) {
g_debug("Failed to create \"%s\": %d - %s\n", dirname, errno, strerror(errno));
}

#if ENABLE_SELINUX
if (labeling_handle != NULL) {
selabel_close(labeling_handle);
}
if (old_default_context_was_retrieved) {
if (setfscreatecon(old_default_context)) {
g_debug("Failed to restore a default SELinux context");
}
}
freecon(old_default_context);
#endif
}

gboolean
Expand Down
Loading