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

lib/vfscore: Fix create through broken symlink #998

Closed
wants to merge 1 commit into from

Conversation

andreittr
Copy link
Contributor

Description of changes

Previously a vfs syscall on a broken symlink would fail with ENOENT instead of attempting the syscall on the symlink target. This would make open(O_CREAT) to fail instead of creating the missing target file. This change fixes this behavior, bringing it in line with expectations.

Prerequisite checklist

  • Read the contribution guidelines regarding submitting new changes to the project;
  • Tested your changes against relevant architectures and platforms;
  • Ran the checkpatch.uk on your commit series before opening this PR;
  • Updated relevant documentation.

Base target

  • Architecture(s): N/A
  • Platform(s): N/A
  • Application(s): N/A

Additional configuration

Test with:

symlink("nonexistent", "broken-link");
int f = open("broken-link", O_WRONLY|O_CREAT, 0644);
if (f < 0) perror("bug in open()");

@andreittr andreittr requested a review from a team as a code owner July 24, 2023 21:31
@razvand razvand requested review from RaduNichita and mariasfiraiala and removed request for a team July 24, 2023 21:49
@razvand razvand self-assigned this Jul 24, 2023
@razvand razvand added area/lib Internal Unikraft Microlibrary kind/quick-fix Issue is a quick fix lib/vfscore VFS Core Interface priority/medium lang/c Issues or PRs to do with C/C++ labels Jul 24, 2023
@razvand razvand added this to the v0.14.0 (Prometheus) milestone Jul 24, 2023
Comment on lines +257 to +258
int
namei(const char *path, struct dentry **dpp)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
int
namei(const char *path, struct dentry **dpp)
int namei(const char *path, struct dentry **dpp)

Copy link
Contributor

Choose a reason for hiding this comment

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

You can leave it on the same line, as mentioned in the coding - conventions PR: unikraft/docs#248

Prefer the Linux style with the return type on the same line as the function name.
In case of long functions + first argument, you can break after the return type.

Copy link
Contributor Author

@andreittr andreittr Aug 2, 2023

Choose a reason for hiding this comment

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

All of lookup.c uses this format, and I believe maintaining consistency is important.
If we however believe this style actively harms readability, we can address it for the entire file in a style change PR.

In vfs.h: sure, there it makes sense, and the rest of the file follows suit as well.

* - (0): Completed successfully
* - (<0): Negative value with error code
*/
int
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

return error;
}
/*
* Convert a pathname into a pointer to a dentry
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the commentary is not needed, since it's very similar in vfs.h

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed the comments are duplicates of the docstrings in vfs.h, however the file already has this style for exported functions and I don't want to break it without good reason.

Copy link
Contributor

@mariasfiraiala mariasfiraiala left a comment

Choose a reason for hiding this comment

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

Thanks @andreittr. See my few comments below. Other than that I wasn't able to reproduce the issue with the example you provided, though the changes make sense.

*/
int
namei(const char *path, struct dentry **dpp)
namei_resolve(const char *path, struct dentry **dpp, char realpath[PATH_MAX])
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
namei_resolve(const char *path, struct dentry **dpp, char realpath[PATH_MAX])
namei_resolve(const char *path, struct dentry **dpp, char *realpath)

Let's have this without the specified size, just like it happens for the other argument.

return 0;
out:
if (realpath)
strcpy(realpath, fp);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
strcpy(realpath, fp);
strlcpy(realpath, fp, PATH_MAX);

We can use strlcpy() in order to keep the consistency within the file and for better security.

@andreittr
Copy link
Contributor Author

Thanks @andreittr. See my few comments below. Other than that I wasn't able to reproduce the issue with the example you provided, though the changes make sense.

What behavior are you getting when trying to reproduce? If the symlink call fails you might need to apply this PR: #952.

@mariasfiraiala
Copy link
Contributor

If the symlink call fails you might need to apply this PR: #952.

I had already applied that PR since I also reviewed it.

What behavior are you getting when trying to reproduce?

The bug is not reproducible on 9pfs (meaning that the error message doesn't get printed), but with ramfs, the behaviour is indeed the one you mentioned, so all good.

@andreittr I'll approve the PR after you apply the suggestions, thank you for this!

Previously a vfs syscall on a broken symlink would fail with ENOENT
instead of attempting the syscall on the symlink target. This would make
open(O_CREAT) to fail instead of creating the missing target file.
This change fixes this behavior, bringing it in line with expectations.

Signed-off-by: Andrei Tatar <andrei@unikraft.io>
@andreittr
Copy link
Contributor Author

Pushed changes addressing comments.

The bug is not reproducible on 9pfs (meaning that the error message doesn't get printed), but with ramfs, the behaviour is indeed the one you mentioned, so all good.

That's really odd that 9pfs isn't affected, as the code paths are common between filesystems 🤷 .

Copy link
Contributor

@mariasfiraiala mariasfiraiala left a comment

Choose a reason for hiding this comment

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

All good on my side now, thanks a lot for the fixes @andreittr!

Reviewed-by: Maria Sfiraiala maria.sfiraiala@gmail.com

@unikraft-bot
Copy link
Member

Checkpatch passed

Beep boop! I ran Unikraft's checkpatch.pl support script on your pull request and it all looks good!

SHA commit checkpatch
257ccba lib/vfscore: Fix create through broken symlink

@RaduNichita
Copy link
Contributor

All good also from my side. As @mariasfiraiala, I have only managed to reproduce the bug on ramfs, not 9pfs.

Reviewed-by: Radu Nichita radunichita99@gmail.com

Copy link
Contributor

@razvand razvand left a 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

@unikraft-bot unikraft-bot added the ci/merged Merged by CI label Aug 7, 2023
@andreittr andreittr deleted the ttr/create-brsym branch August 7, 2023 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/lib Internal Unikraft Microlibrary ci/merged Merged by CI kind/quick-fix Issue is a quick fix lang/c Issues or PRs to do with C/C++ lib/vfscore VFS Core Interface priority/medium
Projects
Status: Done!
Development

Successfully merging this pull request may close these issues.

None yet

5 participants