Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i#2283: Facilitate Umbra Layouts with Constraint Solving. #2300

Merged
merged 20 commits into from
Jan 6, 2021

Conversation

johnfxgalea
Copy link
Contributor

@johnfxgalea johnfxgalea commented Jun 19, 2020

Adds a helper python script to facilitate the setting up of Umbra Shadow Memory Layouts. Given the details of a memory layout, such as mask and disp values, the script will check whether any collisions are present with respect to the current pre-defined app regions that Umbra 64-bit considers today.

Example:

python3 umbra_layout.py --os linux --mask 0xFFFFFFFFFFF --disp 0x120000000000
Information:
	OS: linux
SUCCESS

Memory Layout:

	Disp: 0x0000120000000000
	Mask: 0x00000FFFFFFFFFFF
	Unit Size: 0x0000100000000000
	Scale: 0
	Map Count: 1 

MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000120000000000, 0x0000130000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x0000170000000000, 0x0000190000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x0000210000000000, 0x0000220000000000]

The script also uses a constraint solver (namely Z3) to check a layout as well as synthesize satisfying displacement values that result in no collisions (if sat).

Example:

python3 umbra_layout.py --os linux --scale up_2x --mask 0xFFFFFFFFFFF --verify
Information:
	OS: linux
SUCCESS

Memory Layout:

	Disp: 0x0000140000000000
	Mask: 0x00000FFFFFFFFFFF
	Unit Size: 0x0000100000000000
	Scale: 1
	Map Count: 1 

MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000280000000000, 0x00002A0000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x0000320000000000, 0x0000360000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x0000460000000000, 0x0000480000000000]

@derekbruening
Copy link
Contributor

I was going to say, don't we already have some of this: but it looks like the app I have is not checked in anywhere. It doesn't have a sat checker (used manual loops in the past). It does, however, check all the scales (up 2x, down 2x, down 4x, down 8x) for any particular setting, if you could add that here. I put it at #2301 (not to commit it just for comparison).

The checked-in test we have is umbra_client_allscales but it only checks the checked-in config.

@johnfxgalea
Copy link
Contributor Author

It does, however, check all the scales (up 2x, down 2x, down 4x, down 8x) for any particular setting.

So the script already allows one to check a layout for a given scale. I can add support to the script to check all scales but I wonder what the benefit is because Umbra associates an individual layout setting for each scale.

@derekbruening
Copy link
Contributor

It does, however, check all the scales (up 2x, down 2x, down 4x, down 8x) for any particular setting.

So the script already allows one to check a layout for a given scale. I can add support to the script to check all scales but I wonder what the benefit is because Umbra associates an individual layout setting for each scale.

That's not how I remember Umbra working: it tries to use the same setting for all scales, and only grudgingly makes an exception with a different displacement, having to do it just for one (or 2?) of the scales. Ideally there would be no exceptions, so I would want to see the results for all scales at once, preferring solutions with no exceptions.

@johnfxgalea
Copy link
Contributor Author

johnfxgalea commented Jun 20, 2020

It does, however, check all the scales (up 2x, down 2x, down 4x, down 8x) for any particular setting.

So the script already allows one to check a layout for a given scale. I can add support to the script to check all scales but I wonder what the benefit is because Umbra associates an individual layout setting for each scale.

That's not how I remember Umbra working: it tries to use the same setting for all scales, and only grudgingly makes an exception with a different displacement, having to do it just for one (or 2?) of the scales. Ideally there would be no exceptions, so I would want to see the results for all scales at once, preferring solutions with no exceptions.

Okay, no problem. I added the new option.

python3 umbra_layout.py --help
*** Umbra Shadow Memory Layout ***

usage: umbra_layout.py [-h] [--os {linux,windows8,windows81}] [--mask MASK]
                       [--disp DISP]
                       [--scale {all,down_8x,down_4x,down_2x,same,up_2x,up_4x,up_8x}]
                       [--verify] [--shadow_collision] [--max MAX]
                       [--unit UNIT] [--count COUNT]

