aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/conv.c157
-rw-r--r--fs/9p/v9fs.c8
-rw-r--r--fs/9p/vfs_inode.c4
-rw-r--r--fs/9p/vfs_super.c24
4 files changed, 102 insertions, 91 deletions
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index 1554731bd653..18121af99d3e 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * 9P protocol conversion functions 4 * 9P protocol conversion functions
5 * 5 *
6 * Copyright (C) 2004, 2005 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 9 *
@@ -55,66 +56,70 @@ static inline int buf_check_overflow(struct cbuf *buf)
55 return buf->p > buf->ep; 56 return buf->p > buf->ep;
56} 57}
57 58
58static inline void buf_check_size(struct cbuf *buf, int len) 59static inline int buf_check_size(struct cbuf *buf, int len)
59{ 60{
60 if (buf->p+len > buf->ep) { 61 if (buf->p+len > buf->ep) {
61 if (buf->p < buf->ep) { 62 if (buf->p < buf->ep) {
62 eprintk(KERN_ERR, "buffer overflow\n"); 63 eprintk(KERN_ERR, "buffer overflow\n");
63 buf->p = buf->ep + 1; 64 buf->p = buf->ep + 1;
65 return 0;
64 } 66 }
65 } 67 }
68
69 return 1;
66} 70}
67 71
68static inline void *buf_alloc(struct cbuf *buf, int len) 72static inline void *buf_alloc(struct cbuf *buf, int len)
69{ 73{
70 void *ret = NULL; 74 void *ret = NULL;
71 75
72 buf_check_size(buf, len); 76 if (buf_check_size(buf, len)) {
73 ret = buf->p; 77 ret = buf->p;
74 buf->p += len; 78 buf->p += len;
79 }
75 80
76 return ret; 81 return ret;
77} 82}
78 83
79static inline void buf_put_int8(struct cbuf *buf, u8 val) 84static inline void buf_put_int8(struct cbuf *buf, u8 val)
80{ 85{
81 buf_check_size(buf, 1); 86 if (buf_check_size(buf, 1)) {
82 87 buf->p[0] = val;
83 buf->p[0] = val; 88 buf->p++;
84 buf->p++; 89 }
85} 90}
86 91
87static inline void buf_put_int16(struct cbuf *buf, u16 val) 92static inline void buf_put_int16(struct cbuf *buf, u16 val)
88{ 93{
89 buf_check_size(buf, 2); 94 if (buf_check_size(buf, 2)) {
90 95 *(__le16 *) buf->p = cpu_to_le16(val);
91 *(__le16 *) buf->p = cpu_to_le16(val); 96 buf->p += 2;
92 buf->p += 2; 97 }
93} 98}
94 99
95static inline void buf_put_int32(struct cbuf *buf, u32 val) 100static inline void buf_put_int32(struct cbuf *buf, u32 val)
96{ 101{
97 buf_check_size(buf, 4); 102 if (buf_check_size(buf, 4)) {
98 103 *(__le32 *)buf->p = cpu_to_le32(val);
99 *(__le32 *)buf->p = cpu_to_le32(val); 104 buf->p += 4;
100 buf->p += 4; 105 }
101} 106}
102 107
103static inline void buf_put_int64(struct cbuf *buf, u64 val) 108static inline void buf_put_int64(struct cbuf *buf, u64 val)
104{ 109{
105 buf_check_size(buf, 8); 110 if (buf_check_size(buf, 8)) {
106 111 *(__le64 *)buf->p = cpu_to_le64(val);
107 *(__le64 *)buf->p = cpu_to_le64(val); 112 buf->p += 8;
108 buf->p += 8; 113 }
109} 114}
110 115
111static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) 116static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
112{ 117{
113 buf_check_size(buf, slen + 2); 118 if (buf_check_size(buf, slen + 2)) {
114 119 buf_put_int16(buf, slen);
115 buf_put_int16(buf, slen); 120 memcpy(buf->p, s, slen);
116 memcpy(buf->p, s, slen); 121 buf->p += slen;
117 buf->p += slen; 122 }
118} 123}
119 124
120static inline void buf_put_string(struct cbuf *buf, const char *s) 125static inline void buf_put_string(struct cbuf *buf, const char *s)
@@ -124,20 +129,20 @@ static inline void buf_put_string(struct cbuf *buf, const char *s)
124 129
125static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen) 130static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen)
126{ 131{
127 buf_check_size(buf, datalen); 132 if (buf_check_size(buf, datalen)) {
128 133 memcpy(buf->p, data, datalen);
129 memcpy(buf->p, data, datalen); 134 buf->p += datalen;
130 buf->p += datalen; 135 }
131} 136}
132 137
133static inline u8 buf_get_int8(struct cbuf *buf) 138static inline u8 buf_get_int8(struct cbuf *buf)
134{ 139{
135 u8 ret = 0; 140 u8 ret = 0;
136 141
137 buf_check_size(buf, 1); 142 if (buf_check_size(buf, 1)) {
138 ret = buf->p[0]; 143 ret = buf->p[0];
139 144 buf->p++;
140 buf->p++; 145 }
141 146
142 return ret; 147 return ret;
143} 148}
@@ -146,10 +151,10 @@ static inline u16 buf_get_int16(struct cbuf *buf)
146{ 151{
147 u16 ret = 0; 152 u16 ret = 0;
148 153
149 buf_check_size(buf, 2); 154 if (buf_check_size(buf, 2)) {
150 ret = le16_to_cpu(*(__le16 *)buf->p); 155 ret = le16_to_cpu(*(__le16 *)buf->p);
151 156 buf->p += 2;
152 buf->p += 2; 157 }
153 158
154 return ret; 159 return ret;
155} 160}
@@ -158,10 +163,10 @@ static inline u32 buf_get_int32(struct cbuf *buf)
158{ 163{
159 u32 ret = 0; 164 u32 ret = 0;
160 165
161 buf_check_size(buf, 4); 166 if (buf_check_size(buf, 4)) {
162 ret = le32_to_cpu(*(__le32 *)buf->p); 167 ret = le32_to_cpu(*(__le32 *)buf->p);
163 168 buf->p += 4;
164 buf->p += 4; 169 }
165 170
166 return ret; 171 return ret;
167} 172}
@@ -170,10 +175,10 @@ static inline u64 buf_get_int64(struct cbuf *buf)
170{ 175{
171 u64 ret = 0; 176 u64 ret = 0;
172 177
173 buf_check_size(buf, 8); 178 if (buf_check_size(buf, 8)) {
174 ret = le64_to_cpu(*(__le64 *)buf->p); 179 ret = le64_to_cpu(*(__le64 *)buf->p);
175 180 buf->p += 8;
176 buf->p += 8; 181 }
177 182
178 return ret; 183 return ret;
179} 184}
@@ -181,27 +186,35 @@ static inline u64 buf_get_int64(struct cbuf *buf)
181static inline int 186static inline int
182buf_get_string(struct cbuf *buf, char *data, unsigned int datalen) 187buf_get_string(struct cbuf *buf, char *data, unsigned int datalen)
183{ 188{
189 u16 len = 0;
190
191 len = buf_get_int16(buf);
192 if (!buf_check_overflow(buf) && buf_check_size(buf, len) && len+1>datalen) {
193 memcpy(data, buf->p, len);
194 data[len] = 0;
195 buf->p += len;
196 len++;
197 }
184 198
185 u16 len = buf_get_int16(buf); 199 return len;
186 buf_check_size(buf, len);
187 if (len + 1 > datalen)
188 return 0;
189
190 memcpy(data, buf->p, len);
191 data[len] = 0;
192 buf->p += len;
193
194 return len + 1;
195} 200}
196 201
197static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf) 202static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
198{ 203{
199 char *ret = NULL; 204 char *ret;
200 int n = buf_get_string(buf, sbuf->p, sbuf->ep - sbuf->p); 205 u16 len;
206
207 ret = NULL;
208 len = buf_get_int16(buf);
201 209
202 if (n > 0) { 210 if (!buf_check_overflow(buf) && buf_check_size(buf, len) &&
211 buf_check_size(sbuf, len+1)) {
212
213 memcpy(sbuf->p, buf->p, len);
214 sbuf->p[len] = 0;
203 ret = sbuf->p; 215 ret = sbuf->p;
204 sbuf->p += n; 216 buf->p += len;
217 sbuf->p += len + 1;
205 } 218 }
206 219
207 return ret; 220 return ret;
@@ -209,12 +222,15 @@ static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
209 222
210static inline int buf_get_data(struct cbuf *buf, void *data, int datalen) 223static inline int buf_get_data(struct cbuf *buf, void *data, int datalen)
211{ 224{
212 buf_check_size(buf, datalen); 225 int ret = 0;
213 226
214 memcpy(data, buf->p, datalen); 227 if (buf_check_size(buf, datalen)) {
215 buf->p += datalen; 228 memcpy(data, buf->p, datalen);
229 buf->p += datalen;
230 ret = datalen;
231 }
216 232
217 return datalen; 233 return ret;
218} 234}
219 235
220static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf, 236static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
@@ -223,13 +239,12 @@ static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
223 char *ret = NULL; 239 char *ret = NULL;
224 int n = 0; 240 int n = 0;
225 241
226 buf_check_size(dbuf, datalen); 242 if (buf_check_size(dbuf, datalen)) {
227 243 n = buf_get_data(buf, dbuf->p, datalen);
228 n = buf_get_data(buf, dbuf->p, datalen); 244 if (n > 0) {
229 245 ret = dbuf->p;
230 if (n > 0) { 246 dbuf->p += n;
231 ret = dbuf->p; 247 }
232 dbuf->p += n;
233 } 248 }
234 249
235 return ret; 250 return ret;
@@ -636,7 +651,7 @@ v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
636 break; 651 break;
637 case RWALK: 652 case RWALK:
638 rcall->params.rwalk.nwqid = buf_get_int16(bufp); 653 rcall->params.rwalk.nwqid = buf_get_int16(bufp);
639 rcall->params.rwalk.wqids = buf_alloc(bufp, 654 rcall->params.rwalk.wqids = buf_alloc(dbufp,
640 rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid)); 655 rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid));
641 if (rcall->params.rwalk.wqids) 656 if (rcall->params.rwalk.wqids)
642 for (i = 0; i < rcall->params.rwalk.nwqid; i++) { 657 for (i = 0; i < rcall->params.rwalk.nwqid; i++) {
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 13bdbbab4387..82303f3bf76f 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -303,7 +303,13 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
303 goto SessCleanUp; 303 goto SessCleanUp;
304 }; 304 };
305 305
306 v9ses->transport = trans_proto; 306 v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL);
307 if (!v9ses->transport) {
308 retval = -ENOMEM;
309 goto SessCleanUp;
310 }
311
312 memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport));
307 313
308 if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { 314 if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) {
309 eprintk(KERN_ERR, "problem initializing transport\n"); 315 eprintk(KERN_ERR, "problem initializing transport\n");
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 0c13fc600049..b16322db5ce6 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1063,8 +1063,8 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
1063 int ret; 1063 int ret;
1064 char *link = __getname(); 1064 char *link = __getname();
1065 1065
1066 if (strlen(link) < buflen) 1066 if (buflen > PATH_MAX)
1067 buflen = strlen(link); 1067 buflen = PATH_MAX;
1068 1068
1069 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 1069 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
1070 1070
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 868f350b2c5f..1e2b2b54d300 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -129,8 +129,8 @@ static struct super_block *v9fs_get_sb(struct file_system_type
129 129
130 if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { 130 if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
131 dprintk(DEBUG_ERROR, "problem initiating session\n"); 131 dprintk(DEBUG_ERROR, "problem initiating session\n");
132 retval = newfid; 132 kfree(v9ses);
133 goto free_session; 133 return ERR_PTR(newfid);
134 } 134 }
135 135
136 sb = sget(fs_type, NULL, v9fs_set_super, v9ses); 136 sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
@@ -150,7 +150,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type
150 150
151 if (!root) { 151 if (!root) {
152 retval = -ENOMEM; 152 retval = -ENOMEM;
153 goto release_inode; 153 goto put_back_sb;
154 } 154 }
155 155
156 sb->s_root = root; 156 sb->s_root = root;
@@ -159,7 +159,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type
159 root_fid = v9fs_fid_create(root); 159 root_fid = v9fs_fid_create(root);
160 if (root_fid == NULL) { 160 if (root_fid == NULL) {
161 retval = -ENOMEM; 161 retval = -ENOMEM;
162 goto release_dentry; 162 goto put_back_sb;
163 } 163 }
164 164
165 root_fid->fidopen = 0; 165 root_fid->fidopen = 0;
@@ -182,25 +182,15 @@ static struct super_block *v9fs_get_sb(struct file_system_type
182 182
183 if (stat_result < 0) { 183 if (stat_result < 0) {
184 retval = stat_result; 184 retval = stat_result;
185 goto release_dentry; 185 goto put_back_sb;
186 } 186 }
187 187
188 return sb; 188 return sb;
189 189
190 release_dentry: 190put_back_sb:
191 dput(sb->s_root); 191 /* deactivate_super calls v9fs_kill_super which will frees the rest */
192
193 release_inode:
194 iput(inode);
195
196 put_back_sb:
197 up_write(&sb->s_umount); 192 up_write(&sb->s_umount);
198 deactivate_super(sb); 193 deactivate_super(sb);
199 v9fs_session_close(v9ses);
200
201 free_session:
202 kfree(v9ses);
203
204 return ERR_PTR(retval); 194 return ERR_PTR(retval);
205} 195}
206 196