On Thu, Feb 1, 2024 at 8:05 PM Theo de Raadt deraadt@openbsd.org wrote:
Jeff Xu jeffxu@google.com wrote:
To me, the most important thing is to deliver a feature that's easy to use and works well. I don't want users to mess things up, so if I'm the one giving them the tools, I'm going to make sure they have all the information they need and that there are safeguards in place.
e.g. considering the following user case: 1> a security sensitive data is allocated from heap, using malloc, from the software component A, and filled with information. 2> software component B then uses mprotect to change it to RO, and seal it using mseal().
p = malloc(80); mprotect(p & ~4095, 4096, PROT_NONE); free(p);
Will you save such a developer also? No.
Since the same problem you describe already exists with mprotect() what does mseal() even have to do with your proposal?
What about this?
p = malloc(80); munmap(p & ~4095, 4096); free(p);
And since it is not sealed, how about madvise operations on a proper non-malloc memory allocation? Well, the process smashes it's own memory. And why is it not sealed? You make it harder to seal memory!
How about this?
p = malloc(80); bzero(p, 100000;
Yes it is a buffer overflow. But this is all the same class of software problem:
Memory belongs to processes, which belongs to the program, which is coded by the programmer, who has to learn to be careful and handle the memory correctly.
mseal() / mimmutable() add *no new expectation* to a careful programmer, because they expected to only use it on memory that they *promise will never be de-allocated or re-permissioned*.
What you are proposing is not a "mitigation", it entirely cripples the proposed subsystem because you are afraid of it; because you have cloned a memory subsystem primitive you don't fully understand; and this is because you've not seen a complete operating system using it.
When was the last time you developed outside of Chrome?
This is systems programming. The kernel supports all the programs, not just the one holy program from god.
Even without free. I personally do not like the heap getting sealed like that.
Component A. p=malloc(4096); writing something to p.
Component B: mprotect(p,4096, RO) mseal(p,4096)
This will split the heap VMA, and prevent the heap from shrinking, if this is in a frequent code path, then it might hurt the process's memory usage.
The existing code is more likely to use malloc than mmap(), so it is easier for dev to seal a piece of data belonging to another component. I hope this pattern is not wide-spreading.
The ideal way will be just changing the library A to use mmap.