|
|
ab1ddb |
From f9859498b52d89bf60dbddd898752f859f4952d3 Mon Sep 17 00:00:00 2001
|
|
|
ab1ddb |
From: Sumit Bose <sbose@redhat.com>
|
|
|
ab1ddb |
Date: Thu, 15 Mar 2018 12:50:20 +0100
|
|
|
ab1ddb |
Subject: [PATCH] nss: add a netgroup counter to struct nss_enum_index
|
|
|
ab1ddb |
|
|
|
ab1ddb |
Netgroups are not looked up with the help of a single request but by
|
|
|
ab1ddb |
calling setnetgrent(), getnetgrent() and endnetgrent() where
|
|
|
ab1ddb |
getnetgrent() might be called multiple times depending on the number of
|
|
|
ab1ddb |
netgroup elements. Since the caller does not provide a state the state
|
|
|
ab1ddb |
has to be maintained by the SSSD nss responder. Besides the netgroup
|
|
|
ab1ddb |
name this is mainly the number of elements already returned.
|
|
|
ab1ddb |
|
|
|
ab1ddb |
This number is used to select the next element to return and currently
|
|
|
ab1ddb |
it is assumed that there are not changes to the netgroup while the
|
|
|
ab1ddb |
client is requesting the individual elements. But if e.g. the 3 nss
|
|
|
ab1ddb |
calls are not used correctly or the netgroup is modified while the
|
|
|
ab1ddb |
client is sending getnetgrent() calls the stored number might be out of
|
|
|
ab1ddb |
range. To be on the safe side the stored number should be always
|
|
|
ab1ddb |
compared with the current number of netgroup elements.
|
|
|
ab1ddb |
|
|
|
ab1ddb |
Related to https://pagure.io/SSSD/sssd/issue/3679
|
|
|
ab1ddb |
|
|
|
ab1ddb |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
ab1ddb |
(cherry picked from commit 08db22b1b1a2e742edbca92e35087294d963adda)
|
|
|
ab1ddb |
|
|
|
ab1ddb |
DOWNSTREAM:
|
|
|
ab1ddb |
Resolves: rhbz#1579703 - crash in nss_protocol_fill_netgrent. sssd_nss[19234]: segfault at 80 ip 000055612688c2a0 sp 00007ffddf9b9cd0 error 4 in sssd_nss[55612687e000+39000] [rhel-7.5.z]
|
|
|
ab1ddb |
---
|
|
|
ab1ddb |
src/db/sysdb.h | 3 ++-
|
|
|
ab1ddb |
src/db/sysdb_search.c | 5 ++++-
|
|
|
ab1ddb |
src/responder/nss/nss_enum.c | 3 ++-
|
|
|
ab1ddb |
src/responder/nss/nss_private.h | 1 +
|
|
|
ab1ddb |
src/responder/nss/nss_protocol_netgr.c | 7 +++++++
|
|
|
ab1ddb |
5 files changed, 16 insertions(+), 3 deletions(-)
|
|
|
ab1ddb |
|
|
|
ab1ddb |
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
|
|
ab1ddb |
index fd18ecefed2b2c5f35060fa47fd160a8968e073b..2660314a75a574d7f5625c8672e5261587056d1a 100644
|
|
|
ab1ddb |
--- a/src/db/sysdb.h
|
|
|
ab1ddb |
+++ b/src/db/sysdb.h
|
|
|
ab1ddb |
@@ -1219,7 +1219,8 @@ errno_t sysdb_attrs_to_list(TALLOC_CTX *mem_ctx,
|
|
|
ab1ddb |
|
|
|
ab1ddb |
errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx,
|
|
|
ab1ddb |
struct ldb_result *res,
|
|
|
ab1ddb |
- struct sysdb_netgroup_ctx ***entries);
|
|
|
ab1ddb |
+ struct sysdb_netgroup_ctx ***entries,
|
|
|
ab1ddb |
+ size_t *netgroup_count);
|
|
|
ab1ddb |
|
|
|
ab1ddb |
errno_t sysdb_dn_sanitize(TALLOC_CTX *mem_ctx, const char *input,
|
|
|
ab1ddb |
char **sanitized);
|
|
|
ab1ddb |
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
|
|
|
ab1ddb |
index a6a81e23d257331614085403b4dca8ded860600b..9f37cbcd50a778145518c15b6146ad812a5b4fa3 100644
|
|
|
ab1ddb |
--- a/src/db/sysdb_search.c
|
|
|
ab1ddb |
+++ b/src/db/sysdb_search.c
|
|
|
ab1ddb |
@@ -1829,7 +1829,8 @@ done:
|
|
|
ab1ddb |
|
|
|
ab1ddb |
errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx,
|
|
|
ab1ddb |
struct ldb_result *res,
|
|
|
ab1ddb |
- struct sysdb_netgroup_ctx ***entries)
|
|
|
ab1ddb |
+ struct sysdb_netgroup_ctx ***entries,
|
|
|
ab1ddb |
+ size_t *netgroup_count)
|
|
|
ab1ddb |
{
|
|
|
ab1ddb |
errno_t ret;
|
|
|
ab1ddb |
size_t size = 0;
|
|
|
ab1ddb |
@@ -1933,6 +1934,8 @@ errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx,
|
|
|
ab1ddb |
tmp_entry[c] = NULL;
|
|
|
ab1ddb |
|
|
|
ab1ddb |
*entries = talloc_steal(mem_ctx, tmp_entry);
|
|
|
ab1ddb |
+ *netgroup_count = c;
|
|
|
ab1ddb |
+
|
|
|
ab1ddb |
ret = EOK;
|
|
|
ab1ddb |
|
|
|
ab1ddb |
done:
|
|
|
ab1ddb |
diff --git a/src/responder/nss/nss_enum.c b/src/responder/nss/nss_enum.c
|
|
|
ab1ddb |
index da844fbced529f606a3e98669fb7b95e0696ce00..b2b22bbae8a373ed3abb47381fabd989d4931690 100644
|
|
|
ab1ddb |
--- a/src/responder/nss/nss_enum.c
|
|
|
ab1ddb |
+++ b/src/responder/nss/nss_enum.c
|
|
|
ab1ddb |
@@ -144,7 +144,8 @@ static void nss_setent_internal_done(struct tevent_req *subreq)
|
|
|
ab1ddb |
/* We need to expand the netgroup into triples and members. */
|
|
|
ab1ddb |
ret = sysdb_netgr_to_entries(state->enum_ctx,
|
|
|
ab1ddb |
result[0]->ldb_result,
|
|
|
ab1ddb |
- &state->enum_ctx->netgroup);
|
|
|
ab1ddb |
+ &state->enum_ctx->netgroup,
|
|
|
ab1ddb |
+ &state->enum_ctx->netgroup_count);
|
|
|
ab1ddb |
if (ret != EOK) {
|
|
|
ab1ddb |
goto done;
|
|
|
ab1ddb |
}
|
|
|
ab1ddb |
diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h
|
|
|
ab1ddb |
index 5fc19d26be9adda4d967086e7b239e49a78866ee..aa8d8e9cde0d73e72d3aa4c186f104d6baae411f 100644
|
|
|
ab1ddb |
--- a/src/responder/nss/nss_private.h
|
|
|
ab1ddb |
+++ b/src/responder/nss/nss_private.h
|
|
|
ab1ddb |
@@ -41,6 +41,7 @@ struct nss_enum_index {
|
|
|
ab1ddb |
struct nss_enum_ctx {
|
|
|
ab1ddb |
struct cache_req_result **result;
|
|
|
ab1ddb |
struct sysdb_netgroup_ctx **netgroup;
|
|
|
ab1ddb |
+ size_t netgroup_count;
|
|
|
ab1ddb |
|
|
|
ab1ddb |
/* Ongoing cache request that is constructing enumeration result. */
|
|
|
ab1ddb |
struct tevent_req *ongoing;
|
|
|
ab1ddb |
diff --git a/src/responder/nss/nss_protocol_netgr.c b/src/responder/nss/nss_protocol_netgr.c
|
|
|
ab1ddb |
index ed04fd25821031554e20e14afebaca9b828a748b..9f27c6b78d47f188dea99600a634a18be2512bfb 100644
|
|
|
ab1ddb |
--- a/src/responder/nss/nss_protocol_netgr.c
|
|
|
ab1ddb |
+++ b/src/responder/nss/nss_protocol_netgr.c
|
|
|
ab1ddb |
@@ -126,6 +126,13 @@ nss_protocol_fill_netgrent(struct nss_ctx *nss_ctx,
|
|
|
ab1ddb |
idx = cmd_ctx->enum_index;
|
|
|
ab1ddb |
entries = cmd_ctx->enum_ctx->netgroup;
|
|
|
ab1ddb |
|
|
|
ab1ddb |
+ if (idx->result > cmd_ctx->enum_ctx->netgroup_count) {
|
|
|
ab1ddb |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
ab1ddb |
+ "Unconsistent state while processing netgroups.\n");
|
|
|
ab1ddb |
+ ret = EINVAL;
|
|
|
ab1ddb |
+ goto done;
|
|
|
ab1ddb |
+ }
|
|
|
ab1ddb |
+
|
|
|
ab1ddb |
/* First two fields (length and reserved), filled up later. */
|
|
|
ab1ddb |
ret = sss_packet_grow(packet, 2 * sizeof(uint32_t));
|
|
|
ab1ddb |
if (ret != EOK) {
|
|
|
ab1ddb |
--
|
|
|
ab1ddb |
2.17.0
|
|
|
ab1ddb |
|