Verify output space before doing heavy work in mallctl

This commit is contained in:
Yinan Zhang 2020-07-22 14:46:43 -07:00
parent f5fb4e5a97
commit fb347dc618
2 changed files with 42 additions and 16 deletions

View File

@ -1760,7 +1760,16 @@ malloc_conf = "xmalloc:true";]]></programlisting>
automatically managed one that is used by default. Each explicit cache automatically managed one that is used by default. Each explicit cache
can be used by only one thread at a time; the application must assure can be used by only one thread at a time; the application must assure
that this constraint holds. that this constraint holds.
</para>
<para>If the amount of space supplied for storing the thread-specific
cache identifier does not equal
<code language="C">sizeof(<type>unsigned</type>)</code>, no
thread-specific cache will be created, no data will be written to the
space pointed by <parameter>oldp</parameter>, and
<parameter>*oldlenp</parameter> will be set to 0.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="tcache.flush"> <varlistentry id="tcache.flush">
@ -2300,7 +2309,14 @@ struct extent_hooks_s {
</term> </term>
<listitem><para>Explicitly create a new arena outside the range of <listitem><para>Explicitly create a new arena outside the range of
automatically managed arenas, with optionally specified extent hooks, automatically managed arenas, with optionally specified extent hooks,
and return the new arena index.</para></listitem> and return the new arena index.</para>
<para>If the amount of space supplied for storing the arena index does
not equal <code language="C">sizeof(<type>unsigned</type>)</code>, no
arena will be created, no data will be written to the space pointed by
<parameter>oldp</parameter>, and <parameter>*oldlenp</parameter> will
be set to 0.
</para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="arenas.lookup"> <varlistentry id="arenas.lookup">
@ -3607,7 +3623,8 @@ MAPPED_LIBRARIES:
<listitem><para><parameter>newp</parameter> is not <listitem><para><parameter>newp</parameter> is not
<constant>NULL</constant>, and <parameter>newlen</parameter> is too <constant>NULL</constant>, and <parameter>newlen</parameter> is too
large or too small. Alternatively, <parameter>*oldlenp</parameter> large or too small. Alternatively, <parameter>*oldlenp</parameter>
is too large or too small; in this case as much data as possible is too large or too small; when it happens, except for a very few
cases explicitly documented otherwise, as much data as possible
are read despite the error, with the amount of data read being are read despite the error, with the amount of data read being
recorded in <parameter>*oldlenp</parameter>.</para></listitem> recorded in <parameter>*oldlenp</parameter>.</para></listitem>
</varlistentry> </varlistentry>

View File

@ -1488,6 +1488,15 @@ ctl_mtx_assert_held(tsdn_t *tsdn) {
} \ } \
} while (0) } while (0)
/* Verify that the space provided is enough. */
#define VERIFY_READ(t) do { \
if (oldp == NULL || oldlenp == NULL || *oldlenp != sizeof(t)) { \
*oldlenp = 0; \
ret = EINVAL; \
goto label_return; \
} \
} while (0)
#define READ(v, t) do { \ #define READ(v, t) do { \
if (oldp != NULL && oldlenp != NULL) { \ if (oldp != NULL && oldlenp != NULL) { \
if (*oldlenp != sizeof(t)) { \ if (*oldlenp != sizeof(t)) { \
@ -2103,6 +2112,7 @@ tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
unsigned tcache_ind; unsigned tcache_ind;
READONLY(); READONLY();
VERIFY_READ(unsigned);
if (tcaches_create(tsd, b0get(), &tcache_ind)) { if (tcaches_create(tsd, b0get(), &tcache_ind)) {
ret = EFAULT; ret = EFAULT;
goto label_return; goto label_return;
@ -2608,10 +2618,6 @@ arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
READONLY(); READONLY();
if (*oldlenp != sizeof(unsigned)) {
ret = EINVAL;
goto label_return;
}
narenas = ctl_arenas->narenas; narenas = ctl_arenas->narenas;
READ(narenas, unsigned); READ(narenas, unsigned);
@ -2702,6 +2708,7 @@ arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
VERIFY_READ(unsigned);
extent_hooks = (extent_hooks_t *)&ehooks_default_extent_hooks; extent_hooks = (extent_hooks_t *)&ehooks_default_extent_hooks;
WRITE(extent_hooks, extent_hooks_t *); WRITE(extent_hooks, extent_hooks_t *);
if ((arena_ind = ctl_arena_init(tsd, extent_hooks)) == UINT_MAX) { if ((arena_ind = ctl_arena_init(tsd, extent_hooks)) == UINT_MAX) {
@ -2731,12 +2738,14 @@ arenas_lookup_ctl(tsd_t *tsd, const size_t *mib,
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
WRITE(ptr, void *); WRITE(ptr, void *);
edata = emap_edata_lookup(tsd_tsdn(tsd), &arena_emap_global, ptr); edata = emap_edata_lookup(tsd_tsdn(tsd), &arena_emap_global, ptr);
if (edata == NULL) if (edata == NULL) {
goto label_return; goto label_return;
}
arena = arena_get_from_edata(edata); arena = arena_get_from_edata(edata);
if (arena == NULL) if (arena == NULL) {
goto label_return; goto label_return;
}
arena_ind = arena_ind_get(arena); arena_ind = arena_ind_get(arena);
READ(arena_ind, unsigned); READ(arena_ind, unsigned);