Skip to content

Commit fd3b36d

Browse files
committed
Merge branch 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs namei updates from Al Viro: - make lookup_one_len() safe with parent locked only shared(incoming afs series wants that) - fix of getname_kernel() regression from 2015 (-stable fodder, that one). * 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: getname_kernel() needs to make sure that ->name != ->iname in long case make lookup_one_len() safe to use with directory locked shared new helper: __lookup_slow() merge common parts of lookup_one_len{,_unlocked} into common helper
2 parents 8ea4a5d + 30ce4d1 commit fd3b36d

File tree

1 file changed

+57
-67
lines changed

1 file changed

+57
-67
lines changed

fs/namei.c

Lines changed: 57 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,10 @@ getname_kernel(const char * filename)
224224
if (len <= EMBEDDED_NAME_MAX) {
225225
result->name = (char *)result->iname;
226226
} else if (len <= PATH_MAX) {
227+
const size_t size = offsetof(struct filename, iname[1]);
227228
struct filename *tmp;
228229

229-
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
230+
tmp = kmalloc(size, GFP_KERNEL);
230231
if (unlikely(!tmp)) {
231232
__putname(result);
232233
return ERR_PTR(-ENOMEM);
@@ -1597,22 +1598,21 @@ static int lookup_fast(struct nameidata *nd,
15971598
}
15981599

15991600
/* Fast lookup failed, do it the slow way */
1600-
static struct dentry *lookup_slow(const struct qstr *name,
1601-
struct dentry *dir,
1602-
unsigned int flags)
1601+
static struct dentry *__lookup_slow(const struct qstr *name,
1602+
struct dentry *dir,
1603+
unsigned int flags)
16031604
{
1604-
struct dentry *dentry = ERR_PTR(-ENOENT), *old;
1605+
struct dentry *dentry, *old;
16051606
struct inode *inode = dir->d_inode;
16061607
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
16071608

1608-
inode_lock_shared(inode);
16091609
/* Don't go there if it's already dead */
16101610
if (unlikely(IS_DEADDIR(inode)))
1611-
goto out;
1611+
return ERR_PTR(-ENOENT);
16121612
again:
16131613
dentry = d_alloc_parallel(dir, name, &wq);
16141614
if (IS_ERR(dentry))
1615-
goto out;
1615+
return dentry;
16161616
if (unlikely(!d_in_lookup(dentry))) {
16171617
if (!(flags & LOOKUP_NO_REVAL)) {
16181618
int error = d_revalidate(dentry, flags);
@@ -1634,11 +1634,21 @@ static struct dentry *lookup_slow(const struct qstr *name,
16341634
dentry = old;
16351635
}
16361636
}
1637-
out:
1638-
inode_unlock_shared(inode);
16391637
return dentry;
16401638
}
16411639

1640+
static struct dentry *lookup_slow(const struct qstr *name,
1641+
struct dentry *dir,
1642+
unsigned int flags)
1643+
{
1644+
struct inode *inode = dir->d_inode;
1645+
struct dentry *res;
1646+
inode_lock_shared(inode);
1647+
res = __lookup_slow(name, dir, flags);
1648+
inode_unlock_shared(inode);
1649+
return res;
1650+
}
1651+
16421652
static inline int may_lookup(struct nameidata *nd)
16431653
{
16441654
if (nd->flags & LOOKUP_RCU) {
@@ -2421,56 +2431,63 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
24212431
}
24222432
EXPORT_SYMBOL(vfs_path_lookup);
24232433

2424-
/**
2425-
* lookup_one_len - filesystem helper to lookup single pathname component
2426-
* @name: pathname component to lookup
2427-
* @base: base directory to lookup from
2428-
* @len: maximum length @len should be interpreted to
2429-
*
2430-
* Note that this routine is purely a helper for filesystem usage and should
2431-
* not be called by generic code.
2432-
*
2433-
* The caller must hold base->i_mutex.
2434-
*/
2435-
struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
2434+
static int lookup_one_len_common(const char *name, struct dentry *base,
2435+
int len, struct qstr *this)
24362436
{
2437-
struct qstr this;
2438-
unsigned int c;
2439-
int err;
2440-
2441-
WARN_ON_ONCE(!inode_is_locked(base->d_inode));
2442-
2443-
this.name = name;
2444-
this.len = len;
2445-
this.hash = full_name_hash(base, name, len);
2437+
this->name = name;
2438+
this->len = len;
2439+
this->hash = full_name_hash(base, name, len);
24462440
if (!len)
2447-
return ERR_PTR(-EACCES);
2441+
return -EACCES;
24482442

24492443
if (unlikely(name[0] == '.')) {
24502444
if (len < 2 || (len == 2 && name[1] == '.'))
2451-
return ERR_PTR(-EACCES);
2445+
return -EACCES;
24522446
}
24532447

24542448
while (len--) {
2455-
c = *(const unsigned char *)name++;
2449+
unsigned int c = *(const unsigned char *)name++;
24562450
if (c == '/' || c == '\0')
2457-
return ERR_PTR(-EACCES);
2451+
return -EACCES;
24582452
}
24592453
/*
24602454
* See if the low-level filesystem might want
24612455
* to use its own hash..
24622456
*/
24632457
if (base->d_flags & DCACHE_OP_HASH) {
2464-
int err = base->d_op->d_hash(base, &this);
2458+
int err = base->d_op->d_hash(base, this);
24652459
if (err < 0)
2466-
return ERR_PTR(err);
2460+
return err;
24672461
}
24682462

2469-
err = inode_permission(base->d_inode, MAY_EXEC);
2463+
return inode_permission(base->d_inode, MAY_EXEC);
2464+
}
2465+
2466+
/**
2467+
* lookup_one_len - filesystem helper to lookup single pathname component
2468+
* @name: pathname component to lookup
2469+
* @base: base directory to lookup from
2470+
* @len: maximum length @len should be interpreted to
2471+
*
2472+
* Note that this routine is purely a helper for filesystem usage and should
2473+
* not be called by generic code.
2474+
*
2475+
* The caller must hold base->i_mutex.
2476+
*/
2477+
struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
2478+
{
2479+
struct dentry *dentry;
2480+
struct qstr this;
2481+
int err;
2482+
2483+
WARN_ON_ONCE(!inode_is_locked(base->d_inode));
2484+
2485+
err = lookup_one_len_common(name, base, len, &this);
24702486
if (err)
24712487
return ERR_PTR(err);
24722488

2473-
return __lookup_hash(&this, base, 0);
2489+
dentry = lookup_dcache(&this, base, 0);
2490+
return dentry ? dentry : __lookup_slow(&this, base, 0);
24742491
}
24752492
EXPORT_SYMBOL(lookup_one_len);
24762493

@@ -2490,37 +2507,10 @@ struct dentry *lookup_one_len_unlocked(const char *name,
24902507
struct dentry *base, int len)
24912508
{
24922509
struct qstr this;
2493-
unsigned int c;
24942510
int err;
24952511
struct dentry *ret;
24962512

2497-
this.name = name;
2498-
this.len = len;
2499-
this.hash = full_name_hash(base, name, len);
2500-
if (!len)
2501-
return ERR_PTR(-EACCES);
2502-
2503-
if (unlikely(name[0] == '.')) {
2504-
if (len < 2 || (len == 2 && name[1] == '.'))
2505-
return ERR_PTR(-EACCES);
2506-
}
2507-
2508-
while (len--) {
2509-
c = *(const unsigned char *)name++;
2510-
if (c == '/' || c == '\0')
2511-
return ERR_PTR(-EACCES);
2512-
}
2513-
/*
2514-
* See if the low-level filesystem might want
2515-
* to use its own hash..
2516-
*/
2517-
if (base->d_flags & DCACHE_OP_HASH) {
2518-
int err = base->d_op->d_hash(base, &this);
2519-
if (err < 0)
2520-
return ERR_PTR(err);
2521-
}
2522-
2523-
err = inode_permission(base->d_inode, MAY_EXEC);
2513+
err = lookup_one_len_common(name, base, len, &this);
25242514
if (err)
25252515
return ERR_PTR(err);
25262516

0 commit comments

Comments
 (0)