Skip to content

Commit a0e881b

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs pile from Al Viro: "The stuff in there: fsfreeze deadlock fixes by Jan (essentially, the deadlock reproduced by xfstests 068), symlink and hardlink restriction patches, plus assorted cleanups and fixes. Note that another fsfreeze deadlock (emergency thaw one) is *not* dealt with - the series by Fernando conflicts a lot with Jan's, breaks userland ABI (FIFREEZE semantics gets changed) and trades the deadlock for massive vfsmount leak; this is going to be handled next cycle. There probably will be another pull request, but that stuff won't be in it." Fix up trivial conflicts due to unrelated changes next to each other in drivers/{staging/gdm72xx/usb_boot.c, usb/gadget/storage_common.c} * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (54 commits) delousing target_core_file a bit Documentation: Correct s_umount state for freeze_fs/unfreeze_fs fs: Remove old freezing mechanism ext2: Implement freezing btrfs: Convert to new freezing mechanism nilfs2: Convert to new freezing mechanism ntfs: Convert to new freezing mechanism fuse: Convert to new freezing mechanism gfs2: Convert to new freezing mechanism ocfs2: Convert to new freezing mechanism xfs: Convert to new freezing code ext4: Convert to new freezing mechanism fs: Protect write paths by sb_start_write - sb_end_write fs: Skip atime update on frozen filesystem fs: Add freezing handling to mnt_want_write() / mnt_drop_write() fs: Improve filesystem freezing handling switch the protection of percpu_counter list to spinlock nfsd: Push mnt_want_write() outside of i_mutex btrfs: Push mnt_want_write() outside of i_mutex fat: Push mnt_want_write() outside of i_mutex ...
2 parents eff0d13 + dbc6e02 commit a0e881b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1326
-639
lines changed

Documentation/filesystems/Locking

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ evict_inode:
138138
put_super: write
139139
write_super: read
140140
sync_fs: read
141-
freeze_fs: read
142-
unfreeze_fs: read
141+
freeze_fs: write
142+
unfreeze_fs: write
143143
statfs: maybe(read) (see below)
144144
remount_fs: write
145145
umount_begin: no

Documentation/sysctl/fs.txt

+42
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs:
3232
- nr_open
3333
- overflowuid
3434
- overflowgid
35+
- protected_hardlinks
36+
- protected_symlinks
3537
- suid_dumpable
3638
- super-max
3739
- super-nr
@@ -157,6 +159,46 @@ The default is 65534.
157159

158160
==============================================================
159161

162+
protected_hardlinks:
163+
164+
A long-standing class of security issues is the hardlink-based
165+
time-of-check-time-of-use race, most commonly seen in world-writable
166+
directories like /tmp. The common method of exploitation of this flaw
167+
is to cross privilege boundaries when following a given hardlink (i.e. a
168+
root process follows a hardlink created by another user). Additionally,
169+
on systems without separated partitions, this stops unauthorized users
170+
from "pinning" vulnerable setuid/setgid files against being upgraded by
171+
the administrator, or linking to special files.
172+
173+
When set to "0", hardlink creation behavior is unrestricted.
174+
175+
When set to "1" hardlinks cannot be created by users if they do not
176+
already own the source file, or do not have read/write access to it.
177+
178+
This protection is based on the restrictions in Openwall and grsecurity.
179+
180+
==============================================================
181+
182+
protected_symlinks:
183+
184+
A long-standing class of security issues is the symlink-based
185+
time-of-check-time-of-use race, most commonly seen in world-writable
186+
directories like /tmp. The common method of exploitation of this flaw
187+
is to cross privilege boundaries when following a given symlink (i.e. a
188+
root process follows a symlink belonging to another user). For a likely
189+
incomplete list of hundreds of examples across the years, please see:
190+
http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
191+
192+
When set to "0", symlink following behavior is unrestricted.
193+
194+
When set to "1" symlinks are permitted to be followed only when outside
195+
a sticky world-writable directory, or when the uid of the symlink and
196+
follower match, or when the directory owner matches the symlink's owner.
197+
198+
This protection is based on the restrictions in Openwall and grsecurity.
199+
200+
==============================================================
201+
160202
suid_dumpable:
161203

