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
lib/ukcpio: Fix symlinks not being extracted #992
Conversation
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.
Not something that I used before but for sure can see the benefits. I tried an initRD config and it behaved as expected. As for the code, I don't have any issues with it, so from me, you have the green-light.
Reviewed-by: Eduard-Florin Mihailescu mihailescu.eduard@gmail.com
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.
This looks good, few minor comments.
Besides those, when I try to run an application with a symlink in the initrd fs, I get the following error:
[ 0.171998] Info: [libukcpio] <cpio.c @ 298> Creating symlink /./file2
[ 0.172907] Info: [libukcpio] <cpio.c @ 316> /./file2: Target is file1
[ 0.173839] dbg: [libvfscore] <main.c @ 1532> (int) uk_syscall_r_symlink((const char*) 0x19beb0, (const char*) 0x1ac020)
[ 0.175638] CRIT: [libvfscore] <vnode.c @ 124> Assertion failure: m->owner != cur
Also please rebase this on top of staging so the ci/cd tests can run.
lib/ukcpio/cpio.c
Outdated
target[header_filesize] = 0; | ||
|
||
uk_pr_info("%s: Target is %s\n", path_from_root, target); | ||
if (symlink(target, path_from_root)) { |
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.
if (symlink(target, path_from_root)) { | |
if (uk_syscall_r_symlink(target, path_from_root)) { |
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.
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.
The problem with libc-style syscalls is that you will exit the "kernel space" code and land into an external libc, that you can not control. There were some issues when this would lead to an infinite loop and other problems (see this pr), so we decided to use raw syscalls from whithin the Unikraft core, so the execution will not leave the core space.
The uk_syscall_*
symbols are defined even if the syscall-shim
is not enabled, so most likely the rest of the file was written before we ran into issues with the libc-style syscalls.
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.
Right, I'm aware of the dangers of calling into libc from critical code but hadn't known about the raw syscall policy, nor that this file doesn't necessarily use libcalls on purpose; thanks for clarifying!
I'll use syscalls for symlink in this PR, and add fixing up the rest of the file (or module (or unikraft)) to my backlog to be handled in a future PR.
(char *)(header) + sizeof(struct cpio_header) | ||
+ header_namesize); | ||
|
||
if ((uintptr_t)data_location + header_filesize > last) { |
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.
if ((uintptr_t)data_location + header_filesize > last) { | |
if (unlikely((uintptr_t)data_location + header_filesize > last)) { |
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.
I understand the point, however this being here only for the symlink case and not the others would suggest that symlinks are less likely to fail these checks compared to regular files or dirs (which isn't AFAICT accurate).
A cleaner way to integrate this change then would be to do it file- or lib-wide in its own changeset; thoughts?
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.
Ok, makes sense, we can do this lib-wide.
lib/ukcpio/cpio.c
Outdated
target[header_filesize] = 0; | ||
|
||
uk_pr_info("%s: Target is %s\n", path_from_root, target); | ||
if (symlink(target, path_from_root)) { |
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.
if (symlink(target, path_from_root)) { | |
if (unlikely(symlink(target, path_from_root))) { |
@StefanJum You might need to apply this PR to fix symlink bugs in general: #952. |
a72d2fe
to
7d910fc
Compare
Yes, that was it, it works now. |
Previously the CPIO extraction code would only handle sections whose header was of type directory or file, skipping symlinks. This change adds code to handle extracting symlinks from CPIO archives, as well as a warning message for unknown CPIO sections. Signed-off-by: Andrei Tatar <andrei@unikraft.io>
7d910fc
to
b01fa12
Compare
Update: rebased on staging; changed symlink to syscall |
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.
All good now, thanks @andreittr 🚀
Reviewed-by: Stefan Jumarea stefanjumarea02@gmail.com
Beep boop! I ran Unikraft's
Truncated logs starting from first warning b01fa12:
View complete logs | Learn more about Unikraft's coding style and contribution guidelines. |
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.
Approved-by: Razvan Deaconescu razvand@unikraft.io
Description of changes
Previously the CPIO extraction code would only handle sections whose header was of type directory or file, skipping symlinks. This change adds code to handle extracting symlinks from CPIO archives, as well as a warning message for unknown CPIO sections.
Prerequisite checklist
checkpatch.uk
on your commit series before opening this PR;Base target
Additional configuration
Test with an initrd root that contains symlinks.