Skip to content

Commit 79360dd

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull pile 2 of vfs updates from Al Viro: "Stuff in this one - assorted fixes, lglock tidy-up, death to lock_super(). There'll be a VFS pile tomorrow (with patches from Jeff Layton, sanitizing getname() and related parts of audit and preparing for ESTALE fixes), but I'd rather push the stuff in this one ASAP - some of the bugs closed here are quite unpleasant." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: bogus warnings in fs/namei.c consitify do_mount() arguments lglock: add DEFINE_STATIC_LGLOCK() lglock: make the per_cpu locks static lglock: remove unused DEFINE_LGLOCK_LOCKDEP() MAX_LFS_FILESIZE definition for 64bit needs LL... tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking vfs: drop lock/unlock super ufs: drop lock/unlock super sysv: drop lock/unlock super hpfs: drop lock/unlock super fat: drop lock/unlock super ext3: drop lock/unlock super exofs: drop lock/unlock super dup3: Return an error when oldfd == newfd. fs: handle failed audit_log_start properly fs: prevent use after free in auditing when symlink following was denied
2 parents 8213a2f + 98f6ef6 commit 79360dd

39 files changed

+166
-170
lines changed

fs/ceph/export.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,17 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len,
9999
* FIXME: we should try harder by querying the mds for the ino.
100100
*/
101101
static struct dentry *__fh_to_dentry(struct super_block *sb,
102-
struct ceph_nfs_fh *fh)
102+
struct ceph_nfs_fh *fh, int fh_len)
103103
{
104104
struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
105105
struct inode *inode;
106106
struct dentry *dentry;
107107
struct ceph_vino vino;
108108
int err;
109109

110+
if (fh_len < sizeof(*fh) / 4)
111+
return ERR_PTR(-ESTALE);
112+
110113
dout("__fh_to_dentry %llx\n", fh->ino);
111114
vino.ino = fh->ino;
112115
vino.snap = CEPH_NOSNAP;
@@ -150,14 +153,17 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
150153
* convert connectable fh to dentry
151154
*/
152155
static struct dentry *__cfh_to_dentry(struct super_block *sb,
153-
struct ceph_nfs_confh *cfh)
156+
struct ceph_nfs_confh *cfh, int fh_len)
154157
{
155158
struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
156159
struct inode *inode;
157160
struct dentry *dentry;
158161
struct ceph_vino vino;
159162
int err;
160163

164+
if (fh_len < sizeof(*cfh) / 4)
165+
return ERR_PTR(-ESTALE);
166+
161167
dout("__cfh_to_dentry %llx (%llx/%x)\n",
162168
cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
163169

@@ -207,9 +213,11 @@ static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid,
207213
int fh_len, int fh_type)
208214
{
209215
if (fh_type == 1)
210-
return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
216+
return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw,
217+
fh_len);
211218
else
212-
return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
219+
return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw,
220+
fh_len);
213221
}
214222

215223
/*
@@ -230,6 +238,8 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb,
230238

231239
if (fh_type == 1)
232240
return ERR_PTR(-ESTALE);
241+
if (fh_len < sizeof(*cfh) / 4)
242+
return ERR_PTR(-ESTALE);
233243

234244
pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
235245
cfh->parent_name_hash);

fs/exofs/super.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
389389
if (unlikely(ret))
390390
goto out;
391391

392-
lock_super(sb);
393-
394392
ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
395393
memset(fscb, 0, ios->length);
396394
fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
@@ -406,8 +404,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
406404
if (unlikely(ret))
407405
EXOFS_ERR("%s: ore_write failed.\n", __func__);
408406

409-
410-
unlock_super(sb);
411407
out:
412408
EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
413409
ore_put_io_state(ios);

fs/ext3/super.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2578,11 +2578,9 @@ static int ext3_freeze(struct super_block *sb)
25782578
static int ext3_unfreeze(struct super_block *sb)
25792579
{
25802580
if (!(sb->s_flags & MS_RDONLY)) {
2581-
lock_super(sb);
25822581
/* Reser the needs_recovery flag before the fs is unlocked. */
25832582
EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
25842583
ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
2585-
unlock_super(sb);
25862584
journal_unlock_updates(EXT3_SB(sb)->s_journal);
25872585
}
25882586
return 0;
@@ -2602,7 +2600,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
26022600
#endif
26032601

26042602
/* Store the original options */
2605-
lock_super(sb);
26062603
old_sb_flags = sb->s_flags;
26072604
old_opts.s_mount_opt = sbi->s_mount_opt;
26082605
old_opts.s_resuid = sbi->s_resuid;
@@ -2708,8 +2705,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
27082705
old_opts.s_qf_names[i] != sbi->s_qf_names[i])
27092706
kfree(old_opts.s_qf_names[i]);
27102707
#endif
2711-
unlock_super(sb);
2712-
27132708
if (enable_quota)
27142709
dquot_resume(sb, -1);
27152710
return 0;
@@ -2728,7 +2723,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
27282723
sbi->s_qf_names[i] = old_opts.s_qf_names[i];
27292724
}
27302725
#endif
2731-
unlock_super(sb);
27322726
return err;
27332727
}
27342728

fs/fat/dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
571571
int short_len = 0, fill_len = 0;
572572
int ret = 0;
573573

574-
lock_super(sb);
574+
mutex_lock(&sbi->s_lock);
575575

