- Apply 0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch
This commit is contained in:
parent
742312a8a9
commit
c7d052497b
@ -0,0 +1,384 @@
|
|||||||
|
From b0212b04f109875936612a52a7b30a80e5a85ee5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexey Tikhonov <atikhono@redhat.com>
|
||||||
|
Date: Mon, 23 Oct 2023 16:11:17 +0200
|
||||||
|
Subject: [PATCH] SSS_CLIENT: replace `__thread` with `pthread_*specific()`
|
||||||
|
|
||||||
|
in sss_client code to properly handle OOM condition (with `__thread`
|
||||||
|
glibc terminates process in this case).
|
||||||
|
|
||||||
|
Solution relies on the fact that `sss_cli_check_socket()` is always
|
||||||
|
executed first, before touching socket.
|
||||||
|
Nonetheless, there are sanity guards in setters/getters just in case.
|
||||||
|
|
||||||
|
It's possible to move context initialization code into a separate
|
||||||
|
function and call it in every getter/setter, but probably not worth it.
|
||||||
|
|
||||||
|
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||||
|
Reviewed-by: Carlos O'Donell <codonell@redhat.com>
|
||||||
|
---
|
||||||
|
src/sss_client/common.c | 202 ++++++++++++++++++++++++++++++++--------
|
||||||
|
1 file changed, 164 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
|
||||||
|
index c80c8e74b7..1075af9419 100644
|
||||||
|
--- a/src/sss_client/common.c
|
||||||
|
+++ b/src/sss_client/common.c
|
||||||
|
@@ -62,22 +62,31 @@
|
||||||
|
|
||||||
|
/* common functions */
|
||||||
|
|
||||||
|
+static int sss_cli_sd_get(void);
|
||||||
|
+static void sss_cli_sd_set(int sd);
|
||||||
|
+static const struct stat *sss_cli_sb_get(void);
|
||||||
|
+static int sss_cli_sb_set_by_sd(int sd);
|
||||||
|
+
|
||||||
|
#ifdef HAVE_PTHREAD_EXT
|
||||||
|
static pthread_key_t sss_sd_key;
|
||||||
|
static pthread_once_t sss_sd_key_init = PTHREAD_ONCE_INIT;
|
||||||
|
static atomic_bool sss_sd_key_initialized = false;
|
||||||
|
-static __thread int sss_cli_sd = -1; /* the sss client socket descriptor */
|
||||||
|
-static __thread struct stat sss_cli_sb; /* the sss client stat buffer */
|
||||||
|
+struct sss_socket_descriptor_t {
|
||||||
|
+ int sd;
|
||||||
|
+ struct stat sb;
|
||||||
|
+};
|
||||||
|
#else
|
||||||
|
-static int sss_cli_sd = -1; /* the sss client socket descriptor */
|
||||||
|
-static struct stat sss_cli_sb; /* the sss client stat buffer */
|
||||||
|
+static int _sss_cli_sd = -1; /* the sss client socket descriptor */
|
||||||
|
+static struct stat _sss_cli_sb; /* the sss client stat buffer */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void sss_cli_close_socket(void)
|
||||||
|
{
|
||||||
|
- if (sss_cli_sd != -1) {
|
||||||
|
- close(sss_cli_sd);
|
||||||
|
- sss_cli_sd = -1;
|
||||||
|
+ int sd = sss_cli_sd_get();
|
||||||
|
+
|
||||||
|
+ if (sd != -1) {
|
||||||
|
+ close(sd);
|
||||||
|
+ sss_cli_sd_set(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -85,25 +94,30 @@ void sss_cli_close_socket(void)
|
||||||
|
static void sss_at_thread_exit(void *v)
|
||||||
|
{
|
||||||
|
sss_cli_close_socket();
|
||||||
|
+ free(v);
|
||||||
|
+ pthread_setspecific(sss_sd_key, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_sd_key(void)
|
||||||
|
{
|
||||||
|
- pthread_key_create(&sss_sd_key, sss_at_thread_exit);
|
||||||
|
- sss_sd_key_initialized = true;
|
||||||
|
+ if (pthread_key_create(&sss_sd_key, sss_at_thread_exit) == 0) {
|
||||||
|
+ sss_sd_key_initialized = true;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR
|
||||||
|
__attribute__((destructor)) void sss_at_lib_unload(void)
|
||||||
|
{
|
||||||
|
+ sss_cli_close_socket();
|
||||||
|
#ifdef HAVE_PTHREAD_EXT
|
||||||
|
if (sss_sd_key_initialized) {
|
||||||
|
sss_sd_key_initialized = false;
|
||||||
|
+ free(pthread_getspecific(sss_sd_key));
|
||||||
|
+ pthread_setspecific(sss_sd_key, NULL);
|
||||||
|
pthread_key_delete(sss_sd_key);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
- sss_cli_close_socket();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -137,7 +151,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
|
||||||
|
int res, error;
|
||||||
|
|
||||||
|
*errnop = 0;
|
||||||
|
- pfd.fd = sss_cli_sd;
|
||||||
|
+ pfd.fd = sss_cli_sd_get();
|
||||||
|
pfd.events = POLLOUT;
|
||||||
|
|
||||||
|
do {
|
||||||
|
@@ -163,7 +177,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
|
||||||
|
*errnop = EPIPE;
|
||||||
|
} else if (pfd.revents & POLLNVAL) {
|
||||||
|
/* Invalid request: fd is not opened */
|
||||||
|
- sss_cli_sd = -1;
|
||||||
|
+ sss_cli_sd_set(-1);
|
||||||
|
*errnop = EPIPE;
|
||||||
|
} else if (!(pfd.revents & POLLOUT)) {
|
||||||
|
*errnop = EBUSY;
|
||||||
|
@@ -180,13 +194,13 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (datasent < SSS_NSS_HEADER_SIZE) {
|
||||||
|
- res = send(sss_cli_sd,
|
||||||
|
+ res = send(sss_cli_sd_get(),
|
||||||
|
(char *)header + datasent,
|
||||||
|
SSS_NSS_HEADER_SIZE - datasent,
|
||||||
|
SSS_DEFAULT_WRITE_FLAGS);
|
||||||
|
} else {
|
||||||
|
rdsent = datasent - SSS_NSS_HEADER_SIZE;
|
||||||
|
- res = send(sss_cli_sd,
|
||||||
|
+ res = send(sss_cli_sd_get(),
|
||||||
|
(const char *)rd->data + rdsent,
|
||||||
|
rd->len - rdsent,
|
||||||
|
SSS_DEFAULT_WRITE_FLAGS);
|
||||||
|
@@ -249,7 +263,7 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
|
||||||
|
int bufrecv;
|
||||||
|
int res, error;
|
||||||
|
|
||||||
|
- pfd.fd = sss_cli_sd;
|
||||||
|
+ pfd.fd = sss_cli_sd_get();
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
|
||||||
|
do {
|
||||||
|
@@ -278,7 +292,7 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
|
||||||
|
*errnop = EPIPE;
|
||||||
|
} else if (pfd.revents & POLLNVAL) {
|
||||||
|
/* Invalid request: fd is not opened */
|
||||||
|
- sss_cli_sd = -1;
|
||||||
|
+ sss_cli_sd_set(-1);
|
||||||
|
*errnop = EPIPE;
|
||||||
|
} else if (!(pfd.revents & POLLIN)) {
|
||||||
|
*errnop = EBUSY;
|
||||||
|
@@ -296,12 +310,12 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (datarecv < SSS_NSS_HEADER_SIZE) {
|
||||||
|
- res = read(sss_cli_sd,
|
||||||
|
+ res = read(sss_cli_sd_get(),
|
||||||
|
(char *)header + datarecv,
|
||||||
|
SSS_NSS_HEADER_SIZE - datarecv);
|
||||||
|
} else {
|
||||||
|
bufrecv = datarecv - SSS_NSS_HEADER_SIZE;
|
||||||
|
- res = read(sss_cli_sd,
|
||||||
|
+ res = read(sss_cli_sd_get(),
|
||||||
|
(char *) buf + bufrecv,
|
||||||
|
header[0] - datarecv);
|
||||||
|
}
|
||||||
|
@@ -591,16 +605,6 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef HAVE_PTHREAD_EXT
|
||||||
|
- pthread_once(&sss_sd_key_init, init_sd_key); /* once for all threads */
|
||||||
|
-
|
||||||
|
- /* It actually doesn't matter what value to set for a key.
|
||||||
|
- * The only important thing: key must be non-NULL to ensure
|
||||||
|
- * destructor is executed at thread exit.
|
||||||
|
- */
|
||||||
|
- pthread_setspecific(sss_sd_key, &sss_cli_sd);
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
/* set as non-blocking, close on exec, and make sure standard
|
||||||
|
* descriptors are not used */
|
||||||
|
sd = make_safe_fd(sd);
|
||||||
|
@@ -670,7 +674,7 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = fstat(sd, &sss_cli_sb);
|
||||||
|
+ ret = sss_cli_sb_set_by_sd(sd);
|
||||||
|
if (ret != 0) {
|
||||||
|
close(sd);
|
||||||
|
return -1;
|
||||||
|
@@ -686,33 +690,69 @@ static enum sss_status sss_cli_check_socket(int *errnop,
|
||||||
|
static pid_t mypid_s;
|
||||||
|
static ino_t myself_ino;
|
||||||
|
struct stat mypid_sb, myself_sb;
|
||||||
|
+ const struct stat *sss_cli_sb = NULL;
|
||||||
|
pid_t mypid_d;
|
||||||
|
int mysd;
|
||||||
|
int ret;
|
||||||
|
+#ifdef HAVE_PTHREAD_EXT
|
||||||
|
+ struct sss_socket_descriptor_t *descriptor = NULL;
|
||||||
|
+
|
||||||
|
+ ret = pthread_once(&sss_sd_key_init, init_sd_key); /* once for all threads */
|
||||||
|
+ if (ret != 0) {
|
||||||
|
+ *errnop = EFAULT;
|
||||||
|
+ return SSS_STATUS_UNAVAIL;
|
||||||
|
+ }
|
||||||
|
+ if (!sss_sd_key_initialized) {
|
||||||
|
+ /* pthread_once::init_sd_key::pthread_key_create failed -- game over? */
|
||||||
|
+ *errnop = EFAULT;
|
||||||
|
+ return SSS_STATUS_UNAVAIL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (pthread_getspecific(sss_sd_key) == NULL) { /* for every thread */
|
||||||
|
+ descriptor = (struct sss_socket_descriptor_t *)
|
||||||
|
+ calloc(1, sizeof(struct sss_socket_descriptor_t));
|
||||||
|
+ if (descriptor == NULL) {
|
||||||
|
+ *errnop = ENOMEM;
|
||||||
|
+ return SSS_STATUS_UNAVAIL;
|
||||||
|
+ }
|
||||||
|
+ descriptor->sd = -1;
|
||||||
|
+ ret = pthread_setspecific(sss_sd_key, descriptor);
|
||||||
|
+ if (ret != 0) {
|
||||||
|
+ free(descriptor);
|
||||||
|
+ *errnop = ENOMEM;
|
||||||
|
+ return SSS_STATUS_UNAVAIL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ sss_cli_sb = sss_cli_sb_get();
|
||||||
|
+ if (sss_cli_sb == NULL) {
|
||||||
|
+ *errnop = EFAULT;
|
||||||
|
+ return SSS_STATUS_UNAVAIL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ret = lstat("/proc/self/", &myself_sb);
|
||||||
|
mypid_d = getpid();
|
||||||
|
if (mypid_d != mypid_s || (ret == 0 && myself_sb.st_ino != myself_ino)) {
|
||||||
|
- ret = fstat(sss_cli_sd, &mypid_sb);
|
||||||
|
+ ret = fstat(sss_cli_sd_get(), &mypid_sb);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (S_ISSOCK(mypid_sb.st_mode) &&
|
||||||
|
- mypid_sb.st_dev == sss_cli_sb.st_dev &&
|
||||||
|
- mypid_sb.st_ino == sss_cli_sb.st_ino) {
|
||||||
|
+ mypid_sb.st_dev == sss_cli_sb->st_dev &&
|
||||||
|
+ mypid_sb.st_ino == sss_cli_sb->st_ino) {
|
||||||
|
sss_cli_close_socket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- sss_cli_sd = -1;
|
||||||
|
+ sss_cli_sd_set(-1);
|
||||||
|
mypid_s = mypid_d;
|
||||||
|
myself_ino = myself_sb.st_ino;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if the socket has been closed on the other side */
|
||||||
|
- if (sss_cli_sd != -1) {
|
||||||
|
+ if (sss_cli_sd_get() != -1) {
|
||||||
|
struct pollfd pfd;
|
||||||
|
int res, error;
|
||||||
|
|
||||||
|
*errnop = 0;
|
||||||
|
- pfd.fd = sss_cli_sd;
|
||||||
|
+ pfd.fd = sss_cli_sd_get();
|
||||||
|
pfd.events = POLLIN | POLLOUT;
|
||||||
|
|
||||||
|
do {
|
||||||
|
@@ -738,7 +778,7 @@ static enum sss_status sss_cli_check_socket(int *errnop,
|
||||||
|
*errnop = EPIPE;
|
||||||
|
} else if (pfd.revents & POLLNVAL) {
|
||||||
|
/* Invalid request: fd is not opened */
|
||||||
|
- sss_cli_sd = -1;
|
||||||
|
+ sss_cli_sd_set(-1);
|
||||||
|
*errnop = EPIPE;
|
||||||
|
} else if (!(pfd.revents & (POLLIN | POLLOUT))) {
|
||||||
|
*errnop = EBUSY;
|
||||||
|
@@ -760,7 +800,7 @@ static enum sss_status sss_cli_check_socket(int *errnop,
|
||||||
|
return SSS_STATUS_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- sss_cli_sd = mysd;
|
||||||
|
+ sss_cli_sd_set(mysd);
|
||||||
|
|
||||||
|
if (sss_cli_check_version(socket_name, timeout)) {
|
||||||
|
return SSS_STATUS_SUCCESS;
|
||||||
|
@@ -1015,7 +1055,7 @@ int sss_pam_make_request(enum sss_cli_command cmd,
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- error = check_server_cred(sss_cli_sd);
|
||||||
|
+ error = check_server_cred(sss_cli_sd_get());
|
||||||
|
if (error != 0) {
|
||||||
|
sss_cli_close_socket();
|
||||||
|
*errnop = error;
|
||||||
|
@@ -1307,3 +1347,89 @@ errno_t sss_readrep_copy_string(const char *in,
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_PTHREAD_EXT
|
||||||
|
+
|
||||||
|
+static int sss_cli_sd_get(void)
|
||||||
|
+{
|
||||||
|
+ if (!sss_sd_key_initialized) {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
|
||||||
|
+
|
||||||
|
+ if (descriptor == NULL) { /* sanity check */
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return descriptor->sd;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void sss_cli_sd_set(int sd)
|
||||||
|
+{
|
||||||
|
+ if (!sss_sd_key_initialized) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
|
||||||
|
+
|
||||||
|
+ if (descriptor == NULL) { /* sanity check */
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ descriptor->sd = sd;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct stat *sss_cli_sb_get(void)
|
||||||
|
+{
|
||||||
|
+ if (!sss_sd_key_initialized) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
|
||||||
|
+
|
||||||
|
+ if (descriptor == NULL) { /* sanity check */
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return &descriptor->sb;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int sss_cli_sb_set_by_sd(int sd)
|
||||||
|
+{
|
||||||
|
+ if (!sss_sd_key_initialized) {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
|
||||||
|
+
|
||||||
|
+ if (descriptor == NULL) { /* sanity check */
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return fstat(sd, &descriptor->sb);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
+static int sss_cli_sd_get(void)
|
||||||
|
+{
|
||||||
|
+ return _sss_cli_sd;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void sss_cli_sd_set(int sd)
|
||||||
|
+{
|
||||||
|
+ _sss_cli_sd = sd;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct stat *sss_cli_sb_get(void)
|
||||||
|
+{
|
||||||
|
+ return &_sss_cli_sb;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int sss_cli_sb_set_by_sd(int sd)
|
||||||
|
+{
|
||||||
|
+ return fstat(sd, &_sss_cli_sb);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
Name: sssd
|
Name: sssd
|
||||||
Version: 2.9.1
|
Version: 2.9.1
|
||||||
Release: 4%{?dist}.alma.1
|
Release: 4%{?dist}.1.alma.1
|
||||||
Summary: System Security Services Daemon
|
Summary: System Security Services Daemon
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
URL: https://github.com/SSSD/sssd/
|
URL: https://github.com/SSSD/sssd/
|
||||||
@ -46,7 +46,8 @@ Patch0004: 0004-sss_iface-do-not-add-cli_id-to-chain-key.patch
|
|||||||
Patch0005: 0005-Accept-krb5-1.21-for-building-the-PAC-plugin.patch
|
Patch0005: 0005-Accept-krb5-1.21-for-building-the-PAC-plugin.patch
|
||||||
# https://github.com/SSSD/sssd/commit/88d8afbb115f18007dcc11f7ebac1b238c3ebd98
|
# https://github.com/SSSD/sssd/commit/88d8afbb115f18007dcc11f7ebac1b238c3ebd98
|
||||||
Patch0006: 0006-MC-a-couple-of-additions-to-recover-from-invalid-memory.patch
|
Patch0006: 0006-MC-a-couple-of-additions-to-recover-from-invalid-memory.patch
|
||||||
|
# https://github.com/SSSD/sssd/commit/b0212b04f109875936612a52a7b30a80e5a85ee5
|
||||||
|
Patch0007: 0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch
|
||||||
### Dependencies ###
|
### Dependencies ###
|
||||||
|
|
||||||
Requires: sssd-ad = %{version}-%{release}
|
Requires: sssd-ad = %{version}-%{release}
|
||||||
@ -1072,6 +1073,9 @@ fi
|
|||||||
%systemd_postun_with_restart sssd.service
|
%systemd_postun_with_restart sssd.service
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Dec 13 2023 Eduard Abdullin <eabdullin@almalinux.org> - 2.9.1-4.1.alma.1
|
||||||
|
- Apply 0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch
|
||||||
|
|
||||||
* Wed Nov 08 2023 Eduard Abdullin <eabdullin@almalinux.org> - 2.9.1-4.alma.1
|
* Wed Nov 08 2023 Eduard Abdullin <eabdullin@almalinux.org> - 2.9.1-4.alma.1
|
||||||
- Apply 0003-mc-recover-from-invalid-memory-cache-size.patch
|
- Apply 0003-mc-recover-from-invalid-memory-cache-size.patch
|
||||||
- Apply 0004-sss_iface-do-not-add-cli_id-to-chain-key.patch
|
- Apply 0004-sss_iface-do-not-add-cli_id-to-chain-key.patch
|
||||||
|
Loading…
Reference in New Issue
Block a user