162204
This value can be used to query and set the core dump mode for setuid

arch/powerpc/platforms/cell/spufs/inode.c

+25-52
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,13 @@ static void spufs_prune_dir(struct dentry *dir)
186186
static int spufs_rmdir(struct inode *parent, struct dentry *dir)
187187
{
188188
/* remove all entries */
189+
int res;
189190
spufs_prune_dir(dir);
190191
d_drop(dir);
191-
192-
return simple_rmdir(parent, dir);
192+
res = simple_rmdir(parent, dir);
193+
/* We have to give up the mm_struct */
194+
spu_forget(SPUFS_I(dir->d_inode)->i_ctx);
195+
return res;
193196
}
194197

195198
static int spufs_fill_dir(struct dentry *dir,
@@ -245,9 +248,6 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
245248
mutex_unlock(&parent->i_mutex);
246249
WARN_ON(ret);
247250

248-
/* We have to give up the mm_struct */
249-
spu_forget(ctx);
250-
251251
return dcache_dir_close(inode, file);
252252
}
253253

@@ -450,28 +450,24 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
450450
struct spu_context *neighbor;
451451
struct path path = {.mnt = mnt, .dentry = dentry};
452452

453-
ret = -EPERM;
454453
if ((flags & SPU_CREATE_NOSCHED) &&
455454
!capable(CAP_SYS_NICE))
456-
goto out_unlock;
455+
return -EPERM;
457456

458-
ret = -EINVAL;
459457
if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))
460458
== SPU_CREATE_ISOLATE)
461-
goto out_unlock;
459+
return -EINVAL;
462460

463-
ret = -ENODEV;
464461
if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
465-
goto out_unlock;
462+
return -ENODEV;
466463

467464
gang = NULL;
468465
neighbor = NULL;
469466
affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);
470467
if (affinity) {
471468
gang = SPUFS_I(inode)->i_gang;
472-
ret = -EINVAL;
473469
if (!gang)
474-
goto out_unlock;
470+
return -EINVAL;
475471
mutex_lock(&gang->aff_mutex);
476472
neighbor = spufs_assert_affinity(flags, gang, aff_filp);
477473
if (IS_ERR(neighbor)) {
@@ -492,22 +488,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
492488
}
493489

494490
ret = spufs_context_open(&path);
495-
if (ret < 0) {
491+
if (ret < 0)
496492
WARN_ON(spufs_rmdir(inode, dentry));
497-
if (affinity)
498-
mutex_unlock(&gang->aff_mutex);
499-
mutex_unlock(&inode->i_mutex);
500-
spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
501-
goto out;
502-
}
503493

504494
out_aff_unlock:
505495
if (affinity)
506496
mutex_unlock(&gang->aff_mutex);
507-
out_unlock:
508-
mutex_unlock(&inode->i_mutex);
509-
out:
510-
dput(dentry);
511497
return ret;
512498
}
513499

@@ -580,18 +566,13 @@ static int spufs_create_gang(struct inode *inode,
580566
int ret;
581567

582568
ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO);
583-
if (ret)
584-
goto out;
585-
586-
ret = spufs_gang_open(&path);
587-
if (ret < 0) {
588-
int err = simple_rmdir(inode, dentry);
589-
WARN_ON(err);
569+
if (!ret) {
570+
ret = spufs_gang_open(&path);
571+
if (ret < 0) {
572+
int err = simple_rmdir(inode, dentry);
573+
WARN_ON(err);
574+
}
590575
}
591-
592-
out:
593-
mutex_unlock(&inode->i_mutex);
594-
dput(dentry);
595576
return ret;
596577
}
597578

