From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932481AbcHUPdR (ORCPT ); Sun, 21 Aug 2016 11:33:17 -0400 Received: from wtarreau.pck.nerim.net ([62.212.114.60]:55523 "EHLO 1wt.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932449AbcHUPdO (ORCPT ); Sun, 21 Aug 2016 11:33:14 -0400 From: Willy Tarreau To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Sachin Prabhu , Steve French , Willy Tarreau Subject: [PATCH 3.10 164/180] cifs: Check for existing directory when opening file with O_CREAT Date: Sun, 21 Aug 2016 17:31:34 +0200 Message-Id: <1471793510-13022-165-git-send-email-w@1wt.eu> X-Mailer: git-send-email 2.8.0.rc2.1.gbe9624a In-Reply-To: <1471793510-13022-1-git-send-email-w@1wt.eu> References: <1471793510-13022-1-git-send-email-w@1wt.eu> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sachin Prabhu commit 8d9535b6efd86e6c07da59f97e68f44efb7fe080 upstream. When opening a file with O_CREAT flag, check to see if the file opened is an existing directory. This prevents the directory from being opened which subsequently causes a crash when the close function for directories cifs_closedir() is called which frees up the file->private_data memory while the file is still listed on the open file list for the tcon. Signed-off-by: Sachin Prabhu Signed-off-by: Steve French CC: Stable Reported-by: Xiaoli Feng Signed-off-by: Willy Tarreau --- fs/cifs/dir.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 0c2425b..a998c92 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -227,6 +227,13 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, goto cifs_create_get_file_info; } + if (S_ISDIR(newinode->i_mode)) { + CIFSSMBClose(xid, tcon, fid->netfid); + iput(newinode); + rc = -EISDIR; + goto out; + } + if (!S_ISREG(newinode->i_mode)) { /* * The server may allow us to open things like @@ -391,10 +398,14 @@ cifs_create_set_dentry: if (rc != 0) { cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n", rc); - if (server->ops->close) - server->ops->close(xid, tcon, fid); - goto out; + goto out_err; } + + if (S_ISDIR(newinode->i_mode)) { + rc = -EISDIR; + goto out_err; + } + d_drop(direntry); d_add(direntry, newinode); @@ -402,6 +413,13 @@ out: kfree(buf); kfree(full_path); return rc; + +out_err: + if (server->ops->close) + server->ops->close(xid, tcon, fid); + if (newinode) + iput(newinode); + goto out; } int -- 2.8.0.rc2.1.gbe9624a