Skip to content

Commit 33fc69a

Browse files
committed
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
2 parents 829745b + 180a9cc commit 33fc69a

12 files changed

Lines changed: 34 additions & 29 deletions

File tree

fs/afs/dir_edit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ static void afs_edit_init_block(union afs_xdr_dir_block *meta,
239239
* The caller must hold the inode locked.
240240
*/
241241
void afs_edit_dir_add(struct afs_vnode *vnode,
242-
struct qstr *name, struct afs_fid *new_fid,
242+
const struct qstr *name, struct afs_fid *new_fid,
243243
enum afs_edit_dir_reason why)
244244
{
245245
union afs_xdr_dir_block *meta, *block;
@@ -391,7 +391,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode,
391391
* The caller must hold the inode locked.
392392
*/
393393
void afs_edit_dir_remove(struct afs_vnode *vnode,
394-
struct qstr *name, enum afs_edit_dir_reason why)
394+
const struct qstr *name, enum afs_edit_dir_reason why)
395395
{
396396
union afs_xdr_dir_block *meta, *block, *pblock;
397397
union afs_xdr_dirent *de, *pde;

fs/afs/dir_search.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ int afs_dir_search_bucket(struct afs_dir_iter *iter, const struct qstr *name,
188188
/*
189189
* Search the appropriate hash chain in the contents of an AFS directory.
190190
*/
191-
int afs_dir_search(struct afs_vnode *dvnode, struct qstr *name,
191+
int afs_dir_search(struct afs_vnode *dvnode, const struct qstr *name,
192192
struct afs_fid *_fid, afs_dataversion_t *_dir_version)
193193
{
194194
struct afs_dir_iter iter = { .dvnode = dvnode, };

fs/afs/internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,9 +1099,9 @@ int afs_single_writepages(struct address_space *mapping,
10991099
/*
11001100
* dir_edit.c
11011101
*/
1102-
extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *,
1102+
extern void afs_edit_dir_add(struct afs_vnode *, const struct qstr *, struct afs_fid *,
11031103
enum afs_edit_dir_reason);
1104-
extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
1104+
extern void afs_edit_dir_remove(struct afs_vnode *, const struct qstr *, enum afs_edit_dir_reason);
11051105
void afs_edit_dir_update(struct afs_vnode *vnode, const struct qstr *name,
11061106
struct afs_vnode *new_dvnode, enum afs_edit_dir_reason why);
11071107
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);
11141114
union afs_xdr_dir_block *afs_dir_find_block(struct afs_dir_iter *iter, size_t block);
11151115
int afs_dir_search_bucket(struct afs_dir_iter *iter, const struct qstr *name,
11161116
struct afs_fid *_fid);
1117-
int afs_dir_search(struct afs_vnode *dvnode, struct qstr *name,
1117+
int afs_dir_search(struct afs_vnode *dvnode, const struct qstr *name,
11181118
struct afs_fid *_fid, afs_dataversion_t *_dir_version);
11191119

11201120
/*

fs/dcache.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,13 +1717,13 @@ static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
17171717
dname = dentry->d_shortname.string;
17181718
}
17191719

1720-
dentry->d_name.len = name->len;
1721-
dentry->d_name.hash = name->hash;
1720+
dentry->__d_name.len = name->len;
1721+
dentry->__d_name.hash = name->hash;
17221722
memcpy(dname, name->name, name->len);
17231723
dname[name->len] = 0;
17241724

17251725
/* Make sure we always see the terminating NUL character */
1726-
smp_store_release(&dentry->d_name.name, dname); /* ^^^ */
1726+
smp_store_release(&dentry->__d_name.name, dname); /* ^^^ */
17271727

17281728
dentry->d_flags = 0;
17291729
lockref_init(&dentry->d_lockref);
@@ -2743,25 +2743,25 @@ static void swap_names(struct dentry *dentry, struct dentry *target)
27432743
/*
27442744
* Both external: swap the pointers
27452745
*/
2746-
swap(target->d_name.name, dentry->d_name.name);
2746+
swap(target->__d_name.name, dentry->__d_name.name);
27472747
} else {
27482748
/*
27492749
* dentry:internal, target:external. Steal target's
27502750
* storage and make target internal.
27512751
*/
2752-
dentry->d_name.name = target->d_name.name;
2752+
dentry->__d_name.name = target->__d_name.name;
27532753
target->d_shortname = dentry->d_shortname;
2754-
target->d_name.name = target->d_shortname.string;
2754+
target->__d_name.name = target->d_shortname.string;
27552755
}
27562756
} else {
27572757
if (unlikely(dname_external(dentry))) {
27582758
/*
27592759
* dentry:external, target:internal. Give dentry's
27602760
* storage to target and make dentry internal
27612761
*/
2762-
target->d_name.name = dentry->d_name.name;
2762+
target->__d_name.name = dentry->__d_name.name;
27632763
dentry->d_shortname = target->d_shortname;
2764-
dentry->d_name.name = dentry->d_shortname.string;
2764+
dentry->__d_name.name = dentry->d_shortname.string;
27652765
} else {
27662766
/*
27672767
* Both are internal.
@@ -2771,7 +2771,7 @@ static void swap_names(struct dentry *dentry, struct dentry *target)
27712771
target->d_shortname.words[i]);
27722772
}
27732773
}
2774-
swap(dentry->d_name.hash_len, target->d_name.hash_len);
2774+
swap(dentry->__d_name.hash_len, target->__d_name.hash_len);
27752775
}
27762776

27772777
static void copy_name(struct dentry *dentry, struct dentry *target)
@@ -2781,11 +2781,11 @@ static void copy_name(struct dentry *dentry, struct dentry *target)
27812781
old_name = external_name(dentry);
27822782
if (unlikely(dname_external(target))) {
27832783
atomic_inc(&external_name(target)->count);
2784-
dentry->d_name = target->d_name;
2784+
dentry->__d_name = target->__d_name;
27852785
} else {
27862786
dentry->d_shortname = target->d_shortname;
2787-
dentry->d_name.name = dentry->d_shortname.string;
2788-
dentry->d_name.hash_len = target->d_name.hash_len;
2787+
dentry->__d_name.name = dentry->d_shortname.string;
2788+
dentry->__d_name.hash_len = target->__d_name.hash_len;
27892789
}
27902790
if (old_name && likely(atomic_dec_and_test(&old_name->count)))
27912791
kfree_rcu(old_name, head);
@@ -3134,7 +3134,7 @@ void d_mark_tmpfile(struct file *file, struct inode *inode)
31343134
!d_unlinked(dentry));
31353135
spin_lock(&dentry->d_parent->d_lock);
31363136
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
3137-
dentry->d_name.len = sprintf(dentry->d_shortname.string, "#%llu",
3137+
dentry->__d_name.len = sprintf(dentry->d_shortname.string, "#%llu",
31383138
(unsigned long long)inode->i_ino);
31393139
spin_unlock(&dentry->d_lock);
31403140
spin_unlock(&dentry->d_parent->d_lock);

fs/exfat/namei.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ static int exfat_create(struct mnt_idmap *idmap, struct inode *dir,
587587
}
588588

589589
/* lookup a file */
590-
static int exfat_find(struct inode *dir, struct qstr *qname,
590+
static int exfat_find(struct inode *dir, const struct qstr *qname,
591591
struct exfat_dir_entry *info)
592592
{
593593
int ret, dentry, count;

include/linux/dcache.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ struct dentry {
9595
seqcount_spinlock_t d_seq; /* per dentry seqlock */
9696
struct hlist_bl_node d_hash; /* lookup hash list */
9797
struct dentry *d_parent; /* parent directory */
98-
struct qstr d_name;
98+
union {
99+
struct qstr __d_name; /* for use ONLY in fs/dcache.c */
100+
const struct qstr d_name;
101+
};
99102
struct inode *d_inode; /* Where the name belongs to - NULL is
100103
* negative */
101104
union shortname_store d_shortname;

include/linux/fs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3716,7 +3716,8 @@ int generic_ci_d_compare(const struct dentry *dentry, unsigned int len,
37163716
* happens when a directory is casefolded and the filesystem is strict
37173717
* about its encoding.
37183718
*/
3719-
static inline bool generic_ci_validate_strict_name(struct inode *dir, struct qstr *name)
3719+
static inline bool generic_ci_validate_strict_name(struct inode *dir,
3720+
const struct qstr *name)
37203721
{
37213722
if (!IS_CASEFOLDED(dir) || !sb_has_strict_encoding(dir->i_sb))
37223723
return true;
@@ -3731,7 +3732,8 @@ static inline bool generic_ci_validate_strict_name(struct inode *dir, struct qst
37313732
return !utf8_validate(dir->i_sb->s_encoding, name);
37323733
}
37333734
#else
3734-
static inline bool generic_ci_validate_strict_name(struct inode *dir, struct qstr *name)
3735+
static inline bool generic_ci_validate_strict_name(struct inode *dir,
3736+
const struct qstr *name)
37353737
{
37363738
return true;
37373739
}

include/linux/lsm_hook_defs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry,
8585
int mode, const struct qstr *name, const char **xattr_name,
8686
struct lsm_context *cp)
8787
LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode,
88-
struct qstr *name, const struct cred *old, struct cred *new)
88+
const struct qstr *name, const struct cred *old, struct cred *new)
8989

9090
#ifdef CONFIG_SECURITY_PATH
9191
LSM_HOOK(int, 0, path_unlink, const struct path *dir, struct dentry *dentry)

include/linux/security.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
391391
const char **xattr_name,
392392
struct lsm_context *lsmcxt);
393393
int security_dentry_create_files_as(struct dentry *dentry, int mode,
394-
struct qstr *name,
394+
const struct qstr *name,
395395
const struct cred *old,
396396
struct cred *new);
397397
int security_path_notify(const struct path *path, u64 mask,
@@ -872,7 +872,7 @@ static inline int security_dentry_init_security(struct dentry *dentry,
872872
}
873873

874874
static inline int security_dentry_create_files_as(struct dentry *dentry,
875-
int mode, struct qstr *name,
875+
int mode, const struct qstr *name,
876876
const struct cred *old,
877877
struct cred *new)
878878
{

security/security.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1814,7 +1814,7 @@ EXPORT_SYMBOL(security_dentry_init_security);
18141814
* Return: Returns 0 on success, error on failure.
18151815
*/
18161816
int security_dentry_create_files_as(struct dentry *dentry, int mode,
1817-
struct qstr *name,
1817+
const struct qstr *name,
18181818
const struct cred *old, struct cred *new)
18191819
{
18201820
return call_int_hook(dentry_create_files_as, dentry, mode,

0 commit comments

Comments
 (0)