From: Dmitry Kadashev <[email protected]>
To: Jens Axboe <[email protected]>,
Alexander Viro <[email protected]>,
Christian Brauner <[email protected]>,
Linus Torvalds <[email protected]>
Cc: [email protected], [email protected],
Dmitry Kadashev <[email protected]>
Subject: [PATCH 6/7] namei: clean up do_linkat retry logic
Date: Mon, 12 Jul 2021 19:36:48 +0700 [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
Moving the main logic to a helper function makes the whole thing much
easier to follow.
Cc: Linus Torvalds <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Christian Brauner <[email protected]>
Suggested-by: Linus Torvalds <[email protected]>
Link: https://lore.kernel.org/io-uring/CAHk-=wiG+sN+2zSoAOggKCGue2kOJvw3rQySvQXsZstRQFTN+g@mail.gmail.com/
Signed-off-by: Dmitry Kadashev <[email protected]>
---
fs/namei.c | 80 ++++++++++++++++++++++++++++++------------------------
1 file changed, 44 insertions(+), 36 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index c9110ac83ccb..5e4fa8b65a8d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4380,48 +4380,22 @@ int vfs_link(struct dentry *old_dentry, struct user_namespace *mnt_userns,
}
EXPORT_SYMBOL(vfs_link);
-/*
- * Hardlinks are often used in delicate situations. We avoid
- * security-related surprises by not following symlinks on the
- * newname. --KAB
- *
- * We don't follow them on the oldname either to be compatible
- * with linux 2.0, and to avoid hard-linking to directories
- * and other special files. --ADM
- */
-int do_linkat(int olddfd, struct filename *old, int newdfd,
- struct filename *new, int flags)
+static int linkat_helper(int olddfd, struct filename *old, int newdfd,
+ struct filename *new, unsigned int lookup_flags)
{
struct user_namespace *mnt_userns;
struct dentry *new_dentry;
struct path old_path, new_path;
struct inode *delegated_inode = NULL;
- int how = 0;
int error;
- if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) {
- error = -EINVAL;
- goto out_putnames;
- }
- /*
- * To use null names we require CAP_DAC_READ_SEARCH
- * This ensures that not everyone will be able to create
- * handlink using the passed filedescriptor.
- */
- if (flags & AT_EMPTY_PATH && !capable(CAP_DAC_READ_SEARCH)) {
- error = -ENOENT;
- goto out_putnames;
- }
-
- if (flags & AT_SYMLINK_FOLLOW)
- how |= LOOKUP_FOLLOW;
retry:
- error = __filename_lookup(olddfd, old, how, &old_path, NULL);
+ error = __filename_lookup(olddfd, old, lookup_flags, &old_path, NULL);
if (error)
- goto out_putnames;
+ return error;
new_dentry = __filename_create(newdfd, new, &new_path,
- (how & LOOKUP_REVAL));
+ (lookup_flags & LOOKUP_REVAL));
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
goto out_putpath;
@@ -4447,14 +4421,48 @@ int do_linkat(int olddfd, struct filename *old, int newdfd,
goto retry;
}
}
+out_putpath:
+ path_put(&old_path);
+ return error;
+}
+
+/*
+ * Hardlinks are often used in delicate situations. We avoid
+ * security-related surprises by not following symlinks on the
+ * newname. --KAB
+ *
+ * We don't follow them on the oldname either to be compatible
+ * with linux 2.0, and to avoid hard-linking to directories
+ * and other special files. --ADM
+ */
+int do_linkat(int olddfd, struct filename *old, int newdfd,
+ struct filename *new, int flags)
+{
+ int error, how = 0;
+
+ if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) {
+ error = -EINVAL;
+ goto out;
+ }
+ /*
+ * To use null names we require CAP_DAC_READ_SEARCH
+ * This ensures that not everyone will be able to create
+ * handlink using the passed filedescriptor.
+ */
+ if (flags & AT_EMPTY_PATH && !capable(CAP_DAC_READ_SEARCH)) {
+ error = -ENOENT;
+ goto out;
+ }
+
+ if (flags & AT_SYMLINK_FOLLOW)
+ how |= LOOKUP_FOLLOW;
+
+ error = linkat_helper(olddfd, old, newdfd, new, how);
if (retry_estale(error, how)) {
- path_put(&old_path);
how |= LOOKUP_REVAL;
- goto retry;
+ error = linkat_helper(olddfd, old, newdfd, new, how);
}
-out_putpath:
- path_put(&old_path);
-out_putnames:
+out:
putname(old);
putname(new);
--
2.30.2
next prev parent reply other threads:[~2021-07-12 12:37 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-12 12:36 [PATCH 0/7] namei: clean up retry logic in various do_* functions Dmitry Kadashev
2021-07-12 12:36 ` [PATCH 1/7] namei: clean up do_rmdir retry logic Dmitry Kadashev
2021-07-13 14:53 ` Christian Brauner
2021-07-13 16:57 ` Linus Torvalds
2021-07-15 10:38 ` Dmitry Kadashev
2021-07-12 12:36 ` [PATCH 2/7] namei: clean up do_unlinkat " Dmitry Kadashev
2021-07-12 12:36 ` [PATCH 3/7] namei: clean up do_mkdirat " Dmitry Kadashev
2021-07-12 12:36 ` [PATCH 4/7] namei: clean up do_mknodat " Dmitry Kadashev
2021-07-12 18:46 ` Linus Torvalds
2021-07-12 12:36 ` [PATCH 5/7] namei: clean up do_symlinkat " Dmitry Kadashev
2021-07-12 18:54 ` Linus Torvalds
2021-07-12 12:36 ` Dmitry Kadashev [this message]
2021-07-12 18:57 ` [PATCH 6/7] namei: clean up do_linkat " Linus Torvalds
2021-07-12 12:36 ` [PATCH 7/7] namei: clean up do_renameat " Dmitry Kadashev
2021-07-12 12:41 ` [PATCH 0/7] namei: clean up retry logic in various do_* functions Dmitry Kadashev
2021-07-12 19:01 ` Linus Torvalds
2021-07-12 20:25 ` Al Viro
2021-07-13 12:28 ` Dmitry Kadashev
2021-07-13 10:22 ` Dmitry Kadashev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox