Re: [PATCH 1/3] libsepol: do not pass NULL to memcpy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 16 Oct 2021 at 21:30, Nicolas Iooss <nicolas.iooss@xxxxxxx> wrote:
>
> On Wed, Oct 13, 2021 at 2:54 PM Christian Göttsche
> <cgzones@xxxxxxxxxxxxxx> wrote:
> >
> > For the first iteration `mod->perm_map[sclassi]` is NULL, thus do not
> > use it as source of a memcpy(3), even with a size of 0.  memcpy(3) might
> > be annotated with the function attribute nonnull and UBSan then
> > complains:
> >
> >     link.c:193:3: runtime error: null pointer passed as argument 2, which is declared to never be null
> >
> > Use a realloc + memset instead of a calloc and free to increase the size
> > of `mod->perm_map[sclassi]`.
> >
> > Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
> > ---
> >  libsepol/src/link.c | 6 ++----
> >  1 file changed, 2 insertions(+), 4 deletions(-)
> >
> > diff --git a/libsepol/src/link.c b/libsepol/src/link.c
> > index 7512a4d9..75ce2b20 100644
> > --- a/libsepol/src/link.c
> > +++ b/libsepol/src/link.c
> > @@ -185,14 +185,12 @@ static int permission_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
> >          * may have originated from the class -or- it could be from
> >          * the class's common parent.*/
> >         if (perm->s.value > mod->perm_map_len[sclassi]) {
> > -               uint32_t *newmap = calloc(perm->s.value, sizeof(*newmap));
> > +               uint32_t *newmap = realloc(mod->perm_map[sclassi], perm->s.value * sizeof(*newmap));
>
> Hello,
> It seems sad to transform a calloc call to an explicit multiplication
> which can overflow. Nowadays glibc provides reallocarray, for a
> "realloc with multiplication overflow checking". Could you use it here
> instead?
>

Yes, I thought about that, but I wanted this diff to be as small as possible.
One option would be to wait until reallocarray is available (via
fallback or requirement (see later)) or keep the calloc+memcpy, but
not invoke the memset on a size of 0.

> I saw in another patch ([RFC PATCH 09/35] libsepol: use reallocarray
> wrapper to avoid overflows ;
> https://lore.kernel.org/selinux/20211011162533.53404-10-cgzones@xxxxxxxxxxxxxx/T/#u)
> that you introduced reallocarray calls in other places, with a
> fallback implementation for systems which lack it. When I saw it, I
> was wondering: which C library does not provide this function?
>
> - glibc has it since version 2.29 (according to
> https://man7.org/linux/man-pages/man3/realloc.3.html ; this version
> was released on 2019-02-01)
> - musl has it since version 1.2.2 (thanks to
> https://git.musl-libc.org/cgit/musl/commit/?id=821083ac7b54eaa040d5a8ddc67c6206a175e0ca
> ; released on 2021-01-15)
> - bionic has it since 2018
> (https://android.googlesource.com/platform/bionic/+/b177085ce7219562eecf77f2e8de49f8f2605005%5E%21/)
> - newlib has it since 2017
> (https://sourceware.org/git/?p=newlib-cygwin.git;a=commitdiff;h=eb14d0cc649978c10928bf38c1847f295bf0de69)
>
> However uclic-ng 1.0.39 (released ten days ago) does not provide
> reallocarray. It is the only maintained and open-source C library
> compatible with Linux that I could find which would not provide
> reallocarray. Did I miss a library which is likely to be used by
> libsepol users?
>
> In my humble opinion, this means that for future releases we can
> consider that systems are expected to provide reallocarray, and that
> we can introduce a Makefile variable which would introduce a custom
> internal reallocarray implementation in libsepol. This means that I
> suggest using something like this in libsepol/src/Makefile:
>
> USE_INTERNAL_REALLOCARRAY ?= n
> ifeq (USE_INTERNAL_REALLOCARRAY, y)
>   CFLAGS += -DUSE_INTERNAL_REALLOCARRAY
> endif
>
> and I suggest putting the internal reallocarray implementation from
> your patch in libsepol/src/private.h (like you did), around "#ifdef
> USE_INTERNAL_REALLOCARRAY" statements. This way, libsepol would work
> out-of-the-box on most systems, would be compatible on systems without
> reallocarray by using "make USE_INTERNAL_REALLOCARRAY=y", and would
> not try to auto-detect it at build-time by some compiler magic in
> Makefile (which would avoid issues similar as the one libapparmor had
> in http://lists.busybox.net/pipermail/buildroot/2020-October/294691.html).
> What do you think of these suggestions?
>

Looking for example at
https://github.com/SELinuxProject/selinux/commit/4859b738136ef8889fbb71a166cfec8d313ba4e0
(supporting gcc 4.8) I am not sure what compilers and standard C
libraries should be supported for building the SELinux userland
libraries and tools. Until any statement of the maintainer team, I
prefer the Makefile hack from
https://lore.kernel.org/selinux/20211011162533.53404-10-cgzones@xxxxxxxxxxxxxx/T/#u
to support standard C libraries without reallocarray(3).


> Thanks,
> Nicolas
>
> >                 if (newmap == NULL) {
> >                         ERR(state->handle, "Out of memory!");
> >                         return -1;
> >                 }
> > -               memcpy(newmap, mod->perm_map[sclassi],
> > -                      mod->perm_map_len[sclassi] * sizeof(*newmap));
> > -               free(mod->perm_map[sclassi]);
> > +               memset(newmap + mod->perm_map_len[sclassi], '\0', perm->s.value - mod->perm_map_len[sclassi]);
> >                 mod->perm_map[sclassi] = newmap;
> >                 mod->perm_map_len[sclassi] = perm->s.value;
> >         }
> > --
> > 2.33.0
> >
>




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux