|
|
462afb |
From dc3b2a2b22106fa4c0033a5557584f3b08c942e2 Mon Sep 17 00:00:00 2001
|
|
|
462afb |
From: Marek Blaha <mblaha@redhat.com>
|
|
|
462afb |
Date: Fri, 3 Jan 2020 12:35:33 +0100
|
|
|
462afb |
Subject: [PATCH] Remove killGpgAgent function (RhBug:1781601)
|
|
|
462afb |
|
|
|
462afb |
Instead ensure that /run/user/$UID directory exists so gpgagent could
|
|
|
462afb |
create its socket in it.
|
|
|
462afb |
The solution with KILLAGENT caused race condition with gpgme_release()
|
|
|
462afb |
call and that resulted in dnf being possibly terminated by SIGPIPE after
|
|
|
462afb |
importing the first repository gpg key.
|
|
|
462afb |
|
|
|
462afb |
https://bugzilla.redhat.com/show_bug.cgi?id=1781601
|
|
|
462afb |
---
|
|
|
462afb |
libdnf/repo/Repo.cpp | 56 +++++++++++++++++++++++---------------------
|
|
|
462afb |
1 file changed, 29 insertions(+), 27 deletions(-)
|
|
|
462afb |
|
|
|
462afb |
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
|
|
|
462afb |
index 850e5b4a8..c1891cce9 100644
|
|
|
462afb |
--- a/libdnf/repo/Repo.cpp
|
|
|
462afb |
+++ b/libdnf/repo/Repo.cpp
|
|
|
462afb |
@@ -846,27 +846,35 @@ std::vector<Key> Repo::Impl::retrieve(const std::string & url)
|
|
|
462afb |
return keyInfos;
|
|
|
462afb |
}
|
|
|
462afb |
|
|
|
462afb |
-static void killGpgAgent(gpgme_ctx_t context, const std::string & gpgDir)
|
|
|
462afb |
-{
|
|
|
462afb |
+/*
|
|
|
462afb |
+ * Creates the '/run/user/$UID' directory if it doesn't exist. If this
|
|
|
462afb |
+ * directory exists, gpgagent will create its sockets under
|
|
|
462afb |
+ * '/run/user/$UID/gnupg'.
|
|
|
462afb |
+ *
|
|
|
462afb |
+ * If this directory doesn't exist, gpgagent will create its sockets in gpg
|
|
|
462afb |
+ * home directory, which is under '/var/cache/yum/metadata/' and this was
|
|
|
462afb |
+ * causing trouble with container images, see [1].
|
|
|
462afb |
+ *
|
|
|
462afb |
+ * Previous solution was to send the agent a "KILLAGENT" message, but that
|
|
|
462afb |
+ * would cause a race condition with calling gpgme_release(), see [2], [3],
|
|
|
462afb |
+ * [4].
|
|
|
462afb |
+ *
|
|
|
462afb |
+ * Since the agent doesn't clean up its sockets properly, by creating this
|
|
|
462afb |
+ * directory we make sure they are in a place that is not causing trouble with
|
|
|
462afb |
+ * container images.
|
|
|
462afb |
+ *
|
|
|
462afb |
+ * [1] https://bugzilla.redhat.com/show_bug.cgi?id=1650266
|
|
|
462afb |
+ * [2] https://bugzilla.redhat.com/show_bug.cgi?id=1769831
|
|
|
462afb |
+ * [3] https://github.com/rpm-software-management/microdnf/issues/50
|
|
|
462afb |
+ * [4] https://bugzilla.redhat.com/show_bug.cgi?id=1781601
|
|
|
462afb |
+ */
|
|
|
462afb |
+static void ensure_socket_dir_exists() {
|
|
|
462afb |
auto logger(Log::getLogger());
|
|
|
462afb |
-
|
|
|
462afb |
- auto gpgErr = gpgme_set_protocol(context, GPGME_PROTOCOL_ASSUAN);
|
|
|
462afb |
- if (gpgErr != GPG_ERR_NO_ERROR) {
|
|
|
462afb |
- auto msg = tfm::format(_("%s: gpgme_set_protocol(): %s"), __func__, gpgme_strerror(gpgErr));
|
|
|
462afb |
- logger->warning(msg);
|
|
|
462afb |
- return;
|
|
|
462afb |
- }
|
|
|
462afb |
- std::string gpgAgentSock = gpgDir + "/S.gpg-agent";
|
|
|
462afb |
- gpgErr = gpgme_ctx_set_engine_info(context, GPGME_PROTOCOL_ASSUAN, gpgAgentSock.c_str(), gpgDir.c_str());
|
|
|
462afb |
- if (gpgErr != GPG_ERR_NO_ERROR) {
|
|
|
462afb |
- auto msg = tfm::format(_("%s: gpgme_ctx_set_engine_info(): %s"), __func__, gpgme_strerror(gpgErr));
|
|
|
462afb |
- logger->warning(msg);
|
|
|
462afb |
- return;
|
|
|
462afb |
- }
|
|
|
462afb |
- gpgErr = gpgme_op_assuan_transact_ext(context, "KILLAGENT", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
|
|
462afb |
- if (gpgErr != GPG_ERR_NO_ERROR) {
|
|
|
462afb |
- auto msg = tfm::format(_("%s: gpgme_op_assuan_transact_ext(): %s"), __func__, gpgme_strerror(gpgErr));
|
|
|
462afb |
- logger->debug(msg);
|
|
|
462afb |
+ std::string dirname = "/run/user/" + std::to_string(getuid());
|
|
|
462afb |
+ int res = mkdir(dirname.c_str(), 0700);
|
|
|
462afb |
+ if (res != 0 && errno != EEXIST) {
|
|
|
462afb |
+ logger->debug(tfm::format("Failed to create directory \"%s\": %d - %s",
|
|
|
462afb |
+ dirname, errno, strerror(errno)));
|
|
|
462afb |
}
|
|
|
462afb |
}
|
|
|
462afb |
|
|
|
462afb |
@@ -876,6 +884,7 @@ void Repo::Impl::importRepoKeys()
|
|
|
462afb |
|
|
|
462afb |
auto gpgDir = getCachedir() + "/pubring";
|
|
|
462afb |
auto knownKeys = keyidsFromPubring(gpgDir);
|
|
|
462afb |
+ ensure_socket_dir_exists();
|
|
|
462afb |
for (const auto & gpgkeyUrl : conf->gpgkey().getValue()) {
|
|
|
462afb |
auto keyInfos = retrieve(gpgkeyUrl);
|
|
|
462afb |
for (auto & keyInfo : keyInfos) {
|
|
|
462afb |
@@ -908,13 +917,6 @@ void Repo::Impl::importRepoKeys()
|
|
|
462afb |
|
|
|
462afb |
gpgImportKey(ctx, keyInfo.rawKey);
|
|
|
462afb |
|
|
|
462afb |
- // Running gpg-agent kept opened sockets on the system.
|
|
|
462afb |
- // It tries to exit gpg-agent. Path to the communication socket is derived from homedir.
|
|
|
462afb |
- // The gpg-agent automaticaly removes all its socket before exit.
|
|
|
462afb |
- // Newer gpg-agent creates sockets under [/var]/run/user/{pid}/... if directory exists.
|
|
|
462afb |
- // In this case gpg-agent will not be exited.
|
|
|
462afb |
- killGpgAgent(ctx, gpgDir);
|
|
|
462afb |
-
|
|
|
462afb |
logger->debug(tfm::format(_("repo %s: imported key 0x%s."), id, keyInfo.getId()));
|
|
|
462afb |
}
|
|
|
462afb |
|