1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * fs/hmdfs/comm/message_verify.c
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8 #include "message_verify.h"
9
10 #include <linux/errno.h>
11 #include <linux/limits.h>
12 #include <linux/statfs.h>
13
14 #include "connection.h"
15 #include "hmdfs.h"
16 #include "hmdfs_server.h"
17
18 size_t message_length[C_FLAG_SIZE][F_SIZE][HMDFS_MESSAGE_MIN_MAX];
19 bool need_response[F_SIZE];
20
hmdfs_message_verify_init(void)21 void hmdfs_message_verify_init(void)
22 {
23 int flag, cmd;
24
25 for (cmd = 0; cmd < F_SIZE; cmd++)
26 need_response[cmd] = true;
27 need_response[F_RELEASE] = false;
28 need_response[F_CONNECT_REKEY] = false;
29 need_response[F_DROP_PUSH] = false;
30
31 for (flag = 0; flag < C_FLAG_SIZE; flag++) {
32 for (cmd = 0; cmd < F_SIZE; cmd++) {
33 message_length[flag][cmd][HMDFS_MESSAGE_MIN_INDEX] = 1;
34 message_length[flag][cmd][HMDFS_MESSAGE_MAX_INDEX] = 0;
35 message_length[flag][cmd][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
36 MESSAGE_LEN_JUDGE_RANGE;
37 }
38 }
39
40 message_length[C_REQUEST][F_OPEN][HMDFS_MESSAGE_MIN_INDEX] =
41 sizeof(struct open_request);
42 message_length[C_REQUEST][F_OPEN][HMDFS_MESSAGE_MAX_INDEX] =
43 sizeof(struct open_request) + PATH_MAX + 1;
44 message_length[C_REQUEST][F_OPEN][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
45 MESSAGE_LEN_JUDGE_RANGE;
46 message_length[C_RESPONSE][F_OPEN][HMDFS_MESSAGE_MIN_INDEX] = 0;
47 message_length[C_RESPONSE][F_OPEN][HMDFS_MESSAGE_MAX_INDEX] =
48 sizeof(struct open_response);
49 message_length[C_RESPONSE][F_OPEN][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
50 MESSAGE_LEN_JUDGE_BIN;
51
52 message_length[C_REQUEST][F_ATOMIC_OPEN][HMDFS_MESSAGE_MIN_INDEX] =
53 sizeof(struct atomic_open_request);
54 message_length[C_REQUEST][F_ATOMIC_OPEN][HMDFS_MESSAGE_MAX_INDEX] =
55 sizeof(struct atomic_open_request) + PATH_MAX + NAME_MAX + 1;
56 message_length[C_REQUEST][F_ATOMIC_OPEN][HMDFS_MESSAGE_LEN_JUDGE_INDEX]
57 = MESSAGE_LEN_JUDGE_RANGE;
58 message_length[C_RESPONSE][F_ATOMIC_OPEN][HMDFS_MESSAGE_MIN_INDEX] = 0;
59 message_length[C_RESPONSE][F_ATOMIC_OPEN][HMDFS_MESSAGE_MAX_INDEX] =
60 sizeof(struct atomic_open_response);
61 message_length[C_RESPONSE][F_ATOMIC_OPEN][HMDFS_MESSAGE_LEN_JUDGE_INDEX]
62 = MESSAGE_LEN_JUDGE_BIN;
63
64 message_length[C_REQUEST][F_RELEASE][HMDFS_MESSAGE_MIN_INDEX] =
65 sizeof(struct release_request);
66 message_length[C_REQUEST][F_RELEASE][HMDFS_MESSAGE_MAX_INDEX] =
67 sizeof(struct release_request);
68 message_length[C_REQUEST][F_RELEASE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
69 MESSAGE_LEN_JUDGE_BIN;
70
71 message_length[C_REQUEST][F_FSYNC][HMDFS_MESSAGE_MIN_INDEX] =
72 sizeof(struct fsync_request);
73 message_length[C_REQUEST][F_FSYNC][HMDFS_MESSAGE_MAX_INDEX] =
74 sizeof(struct fsync_request);
75 message_length[C_REQUEST][F_FSYNC][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
76 MESSAGE_LEN_JUDGE_BIN;
77 message_length[C_RESPONSE][F_FSYNC][HMDFS_MESSAGE_MIN_INDEX] = 0;
78 message_length[C_RESPONSE][F_FSYNC][HMDFS_MESSAGE_MAX_INDEX] = 0;
79 message_length[C_RESPONSE][F_FSYNC][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
80 MESSAGE_LEN_JUDGE_BIN;
81
82 message_length[C_REQUEST][F_READPAGE][HMDFS_MESSAGE_MIN_INDEX] =
83 sizeof(struct readpage_request);
84 message_length[C_REQUEST][F_READPAGE][HMDFS_MESSAGE_MAX_INDEX] =
85 sizeof(struct readpage_request);
86 message_length[C_REQUEST][F_READPAGE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
87 MESSAGE_LEN_JUDGE_BIN;
88 message_length[C_RESPONSE][F_READPAGE][HMDFS_MESSAGE_MIN_INDEX] = 0;
89 message_length[C_RESPONSE][F_READPAGE][HMDFS_MESSAGE_MAX_INDEX] =
90 HMDFS_PAGE_SIZE;
91 message_length[C_RESPONSE][F_READPAGE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
92 MESSAGE_LEN_JUDGE_RANGE;
93
94 message_length[C_REQUEST][F_READPAGES][HMDFS_MESSAGE_MIN_INDEX] =
95 sizeof(struct readpages_request);
96 message_length[C_REQUEST][F_READPAGES][HMDFS_MESSAGE_MAX_INDEX] =
97 sizeof(struct readpages_request);
98 message_length[C_REQUEST][F_READPAGES][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
99 MESSAGE_LEN_JUDGE_BIN;
100 message_length[C_RESPONSE][F_READPAGES][HMDFS_MESSAGE_MIN_INDEX] = 0;
101 message_length[C_RESPONSE][F_READPAGES][HMDFS_MESSAGE_MAX_INDEX] =
102 HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE;
103 message_length[C_RESPONSE][F_READPAGES][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
104 MESSAGE_LEN_JUDGE_RANGE;
105
106 message_length[C_REQUEST][F_READPAGES_OPEN][HMDFS_MESSAGE_MIN_INDEX] =
107 sizeof(struct readpages_open_request);
108 message_length[C_REQUEST][F_READPAGES_OPEN][HMDFS_MESSAGE_MAX_INDEX] =
109 sizeof(struct readpages_open_request) + PATH_MAX + 1;
110 message_length[C_REQUEST][F_READPAGES_OPEN][
111 HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_RANGE;
112 message_length[C_RESPONSE][F_READPAGES_OPEN][HMDFS_MESSAGE_MIN_INDEX] =
113 0;
114 message_length[C_RESPONSE][F_READPAGES_OPEN][HMDFS_MESSAGE_MAX_INDEX] =
115 sizeof(struct readpages_open_response) +
116 HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE;
117 message_length[C_RESPONSE][F_READPAGES_OPEN][
118 HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_RANGE;
119
120 message_length[C_REQUEST][F_WRITEPAGE][HMDFS_MESSAGE_MIN_INDEX] =
121 sizeof(struct writepage_request) + HMDFS_PAGE_SIZE;
122 message_length[C_REQUEST][F_WRITEPAGE][HMDFS_MESSAGE_MAX_INDEX] =
123 sizeof(struct writepage_request) + HMDFS_PAGE_SIZE;
124 message_length[C_REQUEST][F_WRITEPAGE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
125 MESSAGE_LEN_JUDGE_BIN;
126 message_length[C_RESPONSE][F_WRITEPAGE][HMDFS_MESSAGE_MIN_INDEX] = 0;
127 message_length[C_RESPONSE][F_WRITEPAGE][HMDFS_MESSAGE_MAX_INDEX] =
128 sizeof(struct writepage_response);
129 message_length[C_RESPONSE][F_WRITEPAGE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
130 MESSAGE_LEN_JUDGE_BIN;
131
132 message_length[C_REQUEST][F_ITERATE][HMDFS_MESSAGE_MIN_INDEX] =
133 sizeof(struct readdir_request);
134 message_length[C_REQUEST][F_ITERATE][HMDFS_MESSAGE_MAX_INDEX] =
135 sizeof(struct readdir_request) + PATH_MAX + 1;
136 message_length[C_REQUEST][F_ITERATE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
137 MESSAGE_LEN_JUDGE_RANGE;
138 message_length[C_RESPONSE][F_ITERATE][HMDFS_MESSAGE_MIN_INDEX] = 0;
139 message_length[C_RESPONSE][F_ITERATE][HMDFS_MESSAGE_MAX_INDEX] =
140 sizeof(__le64) + HMDFS_MAX_MESSAGE_LEN;
141 message_length[C_RESPONSE][F_ITERATE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
142 MESSAGE_LEN_JUDGE_RANGE;
143
144 message_length[C_REQUEST][F_MKDIR][HMDFS_MESSAGE_MIN_INDEX] =
145 sizeof(struct mkdir_request);
146 message_length[C_REQUEST][F_MKDIR][HMDFS_MESSAGE_MAX_INDEX] =
147 sizeof(struct mkdir_request) + PATH_MAX + NAME_MAX + 2;
148 message_length[C_REQUEST][F_MKDIR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
149 MESSAGE_LEN_JUDGE_RANGE;
150 message_length[C_RESPONSE][F_MKDIR][HMDFS_MESSAGE_MIN_INDEX] =
151 sizeof(struct hmdfs_inodeinfo_response);
152 message_length[C_RESPONSE][F_MKDIR][HMDFS_MESSAGE_MAX_INDEX] =
153 sizeof(struct hmdfs_inodeinfo_response);
154 message_length[C_RESPONSE][F_MKDIR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
155 MESSAGE_LEN_JUDGE_BIN;
156
157 message_length[C_REQUEST][F_CREATE][HMDFS_MESSAGE_MIN_INDEX] =
158 sizeof(struct create_request);
159 message_length[C_REQUEST][F_CREATE][HMDFS_MESSAGE_MAX_INDEX] =
160 sizeof(struct create_request) + PATH_MAX + NAME_MAX + 2;
161 message_length[C_REQUEST][F_CREATE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
162 MESSAGE_LEN_JUDGE_RANGE;
163 message_length[C_RESPONSE][F_CREATE][HMDFS_MESSAGE_MIN_INDEX] =
164 sizeof(struct hmdfs_inodeinfo_response);
165 message_length[C_RESPONSE][F_CREATE][HMDFS_MESSAGE_MAX_INDEX] =
166 sizeof(struct hmdfs_inodeinfo_response);
167 message_length[C_RESPONSE][F_CREATE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
168 MESSAGE_LEN_JUDGE_BIN;
169
170 message_length[C_REQUEST][F_RMDIR][HMDFS_MESSAGE_MIN_INDEX] =
171 sizeof(struct rmdir_request);
172 message_length[C_REQUEST][F_RMDIR][HMDFS_MESSAGE_MAX_INDEX] =
173 sizeof(struct rmdir_request) + PATH_MAX + NAME_MAX + 2;
174 message_length[C_REQUEST][F_RMDIR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
175 MESSAGE_LEN_JUDGE_RANGE;
176 message_length[C_RESPONSE][F_RMDIR][HMDFS_MESSAGE_MIN_INDEX] = 0;
177 message_length[C_RESPONSE][F_RMDIR][HMDFS_MESSAGE_MAX_INDEX] = 0;
178 message_length[C_RESPONSE][F_RMDIR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
179 MESSAGE_LEN_JUDGE_BIN;
180
181 message_length[C_REQUEST][F_UNLINK][HMDFS_MESSAGE_MIN_INDEX] =
182 sizeof(struct unlink_request);
183 message_length[C_REQUEST][F_UNLINK][HMDFS_MESSAGE_MAX_INDEX] =
184 sizeof(struct unlink_request) + PATH_MAX + NAME_MAX + 2;
185 message_length[C_REQUEST][F_UNLINK][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
186 MESSAGE_LEN_JUDGE_RANGE;
187 message_length[C_RESPONSE][F_UNLINK][HMDFS_MESSAGE_MIN_INDEX] = 0;
188 message_length[C_RESPONSE][F_UNLINK][HMDFS_MESSAGE_MAX_INDEX] = 0;
189 message_length[C_RESPONSE][F_UNLINK][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
190 MESSAGE_LEN_JUDGE_BIN;
191
192 message_length[C_REQUEST][F_RENAME][HMDFS_MESSAGE_MIN_INDEX] =
193 sizeof(struct rename_request);
194 message_length[C_REQUEST][F_RENAME][HMDFS_MESSAGE_MAX_INDEX] =
195 sizeof(struct rename_request) + 4 + 4 * PATH_MAX;
196 message_length[C_REQUEST][F_RENAME][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
197 MESSAGE_LEN_JUDGE_RANGE;
198 message_length[C_RESPONSE][F_RENAME][HMDFS_MESSAGE_MIN_INDEX] = 0;
199 message_length[C_RESPONSE][F_RENAME][HMDFS_MESSAGE_MAX_INDEX] = 0;
200 message_length[C_RESPONSE][F_RENAME][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
201 MESSAGE_LEN_JUDGE_BIN;
202
203 message_length[C_REQUEST][F_SETATTR][HMDFS_MESSAGE_MIN_INDEX] =
204 sizeof(struct setattr_request);
205 message_length[C_REQUEST][F_SETATTR][HMDFS_MESSAGE_MAX_INDEX] =
206 sizeof(struct setattr_request) + PATH_MAX + 1;
207 message_length[C_REQUEST][F_SETATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
208 MESSAGE_LEN_JUDGE_RANGE;
209 message_length[C_RESPONSE][F_SETATTR][HMDFS_MESSAGE_MIN_INDEX] = 0;
210 message_length[C_RESPONSE][F_SETATTR][HMDFS_MESSAGE_MAX_INDEX] = 0;
211 message_length[C_RESPONSE][F_SETATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
212 MESSAGE_LEN_JUDGE_BIN;
213
214 message_length[C_REQUEST][F_GETATTR][HMDFS_MESSAGE_MIN_INDEX] =
215 sizeof(struct getattr_request);
216 message_length[C_REQUEST][F_GETATTR][HMDFS_MESSAGE_MAX_INDEX] =
217 sizeof(struct getattr_request) + PATH_MAX + 1;
218 message_length[C_REQUEST][F_GETATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
219 MESSAGE_LEN_JUDGE_RANGE;
220 message_length[C_RESPONSE][F_GETATTR][HMDFS_MESSAGE_MIN_INDEX] = 0;
221 message_length[C_RESPONSE][F_GETATTR][HMDFS_MESSAGE_MAX_INDEX] =
222 sizeof(struct getattr_response);
223 message_length[C_RESPONSE][F_GETATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
224 MESSAGE_LEN_JUDGE_BIN;
225
226 message_length[C_REQUEST][F_STATFS][HMDFS_MESSAGE_MIN_INDEX] =
227 sizeof(struct statfs_request);
228 message_length[C_REQUEST][F_STATFS][HMDFS_MESSAGE_MAX_INDEX] =
229 sizeof(struct statfs_request) + PATH_MAX + 1;
230 message_length[C_REQUEST][F_STATFS][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
231 MESSAGE_LEN_JUDGE_RANGE;
232 message_length[C_RESPONSE][F_STATFS][HMDFS_MESSAGE_MIN_INDEX] = 0;
233 message_length[C_RESPONSE][F_STATFS][HMDFS_MESSAGE_MAX_INDEX] =
234 sizeof(struct statfs_response);
235 message_length[C_RESPONSE][F_STATFS][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
236 MESSAGE_LEN_JUDGE_BIN;
237
238 message_length[C_REQUEST][F_SYNCFS][HMDFS_MESSAGE_MIN_INDEX] =
239 sizeof(struct syncfs_request);
240 message_length[C_REQUEST][F_SYNCFS][HMDFS_MESSAGE_MAX_INDEX] =
241 sizeof(struct syncfs_request);
242 message_length[C_REQUEST][F_SYNCFS][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
243 MESSAGE_LEN_JUDGE_BIN;
244 message_length[C_RESPONSE][F_SYNCFS][HMDFS_MESSAGE_MIN_INDEX] = 0;
245 message_length[C_RESPONSE][F_SYNCFS][HMDFS_MESSAGE_MAX_INDEX] = 0;
246 message_length[C_RESPONSE][F_SYNCFS][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
247 MESSAGE_LEN_JUDGE_BIN;
248
249 message_length[C_REQUEST][F_GETXATTR][HMDFS_MESSAGE_MIN_INDEX] =
250 sizeof(struct getxattr_request);
251 message_length[C_REQUEST][F_GETXATTR][HMDFS_MESSAGE_MAX_INDEX] =
252 sizeof(struct getxattr_request) + PATH_MAX + XATTR_NAME_MAX + 2;
253 message_length[C_REQUEST][F_GETXATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
254 MESSAGE_LEN_JUDGE_RANGE;
255 message_length[C_RESPONSE][F_GETXATTR][HMDFS_MESSAGE_MIN_INDEX] = 0;
256 message_length[C_RESPONSE][F_GETXATTR][HMDFS_MESSAGE_MAX_INDEX] =
257 sizeof(struct getxattr_response) + HMDFS_XATTR_SIZE_MAX;
258 message_length[C_RESPONSE][F_GETXATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
259 MESSAGE_LEN_JUDGE_RANGE;
260
261 message_length[C_REQUEST][F_SETXATTR][HMDFS_MESSAGE_MIN_INDEX] =
262 sizeof(struct setxattr_request);
263 message_length[C_REQUEST][F_SETXATTR][HMDFS_MESSAGE_MAX_INDEX] =
264 sizeof(struct setxattr_request) + PATH_MAX + XATTR_NAME_MAX +
265 HMDFS_XATTR_SIZE_MAX + 2;
266 message_length[C_REQUEST][F_SETXATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
267 MESSAGE_LEN_JUDGE_RANGE;
268 message_length[C_RESPONSE][F_SETXATTR][HMDFS_MESSAGE_MIN_INDEX] = 0;
269 message_length[C_RESPONSE][F_SETXATTR][HMDFS_MESSAGE_MAX_INDEX] = 0;
270 message_length[C_RESPONSE][F_SETXATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
271 MESSAGE_LEN_JUDGE_BIN;
272
273 message_length[C_REQUEST][F_LISTXATTR][HMDFS_MESSAGE_MIN_INDEX] =
274 sizeof(struct listxattr_request);
275 message_length[C_REQUEST][F_LISTXATTR][HMDFS_MESSAGE_MAX_INDEX] =
276 sizeof(struct listxattr_request) + PATH_MAX + 1;
277 message_length[C_REQUEST][F_LISTXATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
278 MESSAGE_LEN_JUDGE_RANGE;
279 message_length[C_RESPONSE][F_LISTXATTR][HMDFS_MESSAGE_MIN_INDEX] = 0;
280 message_length[C_RESPONSE][F_LISTXATTR][HMDFS_MESSAGE_MAX_INDEX] =
281 sizeof(struct listxattr_response) + HMDFS_LISTXATTR_SIZE_MAX;
282 message_length[C_RESPONSE][F_LISTXATTR][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
283 MESSAGE_LEN_JUDGE_RANGE;
284
285 message_length[C_REQUEST][F_CONNECT_REKEY][HMDFS_MESSAGE_MIN_INDEX] =
286 sizeof(struct connection_rekey_request);
287 message_length[C_REQUEST][F_CONNECT_REKEY][HMDFS_MESSAGE_MAX_INDEX] =
288 sizeof(struct connection_rekey_request);
289 message_length[C_REQUEST][F_CONNECT_REKEY]
290 [HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_BIN;
291
292 message_length[C_REQUEST][F_DROP_PUSH][HMDFS_MESSAGE_MIN_INDEX] =
293 sizeof(struct drop_push_request);
294 message_length[C_REQUEST][F_DROP_PUSH][HMDFS_MESSAGE_MAX_INDEX] =
295 sizeof(struct drop_push_request) + PATH_MAX + 1;
296 message_length[C_REQUEST][F_DROP_PUSH][HMDFS_MESSAGE_LEN_JUDGE_INDEX] =
297 MESSAGE_LEN_JUDGE_RANGE;
298 }
299
find_first_no_slash(const char ** name,int * len)300 static void find_first_no_slash(const char **name, int *len)
301 {
302 const char *s = *name;
303 int l = *len;
304
305 while (*s == '/' && l > 0) {
306 s++;
307 l--;
308 }
309
310 *name = s;
311 *len = l;
312 }
313
find_first_slash(const char ** name,int * len)314 static void find_first_slash(const char **name, int *len)
315 {
316 const char *s = *name;
317 int l = *len;
318
319 while (*s != '/' && l > 0) {
320 s++;
321 l--;
322 }
323
324 *name = s;
325 *len = l;
326 }
327
path_contain_dotdot(const char * name,int len)328 static bool path_contain_dotdot(const char *name, int len)
329 {
330 while (true) {
331 find_first_no_slash(&name, &len);
332
333 if (len == 0)
334 return false;
335
336 if (len >= 2 && name[0] == '.' && name[1] == '.' &&
337 (len == 2 || name[2] == '/'))
338 return true;
339
340 find_first_slash(&name, &len);
341 }
342 }
343
hmdfs_open_message_verify(int flag,size_t len,void * data)344 static int hmdfs_open_message_verify(int flag, size_t len, void *data)
345 {
346 struct open_request *req = NULL;
347 size_t tmp_len = 0;
348 int path_len;
349
350 if (flag != C_REQUEST || !data)
351 return 0;
352
353 req = data;
354 path_len = le32_to_cpu(req->path_len);
355 tmp_len = strnlen(req->buf, PATH_MAX);
356 if (tmp_len == PATH_MAX ||
357 tmp_len != len - sizeof(struct open_request) - 1 ||
358 path_len != tmp_len) {
359 hmdfs_err("verify fail");
360 return -EINVAL;
361 }
362
363 /*
364 * We only allow server to open file in hmdfs, thus we need to
365 * make sure path don't contain "..".
366 */
367 if (path_contain_dotdot(req->buf, path_len)) {
368 hmdfs_err("verify fail, path contain dotdot");
369 return -EINVAL;
370 }
371
372 return 0;
373 }
374
hmdfs_atomic_open_verify(int flag,size_t len,void * data)375 static int hmdfs_atomic_open_verify(int flag, size_t len, void *data)
376 {
377 struct atomic_open_request *req = NULL;
378 size_t total_len;
379 size_t path_len;
380 size_t max_path_size;
381 size_t file_len;
382 size_t max_file_size;
383
384 if (flag != C_REQUEST || !data)
385 return 0;
386
387 req = data;
388 total_len = len - sizeof(*req);
389 max_path_size = min_t(size_t, PATH_MAX, total_len);
390 path_len = strnlen(req->buf, max_path_size);
391 /* file name need 2 byte at least */
392 if (path_len == max_path_size || path_len + 3 > total_len) {
393 hmdfs_err("verify fail, len %zu, path_len %zu", len, path_len);
394 return -EINVAL;
395 }
396
397 max_file_size = min_t(size_t, NAME_MAX + 1, total_len - path_len - 1);
398 file_len = strnlen(req->buf + path_len + 1, max_file_size);
399
400 if (file_len == max_file_size ||
401 total_len != path_len + 1 + file_len + 1 ||
402 le32_to_cpu(req->path_len) != path_len ||
403 le32_to_cpu(req->file_len) != file_len) {
404 hmdfs_err("verify fail total len %zu path_len %zu, decalared path len %u, file_len %zu, decalared file_len %u",
405 total_len, path_len, le32_to_cpu(req->path_len),
406 file_len, le32_to_cpu(req->file_len) != file_len);
407 return -EINVAL;
408 }
409
410 return 0;
411 }
412
hmdfs_iterate_verify(int flag,size_t len,void * data)413 static int hmdfs_iterate_verify(int flag, size_t len, void *data)
414 {
415 int err = 0;
416 struct readdir_request *tmp_request = NULL;
417 char *tmp_char = NULL;
418 size_t tmp_len = 0;
419
420 if (flag == C_REQUEST) {
421 if (data) {
422 tmp_request = data;
423 tmp_char = tmp_request->path;
424 tmp_len = strnlen(tmp_char, PATH_MAX);
425 } else {
426 return err;
427 }
428
429 if (le32_to_cpu(tmp_request->path_len) != tmp_len ||
430 len - sizeof(struct readdir_request) - 1 != tmp_len) {
431 err = -EINVAL;
432 hmdfs_err("verify fail");
433 return err;
434 }
435 }
436
437 return err;
438 }
439
hmdfs_mkdir_verify(int flag,size_t len,void * data)440 static int hmdfs_mkdir_verify(int flag, size_t len, void *data)
441 {
442 int err = 0;
443 struct mkdir_request *tmp_request = NULL;
444 char *tmp_char = NULL;
445 size_t tmp_path_len = 0;
446 size_t tmp_name_len = 0;
447 size_t tmp_char_path_len = 0;
448 size_t tmp_char_name_len = 0;
449
450 if (flag == C_REQUEST) {
451 if (data) {
452 tmp_request = data;
453 tmp_char = tmp_request->path;
454 tmp_path_len = le32_to_cpu(tmp_request->path_len);
455 tmp_name_len = le32_to_cpu(tmp_request->name_len);
456 tmp_char_path_len = strnlen(tmp_char, PATH_MAX);
457 tmp_char_name_len = strnlen(
458 tmp_char + tmp_char_path_len + 1, NAME_MAX);
459 } else {
460 return err;
461 }
462
463 if (tmp_path_len != tmp_char_path_len ||
464 tmp_name_len != tmp_char_name_len ||
465 len - sizeof(struct mkdir_request) !=
466 tmp_path_len + 1 + tmp_name_len + 1) {
467 err = -EINVAL;
468 hmdfs_err("verify fail");
469 return err;
470 }
471 }
472 return err;
473 }
474
hmdfs_create_verify(int flag,size_t len,void * data)475 static int hmdfs_create_verify(int flag, size_t len, void *data)
476 {
477 int err = 0;
478 struct create_request *tmp_request = NULL;
479 char *tmp_char = NULL;
480 size_t tmp_path_len = 0;
481 size_t tmp_name_len = 0;
482 size_t tmp_char_path_len = 0;
483 size_t tmp_char_name_len = 0;
484
485 if (flag == C_REQUEST) {
486 if (data) {
487 tmp_request = data;
488 tmp_char = tmp_request->path;
489 tmp_path_len = le32_to_cpu(tmp_request->path_len);
490 tmp_name_len = le32_to_cpu(tmp_request->name_len);
491 tmp_char_path_len = strnlen(tmp_char, PATH_MAX);
492 tmp_char_name_len = strnlen(
493 tmp_char + tmp_char_path_len + 1, NAME_MAX);
494 } else {
495 return err;
496 }
497
498 if (tmp_path_len != tmp_char_path_len ||
499 tmp_name_len != tmp_char_name_len ||
500 len - sizeof(struct create_request) !=
501 tmp_path_len + 1 + tmp_name_len + 1) {
502 err = -EINVAL;
503 hmdfs_err("verify fail");
504 return err;
505 }
506 }
507 return err;
508 }
509
hmdfs_rmdir_verify(int flag,size_t len,void * data)510 static int hmdfs_rmdir_verify(int flag, size_t len, void *data)
511 {
512 int err = 0;
513 struct rmdir_request *tmp_request = NULL;
514 char *tmp_char = NULL;
515 size_t tmp_path_len = 0;
516 size_t tmp_name_len = 0;
517 size_t tmp_char_path_len = 0;
518 size_t tmp_char_name_len = 0;
519
520 if (flag == C_REQUEST) {
521 if (data) {
522 tmp_request = data;
523 tmp_char = tmp_request->path;
524 tmp_path_len = le32_to_cpu(tmp_request->path_len);
525 tmp_name_len = le32_to_cpu(tmp_request->name_len);
526 tmp_char_path_len = strnlen(tmp_char, PATH_MAX);
527 tmp_char_name_len = strnlen(
528 tmp_char + tmp_char_path_len + 1, NAME_MAX);
529 } else {
530 return err;
531 }
532
533 if (tmp_path_len != tmp_char_path_len ||
534 tmp_name_len != tmp_char_name_len ||
535 len - sizeof(struct rmdir_request) !=
536 tmp_path_len + 1 + tmp_name_len + 1) {
537 err = -EINVAL;
538 hmdfs_err("verify fail");
539 return err;
540 }
541 }
542
543 return err;
544 }
545
hmdfs_unlink_verify(int flag,size_t len,void * data)546 static int hmdfs_unlink_verify(int flag, size_t len, void *data)
547 {
548 int err = 0;
549 struct unlink_request *tmp_request = NULL;
550 char *tmp_char = NULL;
551 size_t tmp_path_len = 0;
552 size_t tmp_name_len = 0;
553 size_t tmp_char_path_len = 0;
554 size_t tmp_char_name_len = 0;
555
556 if (flag == C_REQUEST) {
557 if (data) {
558 tmp_request = data;
559 tmp_char = tmp_request->path;
560 tmp_path_len = le32_to_cpu(tmp_request->path_len);
561 tmp_name_len = le32_to_cpu(tmp_request->name_len);
562 tmp_char_path_len = strnlen(tmp_char, PATH_MAX);
563 tmp_char_name_len = strnlen(
564 tmp_char + tmp_char_path_len + 1, NAME_MAX);
565 } else {
566 return err;
567 }
568
569 if (tmp_path_len != tmp_char_path_len ||
570 tmp_name_len != tmp_char_name_len ||
571 len - sizeof(struct unlink_request) !=
572 tmp_path_len + 1 + tmp_name_len + 1) {
573 err = -EINVAL;
574 hmdfs_err("verify fail");
575 return err;
576 }
577 }
578
579 return err;
580 }
581
hmdfs_rename_verify(int flag,size_t len,void * data)582 static int hmdfs_rename_verify(int flag, size_t len, void *data)
583 {
584 int err = 0;
585 struct rename_request *tmp_request = NULL;
586 char *tmp_char = NULL;
587 size_t tmp_old_path_len = 0;
588 size_t tmp_new_path_len = 0;
589 size_t tmp_old_name_len = 0;
590 size_t tmp_new_name_len = 0;
591 size_t tmp_char_old_path_len = 0;
592 size_t tmp_char_new_path_len = 0;
593 size_t tmp_char_old_name_len = 0;
594 size_t tmp_char_new_name_len = 0;
595
596 if (flag == C_REQUEST) {
597 if (data) {
598 tmp_request = data;
599 tmp_char = tmp_request->path;
600
601 tmp_old_path_len =
602 le32_to_cpu(tmp_request->old_path_len);
603 tmp_new_path_len =
604 le32_to_cpu(tmp_request->new_path_len);
605 tmp_old_name_len =
606 le32_to_cpu(tmp_request->old_name_len);
607 tmp_new_name_len =
608 le32_to_cpu(tmp_request->new_name_len);
609
610 tmp_char_old_path_len = strnlen(tmp_char, PATH_MAX);
611 tmp_char_new_path_len = strnlen(
612 tmp_char + tmp_char_old_path_len + 1, PATH_MAX);
613
614 tmp_char_old_name_len =
615 strnlen(tmp_char + tmp_char_old_path_len + 1 +
616 tmp_char_new_path_len + 1,
617 PATH_MAX);
618 tmp_char_new_name_len =
619 strnlen(tmp_char + tmp_char_old_path_len + 1 +
620 tmp_char_new_path_len + 1 +
621 tmp_char_old_name_len + 1,
622 PATH_MAX);
623 } else {
624 return err;
625 }
626
627 if (tmp_new_name_len != tmp_char_new_name_len ||
628 tmp_old_name_len != tmp_char_old_name_len ||
629 tmp_new_path_len != tmp_char_new_path_len ||
630 tmp_old_path_len != tmp_char_old_path_len ||
631 len - sizeof(struct rename_request) !=
632 tmp_new_name_len + 1 + tmp_old_name_len + 1 +
633 tmp_new_path_len + 1 + tmp_old_path_len +
634 1) {
635 err = -EINVAL;
636 hmdfs_err("verify fail");
637 return err;
638 }
639 }
640
641 return err;
642 }
643
hmdfs_setattr_verify(int flag,size_t len,void * data)644 static int hmdfs_setattr_verify(int flag, size_t len, void *data)
645 {
646 int err = 0;
647 struct setattr_request *tmp_request = NULL;
648 char *tmp_char = NULL;
649 size_t tmp_len = 0;
650
651 if (flag == C_REQUEST) {
652 if (data) {
653 tmp_request = data;
654 tmp_char = tmp_request->buf;
655 tmp_len = strnlen(tmp_char, PATH_MAX);
656 } else {
657 return err;
658 }
659
660 if (tmp_len != len - sizeof(struct setattr_request) - 1 ||
661 le32_to_cpu(tmp_request->path_len) != tmp_len) {
662 err = -EINVAL;
663 hmdfs_err("verify fail");
664 return err;
665 }
666 }
667
668 return err;
669 }
670
hmdfs_getattr_verify(int flag,size_t len,void * data)671 static int hmdfs_getattr_verify(int flag, size_t len, void *data)
672 {
673 struct getattr_request *req = NULL;
674 size_t tmp_len;
675
676 if (flag != C_REQUEST || !data)
677 return 0;
678
679 req = data;
680 tmp_len = strnlen(req->buf, PATH_MAX);
681 if (tmp_len != len - sizeof(struct getattr_request) - 1 ||
682 le32_to_cpu(req->path_len) != tmp_len) {
683 hmdfs_err("verify fail");
684 return -EINVAL;
685 }
686
687 return 0;
688 }
689
hmdfs_getxattr_verify(int flag,size_t len,void * data)690 static int hmdfs_getxattr_verify(int flag, size_t len, void *data)
691 {
692 struct getxattr_request *req = NULL;
693 struct getxattr_response *resp = NULL;
694 size_t path_len = 0;
695 size_t name_len = 0;
696 size_t size = 0;
697
698 if (!data)
699 return 0;
700
701 if (flag == C_REQUEST) {
702 req = data;
703 path_len = le32_to_cpu(req->path_len);
704 name_len = le32_to_cpu(req->name_len);
705 size = le32_to_cpu(req->size);
706 if (path_len >= PATH_MAX ||
707 path_len != strnlen(req->buf, PATH_MAX) ||
708 name_len !=
709 strnlen(req->buf + path_len + 1, XATTR_NAME_MAX) ||
710 size > HMDFS_XATTR_SIZE_MAX)
711 return -EINVAL;
712 } else {
713 resp = data;
714 size = le32_to_cpu(resp->size);
715 if (len != sizeof(struct getxattr_response) &&
716 len < sizeof(struct getxattr_response) + size)
717 return -EINVAL;
718 }
719
720 return 0;
721 }
722
hmdfs_setxattr_verify(int flag,size_t len,void * data)723 static int hmdfs_setxattr_verify(int flag, size_t len, void *data)
724 {
725 struct setxattr_request *req = NULL;
726 size_t path_len = 0;
727 size_t name_len = 0;
728 size_t size = 0;
729
730 /* No need to verify response */
731 if (flag != C_REQUEST || !data)
732 return 0;
733
734 req = data;
735 path_len = le32_to_cpu(req->path_len);
736 name_len = le32_to_cpu(req->name_len);
737 size = le32_to_cpu(req->size);
738 if (path_len >= PATH_MAX || path_len != strnlen(req->buf, PATH_MAX) ||
739 name_len != strnlen(req->buf + path_len + 1, XATTR_NAME_MAX) ||
740 len != path_len + name_len + size + 2 +
741 sizeof(struct setxattr_request) ||
742 size > HMDFS_XATTR_SIZE_MAX)
743 return -EINVAL;
744
745 return 0;
746 }
747
hmdfs_listxattr_verify(int flag,size_t len,void * data)748 static int hmdfs_listxattr_verify(int flag, size_t len, void *data)
749 {
750 struct listxattr_request *req = NULL;
751 struct listxattr_response *resp = NULL;
752 size_t path_len = 0;
753 size_t size = 0;
754
755 if (!data)
756 return 0;
757
758 if (flag == C_REQUEST) {
759 req = data;
760 path_len = le32_to_cpu(req->path_len);
761 size = le32_to_cpu(req->size);
762 if (path_len >= PATH_MAX ||
763 path_len != strnlen(req->buf, PATH_MAX) ||
764 size > HMDFS_LISTXATTR_SIZE_MAX)
765 return -EINVAL;
766 } else {
767 resp = data;
768 size = le32_to_cpu(resp->size);
769 if (len != sizeof(struct listxattr_response) &&
770 len < sizeof(struct listxattr_response) + size)
771 return -EINVAL;
772 }
773
774 return 0;
775 }
776
hmdfs_writepage_verify(int flag,size_t len,void * data)777 static int hmdfs_writepage_verify(int flag, size_t len, void *data)
778 {
779 struct writepage_request *req = NULL;
780 __u32 count;
781
782 if (flag != C_REQUEST || !data)
783 return 0;
784
785 req = data;
786 count = le32_to_cpu(req->count);
787 if (count == 0 || count > HMDFS_PAGE_SIZE ||
788 len - sizeof(struct writepage_request) != HMDFS_PAGE_SIZE) {
789 hmdfs_err("verify fail, count is %d", count);
790 return -EINVAL;
791 }
792
793 return 0;
794 }
795
hmdfs_statfs_verify(int flag,size_t len,void * data)796 static int hmdfs_statfs_verify(int flag, size_t len, void *data)
797 {
798 int err = 0;
799 struct statfs_request *tmp_request = NULL;
800 char *tmp_char = NULL;
801 size_t tmp_len = 0;
802
803 if (flag == C_REQUEST) {
804 if (data) {
805 tmp_request = data;
806 tmp_char = tmp_request->path;
807 tmp_len = strnlen(tmp_char, PATH_MAX);
808 } else {
809 return err;
810 }
811
812 if (le32_to_cpu(tmp_request->path_len) != tmp_len ||
813 tmp_len != len - sizeof(struct statfs_request) - 1) {
814 err = -EINVAL;
815 hmdfs_err("verify fail");
816 return err;
817 }
818 }
819
820 return err;
821 }
822
hmdfs_readpages_verify(int flag,size_t len,void * data)823 static int hmdfs_readpages_verify(int flag, size_t len, void *data)
824 {
825 struct readpages_request *req = NULL;
826 unsigned int size;
827
828 if (flag != C_REQUEST || !data)
829 return 0;
830
831 req = data;
832 size = le32_to_cpu(req->size);
833 if (size > HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE) {
834 hmdfs_err("verify fail, invalid req->size %u", size);
835 return -EINVAL;
836 }
837
838 return 0;
839 }
840
hmdfs_readpages_open_verify(int flag,size_t len,void * data)841 static int hmdfs_readpages_open_verify(int flag, size_t len, void *data)
842 {
843 struct readpages_open_request *req = NULL;
844 unsigned int size;
845 size_t tmp_len;
846
847 if (flag != C_REQUEST || !data)
848 return 0;
849
850 req = data;
851 size = le32_to_cpu(req->size);
852 tmp_len = strnlen(req->buf, PATH_MAX);
853 if (tmp_len + 1 != len - sizeof(*req) ||
854 le32_to_cpu(req->path_len) != tmp_len ||
855 size > HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE) {
856 hmdfs_err("verify fail, req->size %u", size);
857 return -EINVAL;
858 }
859
860 return 0;
861 }
862
863 typedef int (*hmdfs_message_verify_func)(int, size_t, void *);
864
865 static const hmdfs_message_verify_func message_verify[F_SIZE] = {
866 [F_OPEN] = hmdfs_open_message_verify,
867 [F_WRITEPAGE] = hmdfs_writepage_verify,
868 [F_ITERATE] = hmdfs_iterate_verify,
869 [F_MKDIR] = hmdfs_mkdir_verify,
870 [F_CREATE] = hmdfs_create_verify,
871 [F_RMDIR] = hmdfs_rmdir_verify,
872 [F_UNLINK] = hmdfs_unlink_verify,
873 [F_RENAME] = hmdfs_rename_verify,
874 [F_SETATTR] = hmdfs_setattr_verify,
875 [F_STATFS] = hmdfs_statfs_verify,
876 [F_GETATTR] = hmdfs_getattr_verify,
877 [F_GETXATTR] = hmdfs_getxattr_verify,
878 [F_SETXATTR] = hmdfs_setxattr_verify,
879 [F_LISTXATTR] = hmdfs_listxattr_verify,
880 [F_READPAGES] = hmdfs_readpages_verify,
881 [F_READPAGES_OPEN] = hmdfs_readpages_open_verify,
882 [F_ATOMIC_OPEN] = hmdfs_atomic_open_verify,
883 };
884
handle_bad_message(struct hmdfs_peer * con,struct hmdfs_head_cmd * head,int * err)885 static void handle_bad_message(struct hmdfs_peer *con,
886 struct hmdfs_head_cmd *head, int *err)
887 {
888 /*
889 * Bad message won't be awared by upper layer, so ETIME is
890 * always given to upper layer. It is prefer to pass EOPNOTSUPP
891 * to upper layer when bad message (eg. caused by wrong len)
892 * received.
893 */
894 if (head->operations.cmd_flag == C_RESPONSE) {
895 /*
896 * Change msg ret code. To let upper layer handle
897 * EOPNOTSUPP, hmdfs_message_verify() should return
898 * 0, so err code is modified either.
899 */
900 head->ret_code = cpu_to_le32(-EOPNOTSUPP);
901 *err = 0;
902 } else {
903 if (head->operations.command >= F_SIZE)
904 return;
905 /*
906 * Some request messages do not need to be responded.
907 * Even if a response is returned, the response msg
908 * is automatically ignored in hmdfs_response_recv().
909 * Therefore, it is normal to directly return a response.
910 */
911 if (need_response[head->operations.command])
912 hmdfs_send_err_response(con, head, -EOPNOTSUPP);
913 }
914 }
915
hmdfs_message_verify(struct hmdfs_peer * con,struct hmdfs_head_cmd * head,void * data)916 int hmdfs_message_verify(struct hmdfs_peer *con, struct hmdfs_head_cmd *head,
917 void *data)
918 {
919 int err = 0;
920 int flag, cmd, len_type;
921 size_t len, min, max;
922
923 if (!head)
924 return -EINVAL;
925
926 flag = head->operations.cmd_flag;
927 if (flag != C_REQUEST && flag != C_RESPONSE)
928 return -EINVAL;
929
930 cmd = head->operations.command;
931 if (cmd >= F_SIZE || cmd < F_OPEN || cmd == F_RESERVED_0 ||
932 (cmd >= F_RESERVED_1 && cmd <= F_RESERVED_4) || cmd == F_RESERVED_5) {
933 err = -EINVAL;
934 goto handle_bad_msg;
935 }
936
937 if (head->version != DFS_2_0) {
938 err = -EINVAL;
939 } else {
940 len = le32_to_cpu(head->data_len) -
941 sizeof(struct hmdfs_head_cmd);
942 min = message_length[flag][cmd][HMDFS_MESSAGE_MIN_INDEX];
943 if (head->operations.command == F_ITERATE && flag == C_RESPONSE)
944 max = sizeof(struct slice_descriptor) + PAGE_SIZE;
945 else
946 max = message_length[flag][cmd][HMDFS_MESSAGE_MAX_INDEX];
947 len_type =
948 message_length[flag][cmd][HMDFS_MESSAGE_LEN_JUDGE_INDEX];
949
950 if (len_type == MESSAGE_LEN_JUDGE_RANGE) {
951 if (len < min || len > max) {
952 hmdfs_err(
953 "cmd %d -> %d message verify fail, len = %zu",
954 cmd, flag, len);
955 err = -EINVAL;
956 goto handle_bad_msg;
957 }
958 } else {
959 if (len != min && len != max) {
960 hmdfs_err(
961 "cmd %d -> %d message verify fail, len = %zu",
962 cmd, flag, len);
963 err = -EINVAL;
964 goto handle_bad_msg;
965 }
966 }
967
968 if (message_verify[cmd])
969 err = message_verify[cmd](flag, len, data);
970
971 if (err)
972 goto handle_bad_msg;
973
974 return err;
975 }
976
977 handle_bad_msg:
978 handle_bad_message(con, head, &err);
979 return err;
980 }
981