aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-05-25 05:35:34 -0400
committerSteve French <sfrench@us.ibm.com>2011-05-25 16:02:31 -0400
commitb2e5cd33b598fb496b9366c445bd77c801efabb8 (patch)
tree19f404a46cc637c7d6034deec5d7b1f9b0553924 /fs/cifs
parent3c1105df699188a70f5c17dc0795affea388bca7 (diff)
CIFS: Fix undefined behavior when mount fails
Fix double kfree() calls on the same pointers and cleanup mount code. Reviewed-and-Tested-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c44
1 files changed, 17 insertions, 27 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 131afadce0e0..d1ed7f9946d5 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -104,29 +104,23 @@ cifs_sb_deactive(struct super_block *sb)
104} 104}
105 105
106static int 106static int
107cifs_read_super(struct super_block *sb, struct cifs_sb_info *cifs_sb, 107cifs_read_super(struct super_block *sb, struct smb_vol *volume_info,
108 void *data, struct smb_vol *volume_info, const char *devname, 108 const char *devname, int silent)
109 int silent)
110{ 109{
111 struct inode *inode; 110 struct inode *inode;
111 struct cifs_sb_info *cifs_sb;
112 int rc = 0; 112 int rc = 0;
113 113
114 /* BB should we make this contingent on mount parm? */ 114 cifs_sb = CIFS_SB(sb);
115 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
116 sb->s_fs_info = cifs_sb;
117 115
118 spin_lock_init(&cifs_sb->tlink_tree_lock); 116 spin_lock_init(&cifs_sb->tlink_tree_lock);
119 cifs_sb->tlink_tree = RB_ROOT; 117 cifs_sb->tlink_tree = RB_ROOT;
120 118
121 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); 119 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
122 if (rc) { 120 if (rc)
123 kfree(cifs_sb);
124 return rc; 121 return rc;
125 }
126 cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
127 122
128 if (data) 123 cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
129 cifs_sb->mountdata = data;
130 124
131 rc = cifs_mount(sb, cifs_sb, volume_info, devname); 125 rc = cifs_mount(sb, cifs_sb, volume_info, devname);
132 126
@@ -179,15 +173,7 @@ out_no_root:
179 cifs_umount(sb, cifs_sb); 173 cifs_umount(sb, cifs_sb);
180 174
181out_mount_failed: 175out_mount_failed:
182 if (cifs_sb) { 176 bdi_destroy(&cifs_sb->bdi);
183 if (cifs_sb->mountdata) {
184 kfree(cifs_sb->mountdata);
185 cifs_sb->mountdata = NULL;
186 }
187 unload_nls(cifs_sb->local_nls);
188 bdi_destroy(&cifs_sb->bdi);
189 kfree(cifs_sb);
190 }
191 return rc; 177 return rc;
192} 178}
193 179
@@ -553,7 +539,6 @@ cifs_do_mount(struct file_system_type *fs_type,
553 struct cifs_sb_info *cifs_sb; 539 struct cifs_sb_info *cifs_sb;
554 struct smb_vol *volume_info; 540 struct smb_vol *volume_info;
555 struct dentry *root; 541 struct dentry *root;
556 char *copied_data = NULL;
557 542
558 cFYI(1, "Devname: %s flags: %d ", dev_name, flags); 543 cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
559 544
@@ -576,20 +561,23 @@ cifs_do_mount(struct file_system_type *fs_type,
576 goto out; 561 goto out;
577 } 562 }
578 563
579 sb->s_flags = flags;
580
581 /* 564 /*
582 * Copy mount params for use in submounts. Better to do 565 * Copy mount params for use in submounts. Better to do
583 * the copy here and deal with the error before cleanup gets 566 * the copy here and deal with the error before cleanup gets
584 * complicated post-mount. 567 * complicated post-mount.
585 */ 568 */
586 copied_data = kstrndup(data, PAGE_SIZE, GFP_KERNEL); 569 cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
587 if (copied_data == NULL) { 570 if (cifs_sb->mountdata == NULL) {
588 root = ERR_PTR(-ENOMEM); 571 root = ERR_PTR(-ENOMEM);
589 goto err_out; 572 goto err_out;
590 } 573 }
591 574
592 rc = cifs_read_super(sb, cifs_sb, copied_data, volume_info, dev_name, 575 sb->s_flags = flags;
576 /* BB should we make this contingent on mount parm? */
577 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
578 sb->s_fs_info = cifs_sb;
579
580 rc = cifs_read_super(sb, volume_info, dev_name,
593 flags & MS_SILENT ? 1 : 0); 581 flags & MS_SILENT ? 1 : 0);
594 if (rc) { 582 if (rc) {
595 root = ERR_PTR(rc); 583 root = ERR_PTR(rc);
@@ -604,6 +592,8 @@ out:
604 return root; 592 return root;
605 593
606err_out: 594err_out:
595 kfree(cifs_sb->mountdata);
596 unload_nls(cifs_sb->local_nls);
607 kfree(cifs_sb); 597 kfree(cifs_sb);
608 deactivate_locked_super(sb); 598 deactivate_locked_super(sb);
609 cifs_cleanup_volume_info(&volume_info); 599 cifs_cleanup_volume_info(&volume_info);