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

Freeze .rodata before trying to load programs #1159

Merged
merged 2 commits into from
Oct 10, 2023

Conversation

ti-mo
Copy link
Collaborator

@ti-mo ti-mo commented Oct 6, 2023

As reported in #1143 and #1156.

The change is fairly minimal, had to reindent most of populateMaps().

The gist of it is cl.loadMap() now finalizes maps that can be finalized right after loading, aka. 'scalar' maps without references to other bpf resources. Prog maps or outer maps are skipped.

After doing a first pass over all requested Maps and Programs, a separate pass is run by the renamed populateDeferredMaps() that only considers prog maps and outer maps, lazy-loads dependencies and fully resolves Spec.Contents, then finalizes the Map.

@ti-mo ti-mo requested a review from lmb October 6, 2023 12:48
@ti-mo ti-mo force-pushed the tb/make-rodata-const-again branch 2 times, most recently from 5f3a44d to 792bcdb Compare October 6, 2023 13:01
Copy link
Contributor

@chenhengqi chenhengqi left a comment

Choose a reason for hiding this comment

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

LGTM.

@chenhengqi
Copy link
Contributor

Testing good on my side, thanks.

elf_reader.go Outdated Show resolved Hide resolved
// potentially pending creation. This is needed for frozen maps like .rodata
// that need to be finalized before invoking the verifier.
if !mapSpec.Type.canStoreMapOrProgram() {
if err := m.finalize(mapSpec); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you remind me why we can't populate deferred maps at this point as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Map fds need to be relocated into programs before a program can be loaded, but we can't populate a prog array without creating programs first. We've split up this process into multiple stages to keep things clear. Technically, we only need to defer populating prog arrays, but we can refactor this again later if new requirements pop up.

This test fails if .rodata is not frozen when freeze_rodata() is verified.

Signed-off-by: Timo Beckers <timo@isovalent.com>
`cl.loadMap()` now finalizes maps that can be finalized right after creation,
aka. 'scalar' maps without references to other bpf resources. Prog maps or
outer maps are populated at a later stage.

After doing a first pass over all requested Maps and Programs, a separate pass
is run by `cl.populateMaps()` (renamed to `populateDeferredMaps()`) that only
considers prog maps and outer maps, lazy-loads dependencies and fully resolves
Spec.Contents, then finalizes the Map.

This fixes .rodata being frozen after the verifier has run, which not only
defeats the point of having constants, but also causes verifier errors if
a runtime-provided constant is used as a return code or helper argument that
must be proven to be within a certain range during verification.

Signed-off-by: Timo Beckers <timo@isovalent.com>
@lmb lmb merged commit 9598c01 into cilium:main Oct 10, 2023
12 checks passed
@ti-mo ti-mo deleted the tb/make-rodata-const-again branch October 10, 2023 13:53
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.

None yet

3 participants