@@ -601,40 +582,32 @@ static struct file_system_type spufs_type;
601582
long spufs_create(struct path *path, struct dentry *dentry,
602583
unsigned int flags, umode_t mode, struct file *filp)
603584
{
585+
struct inode *dir = path->dentry->d_inode;
604586
int ret;
605587

606-
ret = -EINVAL;
607588
/* check if we are on spufs */
608589
if (path->dentry->d_sb->s_type != &spufs_type)
609-
goto out;
590+
return -EINVAL;
610591

611592
/* don't accept undefined flags */
612593
if (flags & (~SPU_CREATE_FLAG_ALL))
613-
goto out;
594+
return -EINVAL;
614595

615596
/* only threads can be underneath a gang */
616-
if (path->dentry != path->dentry->d_sb->s_root) {
617-
if ((flags & SPU_CREATE_GANG) ||
618-
!SPUFS_I(path->dentry->d_inode)->i_gang)
619-
goto out;
620-
}
597+
if (path->dentry != path->dentry->d_sb->s_root)
598+
if ((flags & SPU_CREATE_GANG) || !SPUFS_I(dir)->i_gang)
599+
return -EINVAL;
621600

622601
mode &= ~current_umask();
623602

624603
if (flags & SPU_CREATE_GANG)
625-
ret = spufs_create_gang(path->dentry->d_inode,
626-
dentry, path->mnt, mode);
604+
ret = spufs_create_gang(dir, dentry, path->mnt, mode);
627605
else
628-
ret = spufs_create_context(path->dentry->d_inode,
629-
dentry, path->mnt, flags, mode,
606+
ret = spufs_create_context(dir, dentry, path->mnt, flags, mode,
630607
filp);
631608
if (ret >= 0)
632-
fsnotify_mkdir(path->dentry->d_inode, dentry);
633-
return ret;
609+
fsnotify_mkdir(dir, dentry);
634610

635-
out:
636-
mutex_unlock(&path->dentry->d_inode->i_mutex);
637-
dput(dentry);
638611
return ret;
639612
}
640613

arch/powerpc/platforms/cell/spufs/syscalls.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
7070
ret = PTR_ERR(dentry);
7171
if (!IS_ERR(dentry)) {
7272
ret = spufs_create(&path, dentry, flags, mode, neighbor);
73-
path_put(&path);
73+
done_path_create(&path, dentry);
7474
}
7575

7676
return ret;

drivers/base/devtmpfs.c

+2-7
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,7 @@ static int dev_mkdir(const char *name, umode_t mode)
156156
if (!err)
157157
/* mark as kernel-created inode */
158158
dentry->d_inode->i_private = &thread;
159-
dput(dentry);
160-
mutex_unlock(&path.dentry->d_inode->i_mutex);
161-
path_put(&path);
159+
done_path_create(&path, dentry);
162160
return err;
163161
}
164162

@@ -218,10 +216,7 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)
218216
/* mark as kernel-created inode */
219217
dentry->d_inode->i_private = &thread;
220218
}
221-
dput(dentry);
222-
223-
mutex_unlock(&path.dentry->d_inode->i_mutex);
224-
path_put(&path);
219+
done_path_create(&path, dentry);
225220
return err;
226221
}
227222

drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
11881188
kfree(buf);
11891189
/* close file before return */
11901190
if (fp)
1191-
filp_close(fp, current->files);
1191+
filp_close(fp, NULL);
11921192
/* restore previous address limit */
11931193
set_fs(old_fs);
11941194

drivers/staging/bcm/Misc.c

+5-26
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,7 @@ static int create_worker_threads(struct bcm_mini_adapter *psAdapter)
157157

