aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/coda/psdev.c8
-rw-r--r--fs/coda/upcall.c34
-rw-r--r--include/linux/coda_psdev.h3
3 files changed, 41 insertions, 4 deletions
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 241f7e04ad04..b4da2812499e 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -100,8 +100,12 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
100 ssize_t retval = 0, count = 0; 100 ssize_t retval = 0, count = 0;
101 int error; 101 int error;
102 102
103 /* make sure there is enough to copy out the (opcode, unique) values */
104 if (nbytes < (2 * sizeof(u_int32_t)))
105 return -EINVAL;
106
103 /* Peek at the opcode, uniquefier */ 107 /* Peek at the opcode, uniquefier */
104 if (copy_from_user(&hdr, buf, 2 * sizeof(u_long))) 108 if (copy_from_user(&hdr, buf, 2 * sizeof(u_int32_t)))
105 return -EFAULT; 109 return -EFAULT;
106 110
107 if (DOWNCALL(hdr.opcode)) { 111 if (DOWNCALL(hdr.opcode)) {
@@ -127,7 +131,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
127 } 131 }
128 132
129 /* what downcall errors does Venus handle ? */ 133 /* what downcall errors does Venus handle ? */
130 error = coda_downcall(vcp, hdr.opcode, dcbuf); 134 error = coda_downcall(vcp, hdr.opcode, dcbuf, nbytes);
131 135
132 CODA_FREE(dcbuf, nbytes); 136 CODA_FREE(dcbuf, nbytes);
133 if (error) { 137 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 @@ exit:
804 * 804 *
805 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */ 805 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
806 806
807int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) 807int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out,
808 size_t nbytes)
808{ 809{
809 struct inode *inode = NULL; 810 struct inode *inode = NULL;
810 struct CodaFid *fid = NULL, *newfid; 811 struct CodaFid *fid = NULL, *newfid;
811 struct super_block *sb; 812 struct super_block *sb;
812 813
814 /*
815 * Make sure we have received enough data from the cache
816 * manager to populate the necessary fields in the buffer
817 */
818 switch (opcode) {
819 case CODA_PURGEUSER:
820 if (nbytes < sizeof(struct coda_purgeuser_out))
821 return -EINVAL;
822 break;
823
824 case CODA_ZAPDIR:
825 if (nbytes < sizeof(struct coda_zapdir_out))
826 return -EINVAL;
827 break;
828
829 case CODA_ZAPFILE:
830 if (nbytes < sizeof(struct coda_zapfile_out))
831 return -EINVAL;
832 break;
833
834 case CODA_PURGEFID:
835 if (nbytes < sizeof(struct coda_purgefid_out))
836 return -EINVAL;
837 break;
838
839 case CODA_REPLACE:
840 if (nbytes < sizeof(struct coda_replace_out))
841 return -EINVAL;
842 break;
843 }
844
813 /* Handle invalidation requests. */ 845 /* Handle invalidation requests. */
814 mutex_lock(&vcp->vc_mutex); 846 mutex_lock(&vcp->vc_mutex);
815 sb = vcp->vc_sb; 847 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,
71int venus_access(struct super_block *sb, struct CodaFid *fid, int mask); 71int venus_access(struct super_block *sb, struct CodaFid *fid, int mask);
72int venus_pioctl(struct super_block *sb, struct CodaFid *fid, 72int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
73 unsigned int cmd, struct PioctlData *data); 73 unsigned int cmd, struct PioctlData *data);
74int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out); 74int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out,
75 size_t nbytes);
75int venus_fsync(struct super_block *sb, struct CodaFid *fid); 76int venus_fsync(struct super_block *sb, struct CodaFid *fid);
76int venus_statfs(struct dentry *dentry, struct kstatfs *sfs); 77int venus_statfs(struct dentry *dentry, struct kstatfs *sfs);
77 78