mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 03:33:33 +08:00
nscd: Fix use-after-free in addgetnetgrentX [BZ #23520]
addinnetgrX may use the heap-allocated buffer, so free the buffer
in this function.
(cherry picked from commit 745664bd79
)
This commit is contained in:
parent
3668134a9e
commit
2777e19c05
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
2018-08-28 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
[BZ #23520]
|
||||
nscd: Fix use-after-free in addgetnetgrentX and its callers.
|
||||
* nscd/netgroupcache.c
|
||||
(addgetnetgrentX): Add tofreep parameter. Do not free
|
||||
heap-allocated buffer.
|
||||
(addinnetgrX): Free buffer allocated bt addgetnetgrentX.
|
||||
(addgetnetgrentX_ignore): New function.
|
||||
(addgetnetgrent): Call it.
|
||||
(readdgetnetgrent): Likewise.
|
||||
|
||||
2019-02-01 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* support/support_test_compare_string.c
|
||||
|
1
NEWS
1
NEWS
@ -163,6 +163,7 @@ The following bugs are resolved with this release:
|
||||
[23363] stdio-common/tst-printf.c has non-free license
|
||||
[23456] Wrong index_cpu_LZCNT
|
||||
[23459] COMMON_CPUID_INDEX_80000001 isn't populated for Intel processors
|
||||
[23520] nscd: nscd: Use-after-free in addgetnetgrentX and its callers
|
||||
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
|
||||
[23562] signal: Use correct type for si_band in siginfo_t
|
||||
[23579] libc: Errors misreported in preadv2
|
||||
|
@ -113,7 +113,8 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
|
||||
static time_t
|
||||
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
const char *key, uid_t uid, struct hashentry *he,
|
||||
struct datahead *dh, struct dataset **resultp)
|
||||
struct datahead *dh, struct dataset **resultp,
|
||||
void **tofreep)
|
||||
{
|
||||
if (__glibc_unlikely (debug_level > 0))
|
||||
{
|
||||
@ -139,6 +140,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
size_t group_len = strlen (key) + 1;
|
||||
struct name_list *first_needed
|
||||
= alloca (sizeof (struct name_list) + group_len);
|
||||
*tofreep = NULL;
|
||||
|
||||
if (netgroup_database == NULL
|
||||
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
|
||||
@ -151,6 +153,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
|
||||
memset (&data, '\0', sizeof (data));
|
||||
buffer = xmalloc (buflen);
|
||||
*tofreep = buffer;
|
||||
first_needed->next = first_needed;
|
||||
memcpy (first_needed->name, key, group_len);
|
||||
data.needed_groups = first_needed;
|
||||
@ -465,8 +468,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
}
|
||||
|
||||
out:
|
||||
free (buffer);
|
||||
|
||||
*resultp = dataset;
|
||||
|
||||
return timeout;
|
||||
@ -503,8 +504,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
group, group_len,
|
||||
db, uid);
|
||||
time_t timeout;
|
||||
void *tofree;
|
||||
if (result != NULL)
|
||||
timeout = result->head.timeout;
|
||||
{
|
||||
timeout = result->head.timeout;
|
||||
tofree = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
request_header req_get =
|
||||
@ -513,7 +518,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
.key_len = group_len
|
||||
};
|
||||
timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
|
||||
&result);
|
||||
&result, &tofree);
|
||||
}
|
||||
|
||||
struct indataset
|
||||
@ -586,7 +591,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
++dh->nreloads;
|
||||
if (cacheable)
|
||||
pthread_rwlock_unlock (&db->lock);
|
||||
return timeout;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (he == NULL)
|
||||
@ -649,17 +654,30 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
dh->usable = false;
|
||||
}
|
||||
|
||||
out:
|
||||
free (tofree);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
|
||||
static time_t
|
||||
addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
|
||||
const char *key, uid_t uid, struct hashentry *he,
|
||||
struct datahead *dh)
|
||||
{
|
||||
struct dataset *ignore;
|
||||
void *tofree;
|
||||
time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
|
||||
&ignore, &tofree);
|
||||
free (tofree);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
void
|
||||
addgetnetgrent (struct database_dyn *db, int fd, request_header *req,
|
||||
void *key, uid_t uid)
|
||||
{
|
||||
struct dataset *ignore;
|
||||
|
||||
addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore);
|
||||
addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -672,10 +690,8 @@ readdgetnetgrent (struct database_dyn *db, struct hashentry *he,
|
||||
.type = GETNETGRENT,
|
||||
.key_len = he->len
|
||||
};
|
||||
struct dataset *ignore;
|
||||
|
||||
return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh,
|
||||
&ignore);
|
||||
return addgetnetgrentX_ignore
|
||||
(db, -1, &req, db->data + he->key, he->owner, he, dh);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user