Facilitates the set up of shadow memory layouts based on direct
mappings.Mappings are based on known Application Regions typically set up by
the OS. SHDW(app) = (app & MASK) + DISP

optional arguments:
  -h, --help            show this help message and exit
  --os {linux,windows8,windows81}
                        the operating system to consider.
  --mask MASK           the mask value applied to the app address.
  --disp DISP           the displacement value used for shadow translation.
  --scale {all,down_8x,down_4x,down_2x,same,up_2x,up_4x,up_8x}
                        scale of shadow memory with respect to app memory.
  --verify              verifies whether or not the passed value results ina
                        shadow memory layout without any collisions. If no
                        disp or mask values are passed, they will
                        besynthesized with appropriate values automatically.
                        Current implementation does not check formultiple
                        maps.
  --shadow_collision    Denotes whether to detect collisions with shadow's
                        shadow.
  --max MAX             specifies the max limit of a disp when in find mode.
  --unit UNIT           specifies the size of a unit.
  --count COUNT         specifies the number of maps.

I think the current implementation of Umbra tries the same setting for all scales by design, but on Linux, a different displacement value is used for each scale:

0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_8X */

Interestingly, the script manages to synthesize a displacement value that should be suitable for all scales, assuming only one shadow map is registered.

python3 umbra_layout.py --os linux --mask 0xFFFFFFFFFFF --verify --scale all --count 1
*** Umbra Shadow Memory Layout ***

OS: linux 

SUCCESS
Memory Layout:
	Mask: 0x00000FFFFFFFFFFF
	Disp: 0x0000080000000000
	Unit Size: 0x0000100000000000
	Scale UP: False
	Scale: 3


MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000010000000000, 0x0000012000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x000001A000000000, 0x000001E000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x000002E000000000, 0x0000030000000000]


Memory Layout:
	Mask: 0x00000FFFFFFFFFFF
	Disp: 0x0000080000000000
	Unit Size: 0x0000100000000000
	Scale UP: False
	Scale: 2


MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000020000000000, 0x0000024000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x0000034000000000, 0x000003C000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x000005C000000000, 0x0000060000000000]


Memory Layout:
	Mask: 0x00000FFFFFFFFFFF
	Disp: 0x0000080000000000
	Unit Size: 0x0000100000000000
	Scale UP: False
	Scale: 1


MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000040000000000, 0x0000048000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x0000068000000000, 0x0000078000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x00000B8000000000, 0x00000C0000000000]


Memory Layout:
	Mask: 0x00000FFFFFFFFFFF
	Disp: 0x0000080000000000
	Unit Size: 0x0000100000000000
	Scale UP: True
	Scale: 0


MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000080000000000, 0x0000090000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x00000D0000000000, 0x00000F0000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x0000170000000000, 0x0000180000000000]


Memory Layout:
	Mask: 0x00000FFFFFFFFFFF
	Disp: 0x0000080000000000
	Unit Size: 0x0000100000000000
	Scale UP: True
	Scale: 1


MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000100000000000, 0x0000120000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x00001A0000000000, 0x00001E0000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x00002E0000000000, 0x0000300000000000]


Memory Layout:
	Mask: 0x00000FFFFFFFFFFF
	Disp: 0x0000080000000000
	Unit Size: 0x0000100000000000
	Scale UP: True
	Scale: 2


MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000200000000000, 0x0000240000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x0000340000000000, 0x00003C0000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x00005C0000000000, 0x0000600000000000]


Memory Layout:
	Mask: 0x00000FFFFFFFFFFF
	Disp: 0x0000080000000000
	Unit Size: 0x0000100000000000
	Scale UP: True
	Scale: 3


