diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-08-01 04:29:18 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-08-01 11:25:25 -0400 |
commit | 77e69dac3cefacee939cb107ae9cd520a62338e0 (patch) | |
tree | 02ddee5ac85ceb632eab2aff994ffbd3233e51eb /fs/reiserfs/super.c | |
parent | 1b7e190b4764ea3ca1080404dd593eae5230d2b3 (diff) |
[PATCH] fix races and leaks in vfs_quota_on() users
* new helper: vfs_quota_on_path(); equivalent of vfs_quota_on() sans the
pathname resolution.
* callers of vfs_quota_on() that do their own pathname resolution and
checks based on it are switched to vfs_quota_on_path(); that way we
avoid the races.
* reiserfs leaked dentry/vfsmount references on several failure exits.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r-- | fs/reiserfs/super.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 879e54d35c2d..282a13596c70 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -2076,8 +2076,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2076 | return err; | 2076 | return err; |
2077 | /* Quotafile not on the same filesystem? */ | 2077 | /* Quotafile not on the same filesystem? */ |
2078 | if (nd.path.mnt->mnt_sb != sb) { | 2078 | if (nd.path.mnt->mnt_sb != sb) { |
2079 | path_put(&nd.path); | 2079 | err = -EXDEV; |
2080 | return -EXDEV; | 2080 | goto out; |
2081 | } | 2081 | } |
2082 | inode = nd.path.dentry->d_inode; | 2082 | inode = nd.path.dentry->d_inode; |
2083 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ | 2083 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ |
@@ -2087,8 +2087,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2087 | reiserfs_warning(sb, | 2087 | reiserfs_warning(sb, |
2088 | "reiserfs: Unpacking tail of quota file failed" | 2088 | "reiserfs: Unpacking tail of quota file failed" |
2089 | " (%d). Cannot turn on quotas.", err); | 2089 | " (%d). Cannot turn on quotas.", err); |
2090 | path_put(&nd.path); | 2090 | err = -EINVAL; |
2091 | return -EINVAL; | 2091 | goto out; |
2092 | } | 2092 | } |
2093 | mark_inode_dirty(inode); | 2093 | mark_inode_dirty(inode); |
2094 | } | 2094 | } |
@@ -2109,13 +2109,15 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2109 | /* Just start temporary transaction and finish it */ | 2109 | /* Just start temporary transaction and finish it */ |
2110 | err = journal_begin(&th, sb, 1); | 2110 | err = journal_begin(&th, sb, 1); |
2111 | if (err) | 2111 | if (err) |
2112 | return err; | 2112 | goto out; |
2113 | err = journal_end_sync(&th, sb, 1); | 2113 | err = journal_end_sync(&th, sb, 1); |
2114 | if (err) | 2114 | if (err) |
2115 | return err; | 2115 | goto out; |
2116 | } | 2116 | } |
2117 | err = vfs_quota_on_path(sb, type, format_id, &nd.path); | ||
2118 | out: | ||
2117 | path_put(&nd.path); | 2119 | path_put(&nd.path); |
2118 | return vfs_quota_on(sb, type, format_id, path, 0); | 2120 | return err; |
2119 | } | 2121 | } |
2120 | 2122 | ||
2121 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | 2123 | /* Read data from quotafile - avoid pagecache and such because we cannot afford |