From 328f31d50780ce0b55b41e25fbaed0f177b6ed71 Mon Sep 17 00:00:00 2001 From: Justin Stephenson Date: Fri, 22 Sep 2023 10:42:38 -0400 Subject: [PATCH] util: Realloc buffer size for atomic safe read Realloc and increase the buffer size when safe read returns more than CHILD_MSG_CHUNK size bytes. This handles multiple passkey mappings returned from the krb5 child in kerberos pre-authentication. --- src/util/atomic_io.c | 4 +++- src/util/child_common.c | 20 ++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/util/atomic_io.c b/src/util/atomic_io.c index 589dfa4d4e4..948d56e8daa 100644 --- a/src/util/atomic_io.c +++ b/src/util/atomic_io.c @@ -87,7 +87,9 @@ ssize_t sss_atomic_read_safe_s(int fd, void *buf, size_t buf_len, size_t *_len) } if (ulen > buf_len) { - return ERANGE; + *_len = ulen; + errno = ERANGE; + return -1; } if (_len != NULL) { diff --git a/src/util/child_common.c b/src/util/child_common.c index 6f950614f08..3a4a14d2ce8 100644 --- a/src/util/child_common.c +++ b/src/util/child_common.c @@ -509,7 +509,7 @@ static void _read_pipe_handler(struct tevent_context *ev, struct _read_pipe_state *state; ssize_t size; errno_t err; - uint8_t buf[CHILD_MSG_CHUNK]; + uint8_t *buf; size_t len = 0; state = tevent_req_data(req, struct _read_pipe_state); @@ -521,18 +521,34 @@ static void _read_pipe_handler(struct tevent_context *ev, return; } + buf = talloc_array(state, uint8_t, CHILD_MSG_CHUNK); + if (buf == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + if (state->safe) { size = sss_atomic_read_safe_s(state->fd, buf, CHILD_MSG_CHUNK, &len); } else { size = sss_atomic_read_s(state->fd, buf, CHILD_MSG_CHUNK); } + + if (size == -1 && errno == ERANGE) { + buf = talloc_realloc(state, buf, uint8_t, len); + if(!buf) { + tevent_req_error(req, ENOMEM); + return; + } + + size = sss_atomic_read_s(state->fd, buf, len); + } + if (size == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", err, strerror(err)); tevent_req_error(req, err); return; - } else if (size > 0) { state->buf = talloc_realloc(state, state->buf, uint8_t, state->len + size);