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

Make bpf2c maps parser match verifier's maps parser #2543

Merged
merged 16 commits into from
Jun 28, 2023

Conversation

dthaler
Copy link
Collaborator

@dthaler dthaler commented Jun 3, 2023

Description

The verifier will parse "maps/*" sections, and is able to deal with maps sections with various record sizes. This PR updates bpf2c to use the same algorithm. In the future it would be good to refactor the verifier so the same code can be used.

Before this change, such a program would pass the verifier but bpf2c couldn't convert it.
Also upgrading to the latest verifier will fail without this PR.

Also the PR to add BTF support regressed the map_in_map_v2.c sample which stopped testing the legacy reference-by-id paths. This PR changes map_in_map_v2.c back and renames it to map_in_map_legacy_id.c for clarity. Similarly, it restores map_in_map_legacy_idx.c with the original map_in_map.c and renames the BTF map_in_map.c to map_in_map_btf.c. This ensures all three code paths for finding the inner map are tested.

Fixes #900
Fixes #2580

Note to code reviewers: this change is easiest to review by ignoring whitespace changes (since it removes an indentation level for a bunch of code). To do so in github, click "Files changed", then the gear button dropdown button just under the "Checks" and "Files changed" labels, click "Hide whitespace" then "Apply and reload".

Testing

The update to map_in_map.c results in testing this functionality.

Documentation

No impact.

@dthaler dthaler added the bug Something isn't working label Jun 3, 2023
@dthaler dthaler added this to the 2306 milestone Jun 3, 2023
Copy link
Contributor

@saxena-anurag saxena-anurag left a comment

Choose a reason for hiding this comment

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

I think there are some more places in ebpf-for-windows code, where it either assumes the maps section will always be "maps" or hard codes the maps section size. Should we fix those also in this PR?

  1. _get_program_and_map_names() (verifier.cpp) only looks for "maps" section to find the map names, and fails if any map name is not found in "maps" section.
  2. parse_maps_section_windows() assumes the map size to be sizeof(ebpf_map_definition_in_file_t)
  3. read_elf() (elfhelper.cpp) only ignores "maps" section, it should also ignore any "maps/*" sections.

size_t data_size = map_section->get_size();
size_t map_record_size = data_size / map_count;

