Bug 31677 (CVE-2024-33599) - nscd: netgroup cache: invalid memcpy under low memory/storage conditions
Summary: nscd: netgroup cache: invalid memcpy under low memory/storage conditions
Status: RESOLVED FIXED
Alias: CVE-2024-33599
Product: glibc
Classification: Unclassified
Component: nscd (show other bugs)
Version: 2.40
: P2 normal
Target Milestone: 2.40
Assignee: Florian Weimer
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-04-23 20:20 UTC by Carlos O'Donell
Modified: 2024-04-25 21:00 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Carlos O'Donell 2024-04-23 20:20:28 UTC
nscd/netgroupcache.c (addinnetgrX):

497   struct indataset
498   {
499     struct datahead head;
500     innetgroup_response_header resp;
501   } *dataset
502       = (struct indataset *) mempool_alloc (db,
503                                             sizeof (*dataset) + req->key_len,
504                                             1);

mempool_alloc fails and returns NULL.

This is possible if posix_fallocate fails and the retry fails.

505   struct indataset dataset_mem;
506   bool cacheable = true;
507   if (__glibc_unlikely (dataset == NULL))
508     {
509       cacheable = false;
510       dataset = &dataset_mem;

This structure has no room for req->key_len material.

511     }
512 
513   datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
514                      sizeof (innetgroup_response_header),
515                      he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
516   /* Set the notfound status and timeout based on the result from
517      getnetgrent.  */
518   dataset->head.notfound = result->head.notfound;
519   dataset->head.timeout = timeout;
520 
521   dataset->resp.version = NSCD_VERSION;
522   dataset->resp.found = result->resp.found;
523   /* Until we find a matching entry the result is 0.  */
524   dataset->resp.result = 0;
525 
526   char *key_copy = memcpy ((char *) (dataset + 1), group, req->key_len);

This copies up to req->key_len material to a structure that has no storage space for it.

This was detected by static code analysis.

It will only happen in the case the database runs out of memory/storage while expanding the netgroup cache.

The group entries overwrite other data on the stack after dataset_mem.

The workaround is not to cache the netgroup if this is impacting the use of the application.
Comment 1 Florian Weimer 2024-04-25 13:36:42 UTC
Fixed for glibc 2.40 via:

commit 87801a8fd06db1d654eea3e4f7626ff476a9bdaa
Author: Florian Weimer <fweimer@redhat.com>
Date:   Thu Apr 25 15:00:45 2024 +0200

    CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677)
    
    Using alloca matches what other caches do.  The request length is
    bounded by MAXKEYLEN.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>