linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jan Harkes <jaharkes@cs.cmu.edu>
To: Dan Carpenter <dan.carpenter@oracle.com>
Cc: kernel-janitors@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH v3] fs/coda: potential buffer overflow in coda_psdev_write()
Date: Fri, 13 Jul 2018 22:24:36 -0400	[thread overview]
Message-ID: <20180714022435.5lzzhzmpyn5cge5q@cs.cmu.edu> (raw)
In-Reply-To: <20180713190503.eei3axzltm7pt4aa@mwanda>

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 <dan.carpenter@oracle.com
Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu>


diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index c5234c21b539..43e8cc8dbf26 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -105,8 +105,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)) {
@@ -132,7 +136,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..c3c35a80659b 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -804,12 +804,42 @@ 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 15170954aa2b..a553242b30c1 100644
--- a/include/linux/coda_psdev.h
+++ b/include/linux/coda_psdev.h
@@ -60,7 +60,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);
 

      parent reply	other threads:[~2018-07-14  2:41 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-12 12:32 [PATCH] fs/coda: potential buffer overflow in coda_psdev_write() Dan Carpenter
2018-07-12 15:31 ` Jan Harkes
2018-07-12 15:50   ` Dan Carpenter
     [not found] ` <20180713151017.lxbv4eljvd6olziq@kili.mountain>
     [not found]   ` <20180713161630.olrwa2n2tnpqbmlt@cs.cmu.edu>
2018-07-13 19:05     ` [PATCH v2] " Dan Carpenter
2018-07-13 19:08       ` Jan Harkes
2018-07-14  2:24       ` Jan Harkes [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180714022435.5lzzhzmpyn5cge5q@cs.cmu.edu \
    --to=jaharkes@cs.cmu.edu \
    --cc=dan.carpenter@oracle.com \
    --cc=kernel-janitors@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).