576576
cpos = filp->f_pos;
577577
/* Fake . and .. for the root directory. */
@@ -693,7 +693,7 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
693693
if (unicode)
694694
__putname(unicode);
695695
out:
696-
unlock_super(sb);
696+
mutex_unlock(&sbi->s_lock);
697697
return ret;
698698
}
699699

fs/fat/fat.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ struct msdos_sb_info {
7171
unsigned long root_cluster; /* first cluster of the root directory */
7272
unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
7373
struct mutex fat_lock;
74-
unsigned int prev_free; /* previously allocated cluster number */
75-
unsigned int free_clusters; /* -1 if undefined */
74+
struct mutex s_lock;
75+
unsigned int prev_free; /* previously allocated cluster number */
76+
unsigned int free_clusters; /* -1 if undefined */
7677
unsigned int free_clus_valid; /* is free_clusters valid? */
7778
struct fat_mount_options options;
7879
struct nls_table *nls_disk; /* Codepage used on disk */

fs/fat/inode.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,9 +673,9 @@ static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
673673
if (inode->i_ino == MSDOS_FSINFO_INO) {
674674
struct super_block *sb = inode->i_sb;
675675

676-
lock_super(sb);
676+
mutex_lock(&MSDOS_SB(sb)->s_lock);
677677
err = fat_clusters_flush(sb);
678-
unlock_super(sb);
678+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
679679
} else
680680
err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
681681

@@ -1268,6 +1268,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
12681268
b = (struct fat_boot_sector *) bh->b_data;
12691269
}
12701270

1271+
mutex_init(&sbi->s_lock);
12711272
sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus;
12721273
sbi->cluster_bits = ffs(sbi->cluster_size) - 1;
12731274
sbi->fats = b->fats;

fs/fat/namei_msdos.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
208208
struct inode *inode;
209209
int err;
210210

211-
lock_super(sb);
211+
mutex_lock(&MSDOS_SB(sb)->s_lock);
212212
err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
213213
switch (err) {
214214
case -ENOENT:
@@ -221,7 +221,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
221221
default:
222222
inode = ERR_PTR(err);
223223
}
224-
unlock_super(sb);
224+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
225225
return d_splice_alias(inode, dentry);
226226
}
227227

@@ -273,7 +273,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
273273
unsigned char msdos_name[MSDOS_NAME];
274274
int err, is_hid;
275275

276-
lock_super(sb);
276+
mutex_lock(&MSDOS_SB(sb)->s_lock);
277277

278278
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
279279
msdos_name, &MSDOS_SB(sb)->options);
@@ -302,7 +302,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
302302

303303
d_instantiate(dentry, inode);
304304
out:
305-
unlock_super(sb);
305+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
306306
if (!err)
307307
err = fat_flush_inodes(sb, dir, inode);
308308
return err;
@@ -316,7 +316,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
316316
struct fat_slot_info sinfo;
317317
int err;
318318

319-
lock_super(sb);
319+
mutex_lock(&MSDOS_SB(sb)->s_lock);
320320
/*
321321
* Check whether the directory is not in use, then check
322322
* whether it is empty.
@@ -337,7 +337,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
337337
inode->i_ctime = CURRENT_TIME_SEC;
338338
fat_detach(inode);
339339
out:
340-
unlock_super(sb);
340+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
341341
if (!err)
342342
err = fat_flush_inodes(sb, dir, inode);
343343

@@ -354,7 +354,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
354354
struct timespec ts;
355355
int err, is_hid, cluster;
356356

357-
lock_super(sb);
357+
mutex_lock(&MSDOS_SB(sb)->s_lock);
358358

359359
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
360360
msdos_name, &MSDOS_SB(sb)->options);
@@ -392,14 +392,14 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
392392

393393
d_instantiate(dentry, inode);
394394

395-
unlock_super(sb);
395+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
396396
fat_flush_inodes(sb, dir, inode);
397397
return 0;
398398

399399
out_free:
400400
fat_free_clusters(dir, cluster);
401401
out:
402-
unlock_super(sb);
402+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
403403
return err;
404404
}
405405

@@ -411,7 +411,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
411411
struct fat_slot_info sinfo;
412412
int err;
413413

414-
lock_super(sb);
414+
mutex_lock(&MSDOS_SB(sb)->s_lock);
415415
err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
416416
if (err)
417417
goto out;
@@ -423,7 +423,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
423423
inode->i_ctime = CURRENT_TIME_SEC;
424424
fat_detach(inode);
425425
out:
426-
unlock_super(sb);
426+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
427427
if (!err)
428428
err = fat_flush_inodes(sb, dir, inode);
429429

@@ -606,7 +606,7 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
606606
unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
607607
int err, is_hid;
608608

609-
lock_super(sb);
609+
mutex_lock(&MSDOS_SB(sb)->s_lock);
610610

611611
err = msdos_format_name(old_dentry->d_name.name,
612612
old_dentry->d_name.len, old_msdos_name,
@@ -625,7 +625,7 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
625625
err = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
626626
new_dir, new_msdos_name, new_dentry, is_hid);
627627
out:
628-
unlock_super(sb);
628+
mutex_unlock(&MSDOS_SB(sb)->s_lock);
629629
if (!err)
630630
err = fat_flush_inodes(sb, old_dir, new_dir);
631631
return err;

0 commit comments

Comments
 (0)