158158
static struct file *open_firmware_file(struct bcm_mini_adapter *Adapter, const char *path)
159159
{
160-
struct file *flp = NULL;
161-
mm_segment_t oldfs;
162-
oldfs = get_fs();
163-
set_fs(get_ds());
164-
flp = filp_open(path, O_RDONLY, S_IRWXU);
165-
set_fs(oldfs);
160+
struct file *flp = filp_open(path, O_RDONLY, S_IRWXU);
166161
if (IS_ERR(flp)) {
167162
pr_err(DRV_NAME "Unable To Open File %s, err %ld", path, PTR_ERR(flp));
168163
flp = NULL;
@@ -183,14 +178,12 @@ static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, u
183178
{
184179
int errorno = 0;
185180
struct file *flp = NULL;
186-
mm_segment_t oldfs;
187181
struct timeval tv = {0};
188182

189183
flp = open_firmware_file(Adapter, path);
190184
if (!flp) {
191-
errorno = -ENOENT;
192185
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path);
193-
goto exit_download;
186+
return -ENOENT;
194187
}
195188
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path, (unsigned long)flp->f_dentry->d_inode->i_size, loc);
196189
do_gettimeofday(&tv);
@@ -201,23 +194,15 @@ static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, u
201194
errorno = -EIO;
202195
goto exit_download;
203196
}
204-
oldfs = get_fs();
205-
set_fs(get_ds());
206197
vfs_llseek(flp, 0, 0);
207-
set_fs(oldfs);
208198
if (Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, flp, loc)) {
209199
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!");
210200
errorno = -EIO;
211201
goto exit_download;
212202
}
213203

214204
exit_download:
215-
oldfs = get_fs();
216-
set_fs(get_ds());
217-
if (flp && !(IS_ERR(flp)))
218-
filp_close(flp, current->files);
219-
set_fs(oldfs);
220-
205+
filp_close(flp, NULL);
221206
return errorno;
222207
}
223208

@@ -1056,10 +1041,8 @@ int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter)
10561041
static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter)
10571042
{
10581043
struct file *flp = NULL;
1059-
mm_segment_t oldfs = {0};
10601044
char *buff;
10611045
int len = 0;
1062-
loff_t pos = 0;
10631046

10641047
buff = kmalloc(BUFFER_1K, GFP_KERNEL);
10651048
if (!buff)
@@ -1079,20 +1062,16 @@ static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter)
10791062
Adapter->pstargetparams = NULL;
10801063
return -ENOENT;
10811064
}
1082-
oldfs = get_fs();
1083-
set_fs(get_ds());
1084-
len = vfs_read(flp, (void __user __force *)buff, BUFFER_1K, &pos);
1085-
set_fs(oldfs);
1065+
len = kernel_read(flp, 0, buff, BUFFER_1K);
1066+
filp_close(flp, NULL);
10861067

10871068
if (len != sizeof(STARGETPARAMS)) {
10881069
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Mismatch in Target Param Structure!\n");
10891070
kfree(buff);
10901071
kfree(Adapter->pstargetparams);
10911072
Adapter->pstargetparams = NULL;
1092-
filp_close(flp, current->files);
10931073
return -ENOENT;
10941074
}
1095-
filp_close(flp, current->files);
10961075

10971076
/* Check for autolink in config params */
10981077
/*

drivers/staging/gdm72xx/sdio_boot.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@ static int download_image(struct sdio_func *func, char *img_name)
6666
return -ENOENT;
6767
}
6868

69-
if (filp->f_dentry)
70-
inode = filp->f_dentry->d_inode;
71-
if (!inode || !S_ISREG(inode->i_mode)) {
69+
inode = filp->f_dentry->d_inode;
70+
if (!S_ISREG(inode->i_mode)) {
7271
printk(KERN_ERR "Invalid file type: %s\n", img_name);
7372
ret = -EINVAL;
7473
goto out;
@@ -123,7 +122,7 @@ static int download_image(struct sdio_func *func, char *img_name)
123122
pno++;
124123
}
125124
out:
126-
filp_close(filp, current->files);
125+
filp_close(filp, NULL);
127126
return ret;
128127
}
129128

0 commit comments

Comments
 (0)