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