From patchwork Fri May 17 18:36:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Harkes X-Patchwork-Id: 10948331 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9DF786C5 for ; Fri, 17 May 2019 18:37:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 914AB28173 for ; Fri, 17 May 2019 18:37:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8527428415; Fri, 17 May 2019 18:37:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1D51828173 for ; Fri, 17 May 2019 18:37:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728723AbfEQShE (ORCPT ); Fri, 17 May 2019 14:37:04 -0400 Received: from hurricane.elijah.cs.cmu.edu ([128.2.209.191]:57578 "EHLO hurricane.elijah.cs.cmu.edu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728546AbfEQShC (ORCPT ); Fri, 17 May 2019 14:37:02 -0400 Received: from jaharkes by hurricane.elijah.cs.cmu.edu with local (Exim 4.92) (envelope-from ) id 1hRhj2-0000o3-Ii; Fri, 17 May 2019 14:37:00 -0400 From: Jan Harkes To: Andrew Morton Cc: Jan Harkes , linux-fsdevel@vger.kernel.org, Dan Carpenter Subject: [PATCH 05/22] coda: potential buffer overflow in coda_psdev_write() Date: Fri, 17 May 2019 14:36:43 -0400 Message-Id: <894fb6b250add09e4e3935f14649f21284a5cb18.1558117389.git.jaharkes@cs.cmu.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add checks to make sure the downcall message we got from the Coda cache manager is large enough to contain the data it is supposed to have. i.e. when we get a CODA_ZAPDIR we can access &out->coda_zapdir.CodaFid. Reported-by: Dan Carpenter Signed-off-by: Jan Harkes --- fs/coda/psdev.c | 8 ++++++-- fs/coda/upcall.c | 34 +++++++++++++++++++++++++++++++++- include/linux/coda_psdev.h | 3 ++- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 12cec325384c..0cd646a5d0c2 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -104,8 +104,12 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, ssize_t retval = 0, count = 0; int error; + /* make sure there is enough to copy out the (opcode, unique) values */ + if (nbytes < (2 * sizeof(u_int32_t))) + return -EINVAL; + /* Peek at the opcode, uniquefier */ - if (copy_from_user(&hdr, buf, 2 * sizeof(u_long))) + if (copy_from_user(&hdr, buf, 2 * sizeof(u_int32_t))) return -EFAULT; if (DOWNCALL(hdr.opcode)) { @@ -131,7 +135,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, } /* what downcall errors does Venus handle ? */ - error = coda_downcall(vcp, hdr.opcode, dcbuf); + error = coda_downcall(vcp, hdr.opcode, dcbuf, nbytes); CODA_FREE(dcbuf, nbytes); if (error) { diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index 1175a1722411..cf1e662681a5 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -804,12 +804,44 @@ static int coda_upcall(struct venus_comm *vcp, * * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */ -int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) +int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out, + size_t nbytes) { struct inode *inode = NULL; struct CodaFid *fid = NULL, *newfid; struct super_block *sb; + /* + * Make sure we have received enough data from the cache + * manager to populate the necessary fields in the buffer + */ + switch (opcode) { + case CODA_PURGEUSER: + if (nbytes < sizeof(struct coda_purgeuser_out)) + return -EINVAL; + break; + + case CODA_ZAPDIR: + if (nbytes < sizeof(struct coda_zapdir_out)) + return -EINVAL; + break; + + case CODA_ZAPFILE: + if (nbytes < sizeof(struct coda_zapfile_out)) + return -EINVAL; + break; + + case CODA_PURGEFID: + if (nbytes < sizeof(struct coda_purgefid_out)) + return -EINVAL; + break; + + case CODA_REPLACE: + if (nbytes < sizeof(struct coda_replace_out)) + return -EINVAL; + break; + } + /* Handle invalidation requests. */ mutex_lock(&vcp->vc_mutex); sb = vcp->vc_sb; diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h index 57d2b2faf6a3..d1672fd5e638 100644 --- a/include/linux/coda_psdev.h +++ b/include/linux/coda_psdev.h @@ -71,7 +71,8 @@ int venus_symlink(struct super_block *sb, struct CodaFid *fid, int venus_access(struct super_block *sb, struct CodaFid *fid, int mask); int venus_pioctl(struct super_block *sb, struct CodaFid *fid, unsigned int cmd, struct PioctlData *data); -int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out); +int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out, + size_t nbytes); int venus_fsync(struct super_block *sb, struct CodaFid *fid); int venus_statfs(struct dentry *dentry, struct kstatfs *sfs);