MAP 0
	app0:	 [0x0000000000000000, 0x0000010000000000] : exec,heap, data
	shd0:	 [0x0000400000000000, 0x0000480000000000]


	app1:	 [0x0000550000000000, 0x0000570000000000] : pie
	shd1:	 [0x0000680000000000, 0x0000780000000000]


	app2:	 [0x00007F0000000000, 0x0000800000000000] : lib, map, stack, vdso
	shd2:	 [0x0000B80000000000, 0x0000C00000000000]

If I try to consider additional maps, separated by 2 units, a single setting for all scales seems to be unsat on Linux.

python3 umbra_layout.py --os linux --mask 0xFFFFFFFFFFF --verify --scale all --count 2
*** Umbra Shadow Memory Layout ***

OS: linux 

FAILED

@derekbruening
Copy link
Contributor

@johnfxgalea -- is this mergeable? It may be very useful for #2328 where shadow layout problems are blocking us.

@johnfxgalea
Copy link
Contributor Author

Yep, it is ready to be merged but still awaiting a review I think.

@derekbruening
Copy link
Contributor

Yep, it is ready to be merged but still awaiting a review I think.

Oh, whoops. Though no longer sure #2328 is really a layout issue: may instead be an initialization/address walk issue at init time.

tools/umbra_layout.py Outdated Show resolved Hide resolved
tools/umbra_layout.py Show resolved Hide resolved
tools/umbra_layout.py Outdated Show resolved Hide resolved
@johnfxgalea
Copy link
Contributor Author

Done. PTAL. I added some further comments.

Copy link
Contributor

@derekbruening derekbruening left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Unfotunately the CI has been in bad shape for a while...I moved unix to Github Actions, and am trying to move Windows there and make it green too, but there are many problems to resolve.)

@derekbruening
Copy link
Contributor

Xref #1712: we're hitting umbra shadow mapping failures up front on Linux on Github Actions.

@derekbruening
Copy link
Contributor

I thought I got Windows green -- are those flakes? Add to the ignore list?

@johnfxgalea
Copy link
Contributor Author

I thought I got Windows green -- are those flakes? Add to the ignore list?

Does not seem to be a flake, with the following stable error:

Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found."

@johnfxgalea
Copy link
Contributor Author

I thought I got Windows green -- are those flakes? Add to the ignore list?

Does not seem to be a flake, with the following stable error:

Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found."

@derekbruening Any idea what the above error is about please? Happy to investigate further, but just wondering if you have any idea?

@derekbruening
Copy link
Contributor

I thought I got Windows green -- are those flakes? Add to the ignore list?

Does not seem to be a flake, with the following stable error:
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found."

@derekbruening Any idea what the above error is about please? Happy to investigate further, but just wondering if you have any idea?

If that's downloading doxygen is it related to DynamoRIO/dynamorio#4654?

@johnfxgalea
Copy link
Contributor Author

johnfxgalea commented Jan 5, 2021

I thought I got Windows green -- are those flakes? Add to the ignore list?

Does not seem to be a flake, with the following stable error:
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found."

@derekbruening Any idea what the above error is about please? Happy to investigate further, but just wondering if you have any idea?

If that's downloading doxygen is it related to DynamoRIO/dynamorio#4654?

No. Dr Memory's CI is making use of a stale URL (http://doxygen.nl/files/doxygen-1.8.19.windows.x64.bin.zip) here:

(New-Object System.Net.WebClient).DownloadFile("http://doxygen.nl/files/doxygen-1.8.19.windows.x64.bin.zip", "c:\projects\install\doxygen.zip")

@derekbruening
Copy link
Contributor

derekbruening commented Jan 5, 2021

No. Dr Memory's CI is making use of a stale URL (http://doxygen.nl/files/doxygen-1.8.19.windows.x64.bin.zip) here:

(New-Object System.Net.WebClient).DownloadFile("http://doxygen.nl/files/doxygen-1.8.19.windows.x64.bin.zip", "c:\projects\install\doxygen.zip")

Ah yeah it needs the equiv of PR DynamoRIO/dynamorio#4643

@johnfxgalea
Copy link
Contributor Author

CI failures concern #2250 and #2341

This PR does not concern these issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants