[Top][All Lists]

[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

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

#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

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]