On 06.06.2018 00:56, Valery Ushakov wrote: > On Tue, Jun 05, 2018 at 22:04:37 +0200, Kamil Rytarowski wrote: > >> On 05.06.2018 20:47, Valery Ushakov wrote: >>> Kamil Rytarowski <n...@gmx.com> wrote: >>> >>>> On 05.06.2018 18:14, Valery Ushakov wrote: >>>>> Kamil Rytarowski <n...@gmx.com> 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. >
Generating runtime wrapper code for compare isn't that simple, and doing it in a portable across CPUs in C/asm is difficult (if possible). I will solve it with compile-time macros as proposed in the patch. > >> 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)? > In the example there shall be __syscall(SYS_write, fd, buf, nbyte). > > -uwe >
signature.asc
Description: OpenPGP digital signature