diff options
-rw-r--r-- | fs/coda/psdev.c | 8 | ||||
-rw-r--r-- | fs/coda/upcall.c | 34 | ||||
-rw-r--r-- | 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 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 | ||
807 | int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) | 807 | int 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, | |||
71 | int venus_access(struct super_block *sb, struct CodaFid *fid, int mask); | 71 | int venus_access(struct super_block *sb, struct CodaFid *fid, int mask); |
72 | int venus_pioctl(struct super_block *sb, struct CodaFid *fid, | 72 | int venus_pioctl(struct super_block *sb, struct CodaFid *fid, |
73 | unsigned int cmd, struct PioctlData *data); | 73 | unsigned int cmd, struct PioctlData *data); |
74 | int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out); | 74 | int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out, |
75 | size_t nbytes); | ||
75 | int venus_fsync(struct super_block *sb, struct CodaFid *fid); | 76 | int venus_fsync(struct super_block *sb, struct CodaFid *fid); |
76 | int venus_statfs(struct dentry *dentry, struct kstatfs *sfs); | 77 | int venus_statfs(struct dentry *dentry, struct kstatfs *sfs); |
77 | 78 | ||