From patchwork Wed May 25 09:35:34 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 815472 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p4P9aYVm014409 for ; Wed, 25 May 2011 09:36:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754264Ab1EYJge (ORCPT ); Wed, 25 May 2011 05:36:34 -0400 Received: from mail-bw0-f46.google.com ([209.85.214.46]:35836 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753330Ab1EYJgd (ORCPT ); Wed, 25 May 2011 05:36:33 -0400 Received: by mail-bw0-f46.google.com with SMTP id 15so6367329bwz.19 for ; Wed, 25 May 2011 02:36:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:from:to:subject:date:message-id:x-mailer; bh=ASDaV+f1lsvjIDnW3Q7HBhYMCfldGklbv1IeCCbOjE0=; b=bN2j4gv0YCaqea5+nqdsfr9D/GwFwqPlJZl9WAj/m9xAqmcy84+9nWSyQPGWUkXf0y k5DuHzXqGgUeUVXXb/vr9ivjD79s/TpboQsp9UpS8a2l9LPucaTAcWOjW34ElbrA9mkV 3V8FGzQDdN4dd/u+NmHFT53+l7ZWnoBh5egF0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer; b=sTkCP5JBUf630AUYStr4omqv8wJ4GIhFmnGShUVeimqlVL6XERh+5pBzr728/izFrY LoCg+QKCb9vlBZp8J8g76QGVlgCGxsHiZwRSLU0YC5O2thiVy5RPFyzwOXtF/58cHJ7V mnnH7AlOHNMbFeu38f6hCR79ivLgGIRjdVYFs= Received: by 10.205.83.3 with SMTP id ae3mr604675bkc.71.1306316192900; Wed, 25 May 2011 02:36:32 -0700 (PDT) Received: from localhost.localdomain (PPPoE-78-29-101-206.san.ru [78.29.101.206]) by mx.google.com with ESMTPS id c11sm5094998bkc.2.2011.05.25.02.36.28 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 25 May 2011 02:36:29 -0700 (PDT) From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH] CIFS: Fix undefined behavior when mount fails Date: Wed, 25 May 2011 13:35:34 +0400 Message-Id: <1306316134-11736-1-git-send-email-piastry@etersoft.ru> X-Mailer: git-send-email 1.7.1 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 25 May 2011 09:36:35 +0000 (UTC) Fix double kfree() calls on the same pointers and cleanup mount code. Signed-off-by: Pavel Shilovsky --- fs/cifs/cifsfs.c | 44 +++++++++++++++++--------------------------- 1 files changed, 17 insertions(+), 27 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 131afad..d1ed7f9 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -104,29 +104,23 @@ cifs_sb_deactive(struct super_block *sb) } static int -cifs_read_super(struct super_block *sb, struct cifs_sb_info *cifs_sb, - void *data, struct smb_vol *volume_info, const char *devname, - int silent) +cifs_read_super(struct super_block *sb, struct smb_vol *volume_info, + const char *devname, int silent) { struct inode *inode; + struct cifs_sb_info *cifs_sb; int rc = 0; - /* BB should we make this contingent on mount parm? */ - sb->s_flags |= MS_NODIRATIME | MS_NOATIME; - sb->s_fs_info = cifs_sb; + cifs_sb = CIFS_SB(sb); spin_lock_init(&cifs_sb->tlink_tree_lock); cifs_sb->tlink_tree = RB_ROOT; rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); - if (rc) { - kfree(cifs_sb); + if (rc) return rc; - } - cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; - if (data) - cifs_sb->mountdata = data; + cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; rc = cifs_mount(sb, cifs_sb, volume_info, devname); @@ -179,15 +173,7 @@ out_no_root: cifs_umount(sb, cifs_sb); out_mount_failed: - if (cifs_sb) { - if (cifs_sb->mountdata) { - kfree(cifs_sb->mountdata); - cifs_sb->mountdata = NULL; - } - unload_nls(cifs_sb->local_nls); - bdi_destroy(&cifs_sb->bdi); - kfree(cifs_sb); - } + bdi_destroy(&cifs_sb->bdi); return rc; } @@ -553,7 +539,6 @@ cifs_do_mount(struct file_system_type *fs_type, struct cifs_sb_info *cifs_sb; struct smb_vol *volume_info; struct dentry *root; - char *copied_data = NULL; cFYI(1, "Devname: %s flags: %d ", dev_name, flags); @@ -576,20 +561,23 @@ cifs_do_mount(struct file_system_type *fs_type, goto out; } - sb->s_flags = flags; - /* * Copy mount params for use in submounts. Better to do * the copy here and deal with the error before cleanup gets * complicated post-mount. */ - copied_data = kstrndup(data, PAGE_SIZE, GFP_KERNEL); - if (copied_data == NULL) { + cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); + if (cifs_sb->mountdata == NULL) { root = ERR_PTR(-ENOMEM); goto err_out; } - rc = cifs_read_super(sb, cifs_sb, copied_data, volume_info, dev_name, + sb->s_flags = flags; + /* BB should we make this contingent on mount parm? */ + sb->s_flags |= MS_NODIRATIME | MS_NOATIME; + sb->s_fs_info = cifs_sb; + + rc = cifs_read_super(sb, volume_info, dev_name, flags & MS_SILENT ? 1 : 0); if (rc) { root = ERR_PTR(rc); @@ -604,6 +592,8 @@ out: return root; err_out: + kfree(cifs_sb->mountdata); + unload_nls(cifs_sb->local_nls); kfree(cifs_sb); deactivate_locked_super(sb); cifs_cleanup_volume_info(&volume_info);