This is an archive of the discontinued LLVM Phabricator instance.

[scudo] Validate flags in MemMap and ReservedMemory methods
AbandonedPublic

Authored by fabio-d on Jun 14 2023, 11:44 AM.

Details

Reviewers
Chia-hungDuan

Diff Detail

Event Timeline

fabio-d created this revision.Jun 14 2023, 11:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 14 2023, 11:44 AM
fabio-d requested review of this revision.Jun 14 2023, 11:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 14 2023, 11:44 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript

I've allowlisted only the flags the the underlying methods actually accept in at least one platform.

The MAP_RESIZABLE flag is only meaningful on Fuchsia and we'll probably be able to get rid of it in the new design, but we have to keep it for now as it's used by the legacy implementation.

I would suggest this kind of checks to be in the platform specific implementations

Uhm, why? I think that it's super useful to add them here, so that if you want to know if you can pass a given flag when you call these methods you only have one place to look at. If these checks were in platform-specific code, you'd have to look in three different places (and hope that they don't contradict each other).

Uhm, why? I think that it's super useful to add them here, so that if you want to know if you can pass a given flag when you call these methods you only have one place to look at. If these checks were in platform-specific code, you'd have to look in three different places (and hope that they don't contradict each other).

If a flag is used or if it's valid, only can be verified on each platform. AllowedMapFlags doesn't guarantee it'll work on each platform. Like you mentioned, MAP_RESIZABLE is only meaningful on Fuchsia so far, what if it gets passed in a wrong place, when do we know that is causing problem? I think it still needs to wait until its running on Fuchsia. If a flag is not used anymore, we should just remove it. So the AllowedMapFlags is simply the flags you have defined.

I do want to clean up the map flags in common.h, for this case, I would only move those flags to mem_map_base.h

If a flag is used or if it's valid, only can be verified on each platform. AllowedMapFlags doesn't guarantee it'll work on each platform.

Yes, AllowedMapFlags does not guarantee that each flag is supported on _every_ platform. Maybe we'll get there when we fully implement the new backends, but I agree that today it is not the case.

The idea in this CL is simply to validate that callers are not doing anything spectacularly wrong (e.g. passing garbage values) and, at the same time, document what flags platforms may consider implementing (today, if you wanted to implement a new platform backend, the only way to know for sure what flags you might receive is to grep all the callers).

The way I see it is that these are the flags that callers are allowed to pass. How/if they actually they are translated into syscalls depends on the platform.

Like you mentioned, MAP_RESIZABLE is only meaningful on Fuchsia so far, what if it gets passed in a wrong place, when do we know that is causing problem? I think it still needs to wait until its running on Fuchsia.

What I'm proposing in this CL is simply to assert that MAP_RESIZABLE is a valid flag to pass to map and remap. That's it. The actual implementation is still free to ignore it.

If linux.cpp and trusty.cpp had assertions stating that MAP_RESIZABLE is *not* acceptable, we would have to change primary64.h:772, which I think we agree is not a wrong place to use this flag. A similar line of reasoning applies to MAP_PRECOMMIT and, until D152888 lands, to MAP_ALLOWNOMEM too.

fabio-d updated this revision to Diff 531731.Jun 15 2023, 6:54 AM

After discussing offline, I've removed the checks for map and remap and only left them for methods that only accept a subset of the flags (MemMap::setMemoryPermission and ReservedMemory::create)

Chia-hungDuan requested changes to this revision.Sep 25 2023, 9:28 AM

I still don't think the DCHECK here is useful. As mentioned, whether a flag has a meaning depends on the platform. It doesn't bring much benefit at the abstraction layer.

This revision now requires changes to proceed.Sep 25 2023, 9:28 AM

Even only the checks that I've left? e.g. what's the meaning of calling setMemoryPermission with any flag except MAP_NOACCESS?

Even only the checks that I've left? e.g. what's the meaning of calling setMemoryPermission with any flag except MAP_NOACCESS?

We may think a different question first, what will happen if we call setMemoryPermission with the flags other than MAP_NOACCESS? This flags are read by bit checking and if a certain flag has no meaning on the certain platforms, it does nothing. It doesn't cause any *critical* issues. Given that the meaning of a flag is pretty platform dependent, if we do need this kind of check, it should be done at platform specific side. You may always ignore some flags on a platform. If we call setMemoryPermission with a flag that has no meaning on all platforms, then we should avoid the submission of that change at the first place.

I would suggest having this kind of checks when we have some real cases that are caused by redundant flags.

fabio-d abandoned this revision.Oct 3 2023, 8:25 AM