[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: immutable string type
From: |
Tim Rühsen |
Subject: |
Re: immutable string type |
Date: |
Sun, 29 Dec 2019 13:07:42 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.3.1 |
On 29.12.19 10:45, Bruno Haible wrote:
> Tim Rühsen wrote:
>> the use cases are mostly in the testing area (especially fuzzing).
>
> Indeed. During fuzzing, you want to check against any kind of buggy/undefined
> behaviour, and writing into arbitrary memory is one of these kinds.
>
> This brings up the question: Should such as facility be in a Sanitizer and
> not in a library? I think the answer is "no", because
>
> - Writing into a string is not invalid in C. Even casting a 'const char *'
> to 'char *' and then writing into it is valid. The reason is that the
> C standard only makes statements about a program as a whole and therefore
> cannot express constraints such as "function A is allowed to write into
> the memory object M but function B is not".
I agree that such a thing doesn't make sense in a sanitizer, as only the
application/programmer knows about the semantics.
>
> - Integer overflow checking, for example, is available in both the
> Sanitizers
> and library code. Apparently it is useful enough that some applications
> want to have it enabled in production code. I believe the same will be
> true for immutables string or memory regions.
Makes sense, especially as lot's of code is never being fuzzed to a full
degree.
>
>> As a more general approach, a function that switches already allocated
>> memory into read-only memory would be handy. Like in
>> - m = malloc()
>> - initialize m with some data
>> - if in debug mode: call memmap_readonly(m) - from this point on 'm' is
>> read-only and a write leads to a segmentation fault.
>> - ...
>> - free(m)
>
> Hardware has write barriers only on the page level. You can't easily request
> a write barrier for a requence of, say, 30 bytes. To accomodate this, the
> API needs to have a certain shape. Paul wrote:
True, and it means that immalloc() always allocate multiples of the page
size (page is 4096 bytes on x86_64 ?). How do you plan to optimize
memory usage here ?
>
>> p = immalloc (sizeof *p);
>> p->x = whatever; p->y = something; ...
>> imfreeze (p, sizeof *p);
>> [no changes to *p allowed here]
>> imfree (p);
>
> The third line needs to be something like
>
> p = imfreeze (p, sizeof *p);
>
> because the "writable p" and the "read-only p" will be at different virtual
> addresses.
Ah, now I get it - you have two virtual memory addresses pointing to the
same physical memory area.
Just throwing in another thought as an addition to immalloc etc:
Introducing a stronger 'const' could be helpful in some situations - the
compiler could find possible violations during the build phase. Stronger
in the means of "not allowed to be cast to non-const, but allowed to be
cast to const". This can be achieved by either extending the C standard,
by adding a new option to gcc or by adding a new __attribute__ for gcc.
Example:
#define imconst __attribute__ ((immutable))
#define transfer_ptr(dst) ({ typeof(dst) _t=(dst); (dst)=NULL; _t; })
char *tmp = malloc()
... initialize tmp...
imconst char *m = transfer_ptr(tmp);
// now m is save against writing if architecture has a MMU
char *m2 = strdup(m); // allowed
memcpy(m, m2, ...); // compiler error (implicit cast 'imconst char *' to
'void *' not allowed)
memcpy((void *) m, m2, ...); // same compiler error (without 'implicit')
Maybe we can think this through to either drop it or make a suggestion
to the gcc folks.
Regards, Tim
signature.asc
Description: OpenPGP digital signature
Re: immutable string type, Ben Pfaff, 2019/12/28
Re: immutable string type, Paul Eggert, 2019/12/28