Bug 27462 (CVE-2021-27645)

Summary: double-free in nscd (CVE-2021-27645)
Product: glibc Reporter: Siddhesh Poyarekar <siddhesh>
Component: nscdAssignee: dj <dj>
Status: RESOLVED FIXED    
Severity: normal CC: carlos, carnil, crushor, drepper.fsp, sam
Priority: P2 Flags: siddhesh: security+
Version: unspecified   
Target Milestone: 2.34   
Host: Target:
Build: Last reconfirmed:

Description Siddhesh Poyarekar 2021-02-24 07:46:09 UTC
The following upstream patch:

commit 745664bd798ec8fd50438605948eea594179fba1
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 28 13:19:27 2018 +0200

    nscd: Fix use-after-free in addgetnetgrentX [BZ #23520]
    
    addinnetgrX may use the heap-allocated buffer, so free the buffer
    in this function.

introduced a double free bug because reference to an already freed object may escape into tofree.  The worst case impact is an nscd crash (and hence DoS) due to the double free.  The freed object does not get used anywhere, so there's no use-after-free.

Here's a potential (untested) fix proposed by Carlos O'Donell.


diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index dba6ceec1b..ad2daddafd 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -248,7 +248,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
                                             : NULL);
                                    ndomain = (ndomain ? newbuf + ndomaindiff
                                               : NULL);
-                                   buffer = newbuf;
+                                   *tofreep = buffer = newbuf;
                                  }
 
                                nhost = memcpy (buffer + bufused,
@@ -319,7 +319,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
                    else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
                      {
                        buflen *= 2;
-                       buffer = xrealloc (buffer, buflen);
+                       *tofreep = buffer = xrealloc (buffer, buflen);
                      }
                    else if (status == NSS_STATUS_RETURN
                             || status == NSS_STATUS_NOTFOUND
---
Comment 1 crushor 2021-02-27 05:08:45 UTC
accoring to xrealloc manual
   If there is not enough memory in the memory pool to satisfy the memory request, a null pointer is returned and the original memory block is not affected.

so , is it safety which using return value of xrealloc without checking?
Comment 2 dj@redhat.com 2021-02-27 05:43:00 UTC
You're reading the documentation for realloc, not xrealloc.  xrealloc cannot return NULL.
Comment 3 crushor 2021-02-27 06:02:40 UTC
(In reply to dj@redhat.com from comment #2)
> You're reading the documentation for realloc, not xrealloc.  xrealloc cannot
> return NULL.

sure, you are right.

by the way , another question is: why redhat assigns a 7.5 score for it ?
AC is network, and AI is high. 

nscd provides caching for accesses of the passwd(5), group(5),
       hosts(5) services(5) and netgroup databases through standard libc
       interfaces, such as getpwnam(3), getpwuid(3), getgrnam(3),
       getgrgid(3), gethostbyname(3), and others.
Comment 4 Siddhesh Poyarekar 2021-03-01 02:22:53 UTC
(In reply to crushor from comment #3)
> (In reply to dj@redhat.com from comment #2)
> > You're reading the documentation for realloc, not xrealloc.  xrealloc cannot
> > return NULL.
> 
> sure, you are right.
> 
> by the way , another question is: why redhat assigns a 7.5 score for it ?
> AC is network, and AI is high. 

IMO the score is incorrect because at least:

- AV should be local because nscd doesn't listen on remote requests.

- AC should be high since it is constrained by needing a netgroup request to have a response larger than 1K to cause the double-free crash

- A (availability impact) is low since nscd crashing (the freed pointer is not used anywhere in the code path, so there's no UAF) will merely cause a direct request to authentication servers and incur a performance penalty, it won't be a full on denial of service.
Comment 5 Siddhesh Poyarekar 2021-03-03 05:02:51 UTC
https://sourceware.org/git/?p=glibc.git;a=commit;h=dca565886b5e8bd7966e15f0ca42ee5cff686673

commit dca565886b5e8bd7966e15f0ca42ee5cff686673
Author: DJ Delorie <dj@redhat.com>
Date:   Thu Feb 25 16:08:21 2021 -0500

    nscd: Fix double free in netgroupcache [BZ #27462]
    
    In commit 745664bd798ec8fd50438605948eea594179fba1 a use-after-free
    was fixed, but this led to an occasional double-free.  This patch
    tracks the "live" allocation better.
    
    Tested manually by a third party.
    
    Related: RHBZ 1927877
    
    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>