if (data_size % map_record_size != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we have a check before this line that map_record_size != 0 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@dthaler
Copy link
Collaborator Author

dthaler commented Jun 9, 2023

I think there are some more places in ebpf-for-windows code, where it either assumes the maps section will always be "maps" or hard codes the maps section size. Should we fix those also in this PR?

  1. _get_program_and_map_names() (verifier.cpp) only looks for "maps" section to find the map names, and fails if any map name is not found in "maps" section.
  2. parse_maps_section_windows() assumes the map size to be sizeof(ebpf_map_definition_in_file_t)

Thanks. Both of those are now updated.

  1. read_elf() (elfhelper.cpp) only ignores "maps" section, it should also ignore any "maps/*" sections.

ElfHelper appears to be dead code. Filed issue #2572 for removal.

@dthaler dthaler force-pushed the maps branch 2 times, most recently from a52dca8 to 71919bd Compare June 10, 2023 21:04
@dthaler dthaler force-pushed the maps branch 2 times, most recently from 571a115 to 2ae7d4e Compare June 11, 2023 19:23
@dthaler
Copy link
Collaborator Author

dthaler commented Jun 11, 2023

Test requires vbpf/ebpf-verifier#510

@dthaler dthaler force-pushed the maps branch 2 times, most recently from 5373aba to c28a0b7 Compare June 12, 2023 17:41
@codecov
Copy link

codecov bot commented Jun 12, 2023

Codecov Report

Merging #2543 (2213908) into main (ec27659) will increase coverage by 0.02%.
The diff coverage is 92.30%.

@@            Coverage Diff             @@
##             main    #2543      +/-   ##
==========================================
+ Coverage   81.18%   81.21%   +0.02%     
==========================================
  Files         146      147       +1     
  Lines       27655    27738      +83     
==========================================
+ Hits        22452    22527      +75     
- Misses       5203     5211       +8     
Impacted Files Coverage Δ
libs/service/api_service.cpp 80.00% <ø> (ø)
tests/bpftool_tests/bpftool_tests.cpp 97.95% <ø> (ø)
tests/end_to_end/test_helper.cpp 84.63% <ø> (ø)
tests/sample/map_in_map_btf.c 100.00% <ø> (ø)
tools/bpf2c/bpf_code_generator.h 93.54% <ø> (ø)
libs/api_common/api_common.hpp 81.25% <61.53%> (-2.54%) ⬇️
tools/bpf2c/bpf_code_generator.cpp 96.06% <90.42%> (-0.31%) ⬇️
libs/api/Verifier.cpp 77.82% <95.65%> (+0.90%) ⬆️
libs/api/windows_platform.cpp 97.05% <96.66%> (+1.22%) ⬆️
libs/api/ebpf_api.cpp 84.28% <100.00%> (+0.13%) ⬆️
... and 7 more

... and 2 files with indirect coverage changes

@dthaler
Copy link
Collaborator Author

dthaler commented Jun 12, 2023

blocked on vbpf/ebpf-verifier#506 which is fixed in vbpf/ebpf-verifier#511

@dthaler dthaler added the blocked Blocked on another issue that must be done first label Jun 12, 2023
@dthaler dthaler removed the blocked Blocked on another issue that must be done first label Jun 15, 2023
@dthaler dthaler enabled auto-merge June 26, 2023 19:45
Copy link
Collaborator

@shpalani shpalani left a comment

Choose a reason for hiding this comment

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

The curious question behind the changes:
Is the goal to support more than one verifier (from different vendors)?
Or,
Is the goal to support different versions of the same vendor's verifier?

Reason: I see the map query definition by id. So, how is the id determined?

@dthaler
Copy link
Collaborator Author

dthaler commented Jun 27, 2023

The curious question behind the changes: Is the goal to support more than one verifier (from different vendors)? Or, Is the goal to support different versions of the same vendor's verifier?

No. The goal is just to support PREVAIL and have ebpf-for-windows and prevail match in terms of what map capabilities they support.

Reason: I see the map query definition by id. So, how is the id determined?

In a file, it's specified in the BPF program code. See https://github.com/microsoft/ebpf-for-windows/pull/2543/files#diff-c0a7a085a58201871e764452242c7f7fbc723b2dbd8762f3ae879d8c9faddf8cR16 (which is not new code, this restores code that used to be there that was incorrectly deleted in a previous PR).

dthaler added 14 commits June 28, 2023 09:04
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
The verifier will parse "maps/*" sections, and is able to deal with
maps sections with various record sizes.  This PR updates bpf2c to
use the same algorithm.  In the future it would be good to refactor
the verifier so the same code can be used.

Fixes microsoft#900

Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Temporarily point to fork until vbpf/ebpf-verifier#515
is merged, so we can verify the fix in CI/CD.

Signed-off-by: Dave Thaler <dthaler@microsoft.com>
@@ -1631,13 +1631,13 @@ TEST_CASE("simple hash of maps", "[libbpf]") { _ebpf_test_map_in_map(BPF_MAP_TYP

// Verify an app can communicate with an eBPF program via an array of maps.
static void
_array_of_maps_test(ebpf_execution_type_t execution_type)
_array_of_btf_maps_test(ebpf_execution_type_t execution_type)
Copy link
Contributor

Choose a reason for hiding this comment

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

_array_of_btf_maps_test() and _array_of_id_maps_test() look identical except for the file name used. Maybe we can refactor them into a single function and pass file name as input?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good idea, done

@@ -1745,15 +1746,15 @@ _array_of_maps2_test(ebpf_execution_type_t execution_type)
bpf_object__close(xdp_object);
}

DECLARE_JIT_TEST_CASES("array of maps2", "[libbpf]", _array_of_maps2_test);
DECLARE_JIT_TEST_CASES("array of id maps", "[libbpf]", _array_of_id_maps_test);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add an idx version of the test also?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good idea, done

Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
@dthaler dthaler added this pull request to the merge queue Jun 28, 2023
Merged via the queue into microsoft:main with commit 8fecc2e Jun 28, 2023
@dthaler dthaler deleted the maps branch June 28, 2023 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Workflow failed - verifier_fuzzer bpf2c: make maps parser match verifier's maps parser
4 participants