diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-10-03 11:14:02 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-10-03 11:14:02 -0700 |
commit | 33fc69a05c50f00f1218408a56348bcab95b831d (patch) | |
tree | 042a6027a4f068ceea1d929b6a1c3dc5438a5dea | |
parent | 829745b75a1af25bfb0c7dc36640548c98c57169 (diff) | |
parent | 180a9cc3fd6a020746fbd7f97b9b62295a325fd2 (diff) |
Merge tag 'pull-qstr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull d_name audit update from Al Viro:
"Simplifying ->d_name audits, easy part.
Turn dentry->d_name into an anon union of const struct qsrt (d_name
itself) and a writable alias (__d_name).
With constification of some struct qstr * arguments of functions that
get &dentry->d_name passed to them, that ends up with all
modifications provably done only in fs/dcache.c (and a fairly small
part of it).
Any new places doing modifications will be easy to find - grep for
__d_name will suffice"
* tag 'pull-qstr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
make it easier to catch those who try to modify ->d_name
generic_ci_validate_strict_name(): constify name argument
afs_dir_search: constify qstr argument
afs_edit_dir_{add,remove}(): constify qstr argument
exfat_find(): constify qstr argument
security_dentry_init_security(): constify qstr argument
-rw-r--r-- | fs/afs/dir_edit.c | 4 | ||||
-rw-r--r-- | fs/afs/dir_search.c | 2 | ||||
-rw-r--r-- | fs/afs/internal.h | 6 | ||||
-rw-r--r-- | fs/dcache.c | 26 | ||||
-rw-r--r-- | fs/exfat/namei.c | 2 | ||||
-rw-r--r-- | include/linux/dcache.h | 5 | ||||
-rw-r--r-- | include/linux/fs.h | 6 | ||||
-rw-r--r-- | include/linux/lsm_hook_defs.h | 2 | ||||
-rw-r--r-- | include/linux/security.h | 4 | ||||
-rw-r--r-- | security/security.c | 2 | ||||
-rw-r--r-- | security/selinux/hooks.c | 2 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 2 |
12 files changed, 34 insertions, 29 deletions
diff --git a/fs/afs/dir_edit.c b/fs/afs/dir_edit.c index 4b1342c72089..fd3aa9f97ce6 100644 --- a/fs/afs/dir_edit.c +++ b/fs/afs/dir_edit.c @@ -239,7 +239,7 @@ static void afs_edit_init_block(union afs_xdr_dir_block *meta, * The caller must hold the inode locked. */ void afs_edit_dir_add(struct afs_vnode *vnode, - struct qstr *name, struct afs_fid *new_fid, + const struct qstr *name, struct afs_fid *new_fid, enum afs_edit_dir_reason why) { union afs_xdr_dir_block *meta, *block; @@ -391,7 +391,7 @@ error: * The caller must hold the inode locked. */ void afs_edit_dir_remove(struct afs_vnode *vnode, - struct qstr *name, enum afs_edit_dir_reason why) + const struct qstr *name, enum afs_edit_dir_reason why) { union afs_xdr_dir_block *meta, *block, *pblock; union afs_xdr_dirent *de, *pde; diff --git a/fs/afs/dir_search.c b/fs/afs/dir_search.c index b25bd892db4d..d2516e55b5ed 100644 --- a/fs/afs/dir_search.c +++ b/fs/afs/dir_search.c @@ -188,7 +188,7 @@ bad: /* * Search the appropriate hash chain in the contents of an AFS directory. */ -int afs_dir_search(struct afs_vnode *dvnode, struct qstr *name, +int afs_dir_search(struct afs_vnode *dvnode, const struct qstr *name, struct afs_fid *_fid, afs_dataversion_t *_dir_version) { struct afs_dir_iter iter = { .dvnode = dvnode, }; diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 444a3ea4fdf6..a45ae5c2ef8a 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1099,9 +1099,9 @@ int afs_single_writepages(struct address_space *mapping, /* * dir_edit.c */ -extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *, +extern void afs_edit_dir_add(struct afs_vnode *, const struct qstr *, struct afs_fid *, enum afs_edit_dir_reason); -extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason); +extern void afs_edit_dir_remove(struct afs_vnode *, const struct qstr *, enum afs_edit_dir_reason); void afs_edit_dir_update(struct afs_vnode *vnode, const struct qstr *name, struct afs_vnode *new_dvnode, enum afs_edit_dir_reason why); void afs_mkdir_init_dir(struct afs_vnode *dvnode, struct afs_vnode *parent_vnode); @@ -1114,7 +1114,7 @@ bool afs_dir_init_iter(struct afs_dir_iter *iter, const struct qstr *name); union afs_xdr_dir_block *afs_dir_find_block(struct afs_dir_iter *iter, size_t block); int afs_dir_search_bucket(struct afs_dir_iter *iter, const struct qstr *name, struct afs_fid *_fid); -int afs_dir_search(struct afs_vnode *dvnode, struct qstr *name, +int afs_dir_search(struct afs_vnode *dvnode, const struct qstr *name, struct afs_fid *_fid, afs_dataversion_t *_dir_version); /* diff --git a/fs/dcache.c b/fs/dcache.c index b2b3b20b55f6..a067fa0a965a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1717,13 +1717,13 @@ static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) dname = dentry->d_shortname.string; } - dentry->d_name.len = name->len; - dentry->d_name.hash = name->hash; + dentry->__d_name.len = name->len; + dentry->__d_name.hash = name->hash; memcpy(dname, name->name, name->len); dname[name->len] = 0; /* Make sure we always see the terminating NUL character */ - smp_store_release(&dentry->d_name.name, dname); /* ^^^ */ + smp_store_release(&dentry->__d_name.name, dname); /* ^^^ */ dentry->d_flags = 0; lockref_init(&dentry->d_lockref); @@ -2743,15 +2743,15 @@ static void swap_names(struct dentry *dentry, struct dentry *target) /* * Both external: swap the pointers */ - swap(target->d_name.name, dentry->d_name.name); + swap(target->__d_name.name, dentry->__d_name.name); } else { /* * dentry:internal, target:external. Steal target's * storage and make target internal. */ - dentry->d_name.name = target->d_name.name; + dentry->__d_name.name = target->__d_name.name; target->d_shortname = dentry->d_shortname; - target->d_name.name = target->d_shortname.string; + target->__d_name.name = target->d_shortname.string; } } else { if (unlikely(dname_external(dentry))) { @@ -2759,9 +2759,9 @@ static void swap_names(struct dentry *dentry, struct dentry *target) * dentry:external, target:internal. Give dentry's * storage to target and make dentry internal */ - target->d_name.name = dentry->d_name.name; + target->__d_name.name = dentry->__d_name.name; dentry->d_shortname = target->d_shortname; - dentry->d_name.name = dentry->d_shortname.string; + dentry->__d_name.name = dentry->d_shortname.string; } else { /* * Both are internal. @@ -2771,7 +2771,7 @@ static void swap_names(struct dentry *dentry, struct dentry *target) target->d_shortname.words[i]); } } - swap(dentry->d_name.hash_len, target->d_name.hash_len); + swap(dentry->__d_name.hash_len, target->__d_name.hash_len); } static void copy_name(struct dentry *dentry, struct dentry *target) @@ -2781,11 +2781,11 @@ static void copy_name(struct dentry *dentry, struct dentry *target) old_name = external_name(dentry); if (unlikely(dname_external(target))) { atomic_inc(&external_name(target)->count); - dentry->d_name = target->d_name; + dentry->__d_name = target->__d_name; } else { dentry->d_shortname = target->d_shortname; - dentry->d_name.name = dentry->d_shortname.string; - dentry->d_name.hash_len = target->d_name.hash_len; + dentry->__d_name.name = dentry->d_shortname.string; + dentry->__d_name.hash_len = target->__d_name.hash_len; } if (old_name && likely(atomic_dec_and_test(&old_name->count))) kfree_rcu(old_name, head); @@ -3134,7 +3134,7 @@ void d_mark_tmpfile(struct file *file, struct inode *inode) !d_unlinked(dentry)); spin_lock(&dentry->d_parent->d_lock); spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - dentry->d_name.len = sprintf(dentry->d_shortname.string, "#%llu", + dentry->__d_name.len = sprintf(dentry->d_shortname.string, "#%llu", (unsigned long long)inode->i_ino); spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_parent->d_lock); diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index f5f1c4e8a29f..c8388a2ec227 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -587,7 +587,7 @@ unlock: } /* lookup a file */ -static int exfat_find(struct inode *dir, struct qstr *qname, +static int exfat_find(struct inode *dir, const struct qstr *qname, struct exfat_dir_entry *info) { int ret, dentry, count; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index cc3e1c1a3454..c83e02b94389 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -95,7 +95,10 @@ struct dentry { seqcount_spinlock_t d_seq; /* per dentry seqlock */ struct hlist_bl_node d_hash; /* lookup hash list */ struct dentry *d_parent; /* parent directory */ - struct qstr d_name; + union { + struct qstr __d_name; /* for use ONLY in fs/dcache.c */ + const struct qstr d_name; + }; struct inode *d_inode; /* Where the name belongs to - NULL is * negative */ union shortname_store d_shortname; diff --git a/include/linux/fs.h b/include/linux/fs.h index d3c023ff1a86..caa8e8879f4b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3716,7 +3716,8 @@ int generic_ci_d_compare(const struct dentry *dentry, unsigned int len, * happens when a directory is casefolded and the filesystem is strict * about its encoding. */ -static inline bool generic_ci_validate_strict_name(struct inode *dir, struct qstr *name) +static inline bool generic_ci_validate_strict_name(struct inode *dir, + const struct qstr *name) { if (!IS_CASEFOLDED(dir) || !sb_has_strict_encoding(dir->i_sb)) return true; @@ -3731,7 +3732,8 @@ static inline bool generic_ci_validate_strict_name(struct inode *dir, struct qst return !utf8_validate(dir->i_sb->s_encoding, name); } #else -static inline bool generic_ci_validate_strict_name(struct inode *dir, struct qstr *name) +static inline bool generic_ci_validate_strict_name(struct inode *dir, + const struct qstr *name) { return true; } diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index adbe234a6f6c..8c42b4bde09c 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -85,7 +85,7 @@ LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry, int mode, const struct qstr *name, const char **xattr_name, struct lsm_context *cp) LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode, - struct qstr *name, const struct cred *old, struct cred *new) + const struct qstr *name, const struct cred *old, struct cred *new) #ifdef CONFIG_SECURITY_PATH LSM_HOOK(int, 0, path_unlink, const struct path *dir, struct dentry *dentry) diff --git a/include/linux/security.h b/include/linux/security.h index bd33f194c94a..92ac3f27b973 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -391,7 +391,7 @@ int security_dentry_init_security(struct dentry *dentry, int mode, const char **xattr_name, struct lsm_context *lsmcxt); int security_dentry_create_files_as(struct dentry *dentry, int mode, - struct qstr *name, + const struct qstr *name, const struct cred *old, struct cred *new); int security_path_notify(const struct path *path, u64 mask, @@ -872,7 +872,7 @@ static inline int security_dentry_init_security(struct dentry *dentry, } static inline int security_dentry_create_files_as(struct dentry *dentry, - int mode, struct qstr *name, + int mode, const struct qstr *name, const struct cred *old, struct cred *new) { diff --git a/security/security.c b/security/security.c index 301104d63fde..4d3c03a4524c 100644 --- a/security/security.c +++ b/security/security.c @@ -1814,7 +1814,7 @@ EXPORT_SYMBOL(security_dentry_init_security); * Return: Returns 0 on success, error on failure. */ int security_dentry_create_files_as(struct dentry *dentry, int mode, - struct qstr *name, + const struct qstr *name, const struct cred *old, struct cred *new) { return call_int_hook(dentry_create_files_as, dentry, mode, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 76b66845a1c3..dfc22da42f30 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2905,7 +2905,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, } static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, - struct qstr *name, + const struct qstr *name, const struct cred *old, struct cred *new) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index fdf2f193a291..af986587841d 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4908,7 +4908,7 @@ static int smack_inode_copy_up_xattr(struct dentry *src, const char *name) } static int smack_dentry_create_files_as(struct dentry *dentry, int mode, - struct qstr *name, + const struct qstr *name, const struct cred *old, struct cred *new) { |