From 5b02bfc1e7e3811c5bf7f0fa626a0694d0dbbd77 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Wed, 16 Aug 2023 16:47:59 +0300 Subject: ovl: do not encode lower fh with upper sb_writers held When lower fs is a nested overlayfs, calling encode_fh() on a lower directory dentry may trigger copy up and take sb_writers on the upper fs of the lower nested overlayfs. The lower nested overlayfs may have the same upper fs as this overlayfs, so nested sb_writers lock is illegal. Move all the callers that encode lower fh to before ovl_want_write(). Signed-off-by: Amir Goldstein --- fs/overlayfs/util.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'fs/overlayfs/util.c') diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 12156e2091ad..f8455fcb8b07 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -1013,12 +1013,18 @@ static void ovl_cleanup_index(struct dentry *dentry) struct dentry *index = NULL; struct inode *inode; struct qstr name = { }; + bool got_write = false; int err; err = ovl_get_index_name(ofs, lowerdentry, &name); if (err) goto fail; + err = ovl_want_write(dentry); + if (err) + goto fail; + + got_write = true; inode = d_inode(upperdentry); if (!S_ISDIR(inode->i_mode) && inode->i_nlink != 1) { pr_warn_ratelimited("cleanup linked index (%pd2, ino=%lu, nlink=%u)\n", @@ -1056,6 +1062,8 @@ static void ovl_cleanup_index(struct dentry *dentry) goto fail; out: + if (got_write) + ovl_drop_write(dentry); kfree(name.name); dput(index); return; @@ -1135,6 +1143,8 @@ void ovl_nlink_end(struct dentry *dentry) { struct inode *inode = d_inode(dentry); + ovl_drop_write(dentry); + if (ovl_test_flag(OVL_INDEX, inode) && inode->i_nlink == 0) { const struct cred *old_cred; @@ -1143,7 +1153,6 @@ void ovl_nlink_end(struct dentry *dentry) revert_creds(old_cred); } - ovl_drop_write(dentry); ovl_inode_unlock(inode); } -- cgit v1.2.3