-
-
Notifications
You must be signed in to change notification settings - Fork 185
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
track files in /boot in kexec_tree.txt #1262
Conversation
@JonathonHall-Purism Seems to work fine in my test without regression. People upgrading firmware would get an error of hash files not being present even if it is, the user being asked to update them. I think it would not be bad. A default boot, which checks things tighter, would still fail in current code base with same error anyway. Only thing is that directories names One thing I would do on next step (since Qemu overhead [not kvm] really shows difference of cpu time) would be to compare dir tree file first instead of checking for hashes (for show options which doesn't check detached signature since force option is passed) where default boot checks kexec.sig and exits first for performance improvement at later time? |
Nice work @3hhh ! I think this is a great direction. I tested this out a bit and have some notes: Initial install - new file .auditing-0I did a clean setup from scratch in qemu (with PureOS but I don't think the distro matters). Everything went smoothly until it was about to boot - somehow a file @tlaurion Any idea what creates Escape sequences / control characters@tlaurion - You probably knew this, but just to get on the same page, your test showed a directory containing literally The literal line break causes oddities but I'm more concerned with control characters being passed through the whiptail prompt 🤔 As a crude example, an attacker can make text look like it is part of the prompt from Heads: On regular terminal whiptail, I would think you could craft terminal escapes to overwrite the entire prompt if you wanted to, and the premise is that these files could be attacker-controlled. If we had bash, I would recommend to just escape all the file names with ${VAR@Q} or something and be done with it, but I can't find a straightforward solution in busybox ash. Maybe we need to bite the bullet and write some "quoter" in a regex or C? There are definitely other places we should use it, like the boot menu (could solve the spaces-to-underscores in the boot menu choices). |
EDIT: It happens through libtpm usage https://github.com/osresearch/tpmtotp/blob/18b860fdcf5a55537c8395b891f2b2a5c24fc00a/libtpm/auditing.c#L391 and I thought it was created as part of TPM ownership (the file is written if non-existing at https://github.com/osresearch/tpmtotp/blob/18b860fdcf5a55537c8395b891f2b2a5c24fc00a/libtpm/auditing.c#L513-L514 This PR taking into consideration new files as opposed to previously only existing files being modified: this exposes this new behavior. @JonathonHall-Purism I'm confused by your report stating that OEM reownership doesn't create the file, since TPM ownership should, so I will need to test this further. Creating a debian-xfce disk image now, will snapshot prior of using it with heads to check behavior myself and will report back.
This is really, really bad and an invitation to go back to simplicity. Will go deeper and test, but I would prefer to go into presenting the raw changes with minimal modification (print_tree does that here) where showing the result would require additional sanitization that might be unneeded. Having the output on screen is not enough to investigate. I think this output should be presented through command line only, just like it is, currently, when 10+ files are detected as modified. What about the following to entice thought experiment: no more showing those into whiptail and using raw output to enforce auditing:
This way the user would be presented the same list he would need to dig into prior of signing if he doesn't recognize the change, which we expect he would do from recovery shell, telling him where to find the new/modified file list for inspection. We would dodge having to cleanup output altogether (which would be problematic: we want the list to be as it is so the user can inspect what happened to his system, not miss other bullets). @3hhh @JonathonHall-Purism Thoughts?
@JonathonHall-Purism : unfortunately, from my attempts on integrating tpm2 from hardenedvault fork which included prior work from Trammel in old stalled PR, including bash would be really costly and doesn't seem an option for production. Not relevant for this ticket, but I would love to add it somehow into qemu builds, since it would be easily possible to track caller/callee/sourced functions under warn/die calls to ease troubleshooting if bash was included. That would help a bunch, but here again ash is failing us.
@JonathonHall-Purism This is another area where a little more thought should be invested. In case of Qubes (multiboot), we lost a lot of precious output on what the user is actually trusting to booting into (at setting new boot default, for example). Xen parameters and Kernel parameters would need to be outputted more in detail (not less), where they were removed prior of expending height of whiptail output dynamically. I will revisit that later on, but I think this should be a separate issue, differently problematic than the current case. Here again, thoughts welcome. |
qemu-coreboot-whiptail-tpm1 qemu-coreboot-fbwhiptail-tpm1-hotp Edit: flashed master on x230-hotp-maximized to make sure things are not broken. So something weird with testing setup (swtpm, NV and hotp: no prompt for HOTP GPG admin PIN, and meu loop. Will rebuild qemu-coreboot-fbwhiptail-tpm1-hotp clean |
Yes, ideally untrusted output should be visibly separated from trusted output. Some other remarks:
|
It's crude, but how about this:
I'm sure performance is abysmal but it shouldn't make much of a difference here I think, and at least it works. |
Could be added under config/busybox if needed
@JonathonHall-Purism @3hhh : Struggling with tr, which should be able to be up the task following changelogs of bysybox and some quick test (where
|
A quick test of tr -cd did work for me (
The implementation may not be stellar but at least it's isolated and easy to test, if it becomes limiting we could always replace it with a tiny escaper in C instead. What do you all think though, do you prefer the alternatives? |
I'm still struggling to make From my understanding of the problem (going to basics)
EDIT (forgot -print0 from past test, same output):
Unfortunately, I haven't found any tricks, as of now, to have tr specify a character class that would remove all control characters but null, so that we could, in my understanding, dodge the problem efficiently without recreating the wheel. Trying to combine
In the goal of being able to remove cntrl characters from each line returned by find, so that the output that is to be saved in file is used for both comparison and guideline for user to investigate what is going on. @3hhh @JonathonHall-Purism : if we could find hack to have tr used to do this or tools provided by busybox, that would be better. To be honest @JonathonHall-Purism : I haven't tested your script to sanitize but from past experience, the performance efficiency @JonathonHall-Purism Unfortunately there were issues opened in the past to limit /boot deepness for performance reasons in certain scenarios and going with something not efficient will bite us back quick. |
Ohhhhh! Maybe https://stackoverflow.com/questions/14680100/removing-control-characters-from-a-file Let's see... |
exerpt:
We have something better then this? |
@JonathonHall-Purism : actually, this is a bug. That should be another issue which solution is to make sure that each time we do write operations is under a subshell. |
With the following patch on top of 0006f58:
Whiptail output still problematic: @JonathonHall-Purism : By bypassing whiptail output completely with quick hack (right now, if number of new/modified files lower then 10 we show file report under whiptail)
We make sure that the file reports would always be through That would require a little additional gui-init work to make this hack more long term, but I think this is going where we want this to be. |
@JonathonHall-Purism @3hhh : another thing to keep in mind for UX. Any suggestion how to deal with this better as a transitional measure to not scare users upon firmware upgrade? |
At the end of the day, finding back those files with invalid names will fail (will current patch proposed under #1262 (comment) please use and adapt as desired) The user will probably want to delete those files from recovery shell/OS prior of generating new hashes/dir tree and sign. I have no solution to propose for this nor have a use case in mind where such filenames are normal to be there. Anyway, trying to create digests for those awkward files fails: |
I'm a bit in a hurry today, but let's please judge it based on some performance comparison with the alternative. I personally doubt that And if it's somewhat OK performance wise, I agree with @JonathonHall-Purism that it's better to not remove the characters and just escape them. |
Hm OK the relative performance difference is quite significant. Whether the absolute difference of ~180ms on my debian box is relevant in practice I'll let for you guys to judge:
( Personally I don't care waiting ~200ms more.
In general adjusting the error message and also mentioning the tree file should help. Moreover one could temporarily (for 1-2 versions) adjust the error message and say that the update request could also be caused by a firmware upgrade from a version prior to XYZ. But yes, at least mention it in the changelog. |
OK, slept on it. print_tree is used for both generation of dir tree and showing the information to user. I think the problem lies there. We should warn the user that X files/directories contain non-printable characters and show them in less, while keeping dir tree saved with those invalid characters (minus newlines which interfere with output in on otherwise multiple lines). The point discussed with @JonathonHall-Purism is that no file containing invalid characters should be present under boot, so user should know. Will take another shot at this next week. I agree sanitization for output to screen is needed. Will also review https://source.puri.sm/firmware/pureboot/-/commit/4e83fa9c3ee96768af5c47300495fac22659fccc and two prior commits |
And the more I think about it, the more dir_tree might be irrelevant altogether. @3hhh is there any reason why files only (not reporting on new/deleted empty directories outside of directories containing new/deleted files per sha256sum) would not be enough? |
Showing it in So yes, sanitization is needed anyway.
Any initrd developer could do something like |
The current version should fix most of the aforementioned issues. |
Test upon properly detached signed digests (Options->Generate hashes + sign)
Options -> show OS boot options If we are ok with the idea that user should review files with weird characters and not sign, then I have nothing against merging this as this is to me a big improvement. @JonathonHall-Purism ? |
Interesting. Looks like |
Upon generated hashes + sign of digests:
generate checkums, sign
Exerpt
Even though checksums were created for invalid paths and files:
Even though kexec_dirtree.txt was created with escaped names: Again:
Exerpt:
So my question here is: should we report on invalid folder names/filenames? Solution space:
Outputs:
We could squash multiple instances of the same replaced char with
Where to be able to resolve the issue with
But as you can see above there is not such a thing as saving "raw" directory tree with bad dir/filenames unless we sanitize them, and if we do, the paths saved into kexec_tree.txt/kexec_hashes.txt won't exist and will fail later on at verification. IE: where:
So we either create an issue out of this reply to deal later or try to come out with a solution here prior of merge? |
It's a bug in busybox sha256sum that should be reported upstream IMHO:
|
@tlaurion Btw with the last version, no escaped output is stored in |
@tlaurion @3hhh Thanks for letting me catch up with this. The improvements are great and I think it is close. I did a fair amount of testing this morning and we still have a few things that I think were discussed partially but lost in the shuffle. I think the upgrade path is fine - the message presented is pretty good (specifically says "...if you are upgrading..."). While we could detect an old signature lacking kexec_tree.txt I don't think it's necessary, and I think we should have the general expectation that updating Heads/PB may require re-signing this way, in general adding compatibilities has a significant risk of reopening holes IMO.
|
initrd/etc/functions
Outdated
} | ||
|
||
# Escape zero-delimited standard input for use in shell. | ||
# These characters are passed verbatim: a-zA-Z0-9,._+:@%/- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is no longer trying to create shell-safe output (which is fine, makes sense for whiptail), I think we can allow more characters through to make the output more readable.
I think we'd be fine to escape 00-1f (controls), # (escape char itself), \ (interpreted by whiptail), 7f (del). Continuing to use #n#r#t#v#b## for those chars is good IMO, hex for everything else.
In particular leaving space alone would make files with spaces more readable. I don't think escaping other shell chars like "'(){}[], etc. has any benefit.
I think # was a good choice for the escape char. It's unfortunate that we have to invent another kind of escaping and hope that the user understands it, but # is odd enough not just in file names but any sort of terminal output that I think it's OK. I liked what less did with other control chars (inverted colors, some unusual character) but your point about \b
is good, I hadn't checked that one specifically, better safe than sorry.
Updated upstream related ticket at https://bugs.busybox.net/show_bug.cgi?id=14226 for sha256sum (and other busybox applets) bad behavior |
Per reply at #1262 (comment)
@3hhh @JonathonHall-Purism this is on what I want to direct your attention. But by introducing new code that introduce creation of a dir tree, we should, I think, at the same time, prevent the user of creating invalid checksums/signing of files that would fail verification on next boot. Thoughts on that point? Otherwise @JonathonHall-Purism #1272 fixes your concerns about |
@3hhh - @tlaurion and I discussed this since we were going in circles: Since signing a /boot containing control chars doesn't work (and is unlikely to work in any near future), it doesn't make sense to try to handle things like this in kexec_tree, the prompts, etc. Instead we should prevent the user from signing, because it won't work. So we suggest:
While Heads already cannot sign files like this, we would like these changes in order to merge this PR because the alternative escaping strategy leaves the user stuck in a flow where they attempt to sign, then the signatures are invalid and they're prompted to sign again, etc. I think the performance is a problem, 0.2 s doesn't seem like much but by my math it could take 25 min if an attacker created 100 MB of file names. Thanks again for all the work on this and hashing this out with us. @tlaurion Please comment if I overlooked any detail from our discussion. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Found errors. Fixed in master |
@3hhh : sorry for past noise. If you rebase this PR on master, I changed 2 things in the following patch provided on top of master (or tlaurion@09ae3d9 directly after rebasing this PR on master)
With a rebase on master and the following changes, I think this PR is ready to merge.
(this is also under https://github.com/tlaurion/heads/tree/3hhh-add-files_WiP: tlaurion@09ae3d9) Edit: This would give the following hints to the user to be acted upon when landing on the recovery shell, already under /boot dir in case of undesirable files/directories being present under /boot prior of signing: |
Attempt to fix the following issues: 1. unescaped file names may let an attacker display arbitrary whiptail prompts --> escape, original code by @JonathonHall-Purism 2. whiptail itself allows escape characters such as \n --> use an escape character not used by whiptail, i.e. # 3. performance issues caused by diff'ing too early --> only generate a diff to display to the user, if an actual issue is found
by not generating the kexec_tree diff in that case
busybox sha256sum will create a checksum file for uncommon file names (e.g. /boot/foo"$\n"bar), but fail to verify that exact file. https://bugs.busybox.net/show_bug.cgi?id=14226 Thus disallow all files in /boot/ with strange file names at the time of signing for now. Verifying in the presence of new files with such file names in /boot/ is no issue for the kexec_tree verification due to the previously implemented escaping mechanism.
No need to check for the GPG card first.
and display some more information to the user, if available
Since it's not supposed to be shell safe, just display safe inside double quotes, we can allow some more characters. Also fix the escape character not being escaped.
It should be ready to go then. ping @JonathonHall-Purism
|
@JonathonHall-Purism : I retested and LGTM! |
The above happening on recovery console when a user decides to proceed signing invalid files/dir only (with now extended charset escaped under d07df1e). |
Fixes #1248