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

unify two disparate PE executable parsers we currently have into one #28955

Merged
merged 4 commits into from Aug 29, 2023

Conversation

poettering
Copy link
Member

Our codebase contains three PE binary parsers: two in userspace, one in EFI. This sucks of course. Unifying disk reading over userspace and EFI is hard, so let's avoid that for now. Let's however unify the userspace parsers already.

Except that I actually had written a 3rd PE parse in #28891 for the Authenticode hash calculation. So, actually unify three parsers into one.

This doesn't bring any features. It just unifies the two parses, moving the generic one to src/shared/pe-binary.[ch], just refactoring hence.

src/shared/kernel-image.c Fixed Show fixed Hide fixed
src/shared/kernel-image.c Fixed Show fixed Hide fixed
@medhefgo
Copy link
Contributor

Unifying disk reading over userspace and EFI is hard, so let's avoid that for now.

Well, not necessarily. For our uses, only doctored images would have headers that are larger than 4K. So you could make a unified API that only works over a provided memory block to access and handle the headers. Further convenience APIs to operate on the whole (mmapped) image can be provided to userspace, while EFI code would just use the offsets directly as it currently does…

(Just a though)

@medhefgo
Copy link
Contributor

medhefgo commented Aug 24, 2023

Alternatively, there has got to be a userspace library that we can use for this. This is one of those stupid C-dependencies-suck-so-let's-reinvent-the-wheel-instead cases.

(There is https://lief-project.github.io/doc/stable/index.html, which has a C-API, for example.)

Copy link
Contributor

@medhefgo medhefgo left a comment

Choose a reason for hiding this comment

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

PE code looks fine.

src/shared/pe-binary.h Outdated Show resolved Hide resolved
@poettering
Copy link
Member Author

Well, not necessarily. For our uses, only doctored images would have headers that are larger than 4K. So you could make a unified API that only works over a provided memory block to access and handle the headers. Further convenience APIs to operate on the whole (mmapped) image can be provided to userspace, while EFI code would just use the offsets directly as it currently does…

(Just a though)

Hmm, the problem is that the embedded DOS stub in a PE binary can be any size (i.e. it's a form of "fat" binary).

I mean, I am not saying it wouldn't be possible to get this abstracted and make it nice even, all I am saying that for now I was too lazy for that ;-)

@poettering
Copy link
Member Author

(There is https://lief-project.github.io/doc/stable/index.html, which has a C-API, for example.)

Hmm, that is not even packaged for Fedora yet. Also, looking at the code it uses unchecked malloc() in the code, which makes me quite suspicous of the code quality. And C++, uh.

I tried to find an existing implementation of the PE authenticode hash stuff that we could link to, but couldn't find anything reasonably nice. I think the implementation in our code is not overly complex. There's certainly a threshold where I'd say "hey, let's better use existing code" (and we do that in many areas, we link against so many libs after all), but I am not sure with the little PE stuff we need that point is already reached here.

src/shared/pe-binary.c Outdated Show resolved Hide resolved
@bluca bluca added reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks and removed please-review PR is ready for (re-)review by a maintainer labels Aug 28, 2023
@github-actions github-actions bot added please-review PR is ready for (re-)review by a maintainer and removed reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks labels Aug 29, 2023
@poettering
Copy link
Member Author

Force pushed a new version. Only change is the strncmp() thing and a rebase. Since the only other discussion point left was the UKI check, i.e. whether to include .osrel or not, but I'd vote for doing this separately. Hence taking liberty to set green label.

@poettering poettering removed the please-review PR is ready for (re-)review by a maintainer label Aug 29, 2023
@poettering poettering added the good-to-merge/waiting-for-ci 👍 PR is good to merge, but CI hasn't passed at time of review. Please merge if you see CI has passed label Aug 29, 2023
@bluca bluca merged commit 8fcc700 into systemd:main Aug 29, 2023
45 of 48 checks passed
@github-actions github-actions bot removed the good-to-merge/waiting-for-ci 👍 PR is good to merge, but CI hasn't passed at time of review. Please merge if you see CI has passed label Aug 29, 2023
@bluca
Copy link
Member

bluca commented Aug 29, 2023

Force pushed a new version. Only change is the strncmp() thing and a rebase. Since the only other discussion point left was the UKI check, i.e. whether to include .osrel or not, but I'd vote for doing this separately. Hence taking liberty to set green label.

Given direct booting is supported, I think it makes sense that osrel is optional as the spec says. As long as you have a kernel and an initrd, the image will boot it, so those should be the only mandatory sections I'd think?

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

Successfully merging this pull request may close these issues.

None yet

3 participants