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 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 <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.
> 

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
> 


Attachment: signature.asc
Description: OpenPGP digital signature



Home | Main Index | Thread Index | Old Index