tech-userlevel archive

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

Re: Auxiliary header and macros for sanitizers in userland programs



On Tue, Jun 05, 2018 at 22:04:37 +0200, Kamil Rytarowski wrote:

> On 05.06.2018 20:47, Valery Ushakov wrote:
> > Kamil Rytarowski <n54%gmx.com@localhost> wrote:
> > 
> >> On 05.06.2018 18:14, Valery Ushakov wrote:
> >>> Kamil Rytarowski <n54%gmx.com@localhost> wrote:
> >>>
> >>>> We've faced a problem with sanitizing part of the NetBSD userland, as we
> >>>> need to use helper functions to make sanitization possible in some
> >>>> narrow cases that aren't clear for sanitizers.
> >>>>
> >>>> The current problem is the usage of callback functions defined in
> >>>> programs and executed from the internals of libc.
> >>> [...] 
> >>>> Once a callback function is executed from the internals of libc, a
> >>>> sanitized program does not know whether the arguments passed to it are
> >>>> properly initialized.
> >>>
> >>> Why?  What makes calling from libc special?  It's probably obvious to
> >>> you since you've been workign on this for a while, but most of us have
> >>> no clue.
> > [...]
> >> In the fts_open(3) case, there is performed allocation of FTSENT
> >> entries inside libc and this buffer is passed to the callback
> >> function without prior notifying the user of fts_open(3) about these
> >> elements (their address and size of initialized buffer).  MSan does
> >> not know whether the passed arguments to the arguments of the
> >> callback are initialized or not.
> > 
> > So the issue is that libc is compiled without sanitizer and
> > allocations done inside libc are not known to a sanitizer?  For libc
> > functions that return allocated memory I guess you mark it in the
> > sanitizer's interposed wrapper ("interceptor"?), but in the case of
> > callbacks there is no interceptor between libc and the callback to do
> > that.  Is that about right?
>
[...]
> but in general the sanitizers have no
> information what happens inside libc, treating it as a blackbox.
>
[...]
>
> Interceptos mostly have rules of type PreRead/PostRead and
> PreWrite/PostWrite arguments passed to functions in libc (pthread, ..).
> In the MSan case during PreWrite there is a check whether arguments
> passed to a function are properly initialized, and in PostRead phase
> mark the buffers as initialized.
> 
> In the fts_open(3) case there is no stage between the time of being
> aware about initialzed (not just allocated) FTSENT buffers and executing
> callback function that already needs this information. In this case,
> there is need to help to Memory Sanitizer with explicit __msan_unpoison().

It sounds like sanitizers must use run-time generated closures or
compile-time generated auxiliary functions to wrap libc callbacks.
I.e. when code calls fts_open(..., compare); the sanitizer must
generate code to call fts_open(..., sanitize_compare); where
sanitize_compare does the pre/post checks around a call to the real
compare.


> There are similar cases when someone is using syscall(2) directly.
> There are helper macros and functions to make usage of
> syscall(2)-like API easier, e.g. for write(2):
> 
> __sanitizer_syscall_pre_write(fd, buf, nbyte)
> res = write(fd, buf, nbyte)
> __sanitizer_syscall_post_write(res, fd, buf, nbyte)

I'm confused, how is this write(2) example relevant to syscall(2)?


-uwe


Home | Main Index | Thread Index | Old Index