Skip to content

Commit

Permalink
KCM: Reduce the amount of memory allocated for the packages
Browse files Browse the repository at this point in the history
Some packages are being allocated to their maximum size, even though all
that memory is not required. When the amount of memory needed is not know,
We reduce the amount of memory allocated to the initial size defined by
the KCM_PACKET_INITIAL_SIZE macro.

The existing KCM_REPLY_MAX was replaced by KCM_PACKET_MAX_SIZE.

Resolves: SSSD#7014
  • Loading branch information
aplopez committed Nov 13, 2023
1 parent 78bd787 commit cf1994e
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
5 changes: 0 additions & 5 deletions src/responder/kcm/kcmsrv_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@
/* The return code is 32bits */
#define KCM_RETCODE_SIZE 4

/* The maximum length of a request or reply as defined by the RPC
* protocol. This is the same constant size as MIT KRB5 uses
*/
#define KCM_PACKET_MAX_SIZE 10*1024*1024

/* KCM operation, its raw input and raw output and result */
struct kcm_op_io {
struct kcm_op *op;
Expand Down
15 changes: 5 additions & 10 deletions src/responder/kcm/kcmsrv_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@
#include "responder/kcm/kcmsrv_ops.h"
#include "responder/kcm/kcmsrv_ccache.h"

/* This limit comes from:
* https://github.com/krb5/krb5/blob/master/src/lib/krb5/ccache/cc_kcm.c#L53
*/
#define KCM_REPLY_MAX 10*1024*1024

struct kcm_op_ctx {
struct kcm_resp_ctx *kcm_data;
struct kcm_conn_data *conn_data;
Expand Down Expand Up @@ -114,8 +109,8 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_LIBS, "%zu bytes on KCM input\n", input->length);

state->reply = sss_iobuf_init_empty(state,
KCM_REPLY_MAX,
KCM_REPLY_MAX);
KCM_PACKET_INITIAL_SIZE,
KCM_PACKET_MAX_SIZE);
if (state->reply == NULL) {
ret = ENOMEM;
goto immediate;
Expand Down Expand Up @@ -159,8 +154,8 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
*/
state->op_ctx->reply = sss_iobuf_init_empty(
state,
KCM_REPLY_MAX - 2*sizeof(uint32_t),
KCM_REPLY_MAX - 2*sizeof(uint32_t));
KCM_PACKET_INITIAL_SIZE,
KCM_PACKET_MAX_SIZE - 2*sizeof(uint32_t));
if (state->op_ctx->reply == NULL) {
ret = ENOMEM;
goto immediate;
Expand Down Expand Up @@ -879,7 +874,7 @@ static struct tevent_req *kcm_op_store_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_LIBS, "Storing credentials for %s\n", name);

creds_len = sss_iobuf_get_size(op_ctx->input) - strlen(name) -1;
if (creds_len > KCM_REPLY_MAX) {
if (creds_len > KCM_PACKET_MAX_SIZE) {
/* Protects against underflows and in general adds sanity */
ret = E2BIG;
goto immediate;
Expand Down
21 changes: 21 additions & 0 deletions src/responder/kcm/kcmsrv_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@
#include "util/sss_iobuf.h"
#include "responder/kcm/kcmsrv_pvt.h"

/* The initial packet size, which can later be grown up to KCM_PACKET_MAX_SIZE.
* The kernel will allocate whole pages even if less is requested, and the
* buffer size will probably grow. Intermediate allocators might assign a part
* of a page to different allocations, but growing the buffer would take more
* time as it would also require to move the existing structure.
* So, allocating this small but not tiny amount of memory is a trade off to
* achieve an acceptable performance while not allocating enormous amounts of
* memory.
* We could use `sysconf(_SC_PAGE_SIZE)` to determine the page size, but that
* would imply calling the function each time. So we manually force the value
* which is by now quite unrelated to the physical page size.
*/
#define KCM_PACKET_INITIAL_SIZE 4096

/* The maximum length of a request or reply as defined by the RPC
* protocol. This is the same constant size as MIT KRB5 uses
* This limit comes from:
* https://github.com/krb5/krb5/blob/c20251dafd6120fa08c76b19315cb9deb1a1b24e/src/lib/krb5/ccache/cc_kcm.c#L54
*/
#define KCM_PACKET_MAX_SIZE 10*1024*1024

struct kcm_op;
struct kcm_op *kcm_get_opt(uint16_t opcode);
const char *kcm_opt_name(struct kcm_op *op);
Expand Down

0 comments on commit cf1994e

Please sign in to comment.