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 (resp->size != sizeof(*resp->value))
659 return -EINVAL;
660
661 if (msg_len < sizeof(*resp))
662 return -EINVAL;
663
664 if (resp->size > XATTR_SIZE_MAX)
665 return -EINVAL;
666
667 return 0;
668 }
669
hmdfs_getxattr_verify(int flag, size_t msg_len, void *msg)670 static int hmdfs_getxattr_verify(int flag, size_t msg_len, void *msg)
671 {
672 if (!msg || !msg_len)
673 return 0;
674
675 if (flag == C_REQUEST)
676 return verify_getxattr_req(msg_len, msg);
677 else
678 return verify_getxattr_resp(msg_len, msg);
679 }
680
verify_setxattr_req(size_t msg_len, void *msg)681 static int verify_setxattr_req(size_t msg_len, void *msg)
682 {
683 struct setxattr_request *req = msg;
684 int str_len[] = { req->path_len, req->name_len};
685
686 if (req->path_len < 0 || req->path_len >= PATH_MAX ||
687 req->name_len < 0 || req->name_len >= PATH_MAX)
688 return -EINVAL;
689
690 if (msg_len != sizeof(*req) + req->path_len + 1 + req->name_len + 1 +
691 req->size)
692 return -EINVAL;
693
694 if (req->name_len > XATTR_NAME_MAX || req->size < 0 ||
695 req->size > XATTR_SIZE_MAX)
696 return -EINVAL;
697
698 if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int)))
699 return -EINVAL;
700
701 return 0;
702 }
703
hmdfs_setxattr_verify(int flag, size_t msg_len, void *msg)704 static int hmdfs_setxattr_verify(int flag, size_t msg_len, void *msg)
705 {
706 if (!msg || !msg_len)
707 return 0;
708
709 if (flag == C_REQUEST)
710 return verify_setxattr_req(msg_len, msg);
711
712 return 0;
713 }
714
verify_listxattr_req(size_t msg_len, void *msg)715 static int verify_listxattr_req(size_t msg_len, void *msg)
716 {
717 struct listxattr_request *req = msg;
718 int str_len[] = { req->path_len };
719
720 if (req->path_len < 0 || req->path_len >= PATH_MAX)
721 return -EINVAL;
722
723 if (msg_len != sizeof(*req) + req->path_len + 1)
724 return -EINVAL;
725
726 if (req->size < 0 || req->size > XATTR_LIST_MAX)
727 return -EINVAL;
728
729 if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int)))
730 return -EINVAL;
731
732 return 0;
733 }
734
verify_listxattr_resp(size_t msg_len, void *msg)735 static int verify_listxattr_resp(size_t msg_len, void *msg)
736 {
737 struct listxattr_response *resp = msg;
738
739 if (resp->size != sizeof(*resp->list))
740 return -EINVAL;
741
742 if (msg_len < sizeof(*resp))
743 return -EINVAL;
744
745 if (resp->size > XATTR_LIST_MAX)
746 return -EINVAL;
747
748 return 0;
749 }
750
hmdfs_listxattr_verify(int flag, size_t msg_len, void *msg)751 static int hmdfs_listxattr_verify(int flag, size_t msg_len, void *msg)
752 {
753 if (!msg || !msg_len)
754 return 0;
755
756 if (flag == C_REQUEST)
757 return verify_listxattr_req(msg_len, msg);
758 else
759 return verify_listxattr_resp(msg_len, msg);
760 }
761
hmdfs_readpage_verify(int flag, size_t msg_len, void *msg)762 static int hmdfs_readpage_verify(int flag, size_t msg_len, void *msg)
763 {
764 struct readpage_request *req = NULL;
765
766 if (flag != C_REQUEST || !msg || !msg_len)
767 return 0;
768
769 req = msg;
770 if (msg_len != sizeof(*req))
771 return -EINVAL;
772
773 return 0;
774 }
775
hmdfs_writepage_verify(int flag, size_t msg_len, void *msg)776 static int hmdfs_writepage_verify(int flag, size_t msg_len, void *msg)
777 {
778 struct writepage_request *req = NULL;
779
780 if (flag != C_REQUEST || !msg || !msg_len)
781 return 0;
782
783 req = msg;
784 if (req->count <= 0 || req->count > HMDFS_PAGE_SIZE)
785 return -EINVAL;
786
787 if (msg_len != sizeof(*req) + HMDFS_PAGE_SIZE)
788 return -EINVAL;
789
790 return 0;
791 }
792
verify_statfs_req(size_t msg_len, void *msg)793 static int verify_statfs_req(size_t msg_len, void *msg)
794 {
795 struct statfs_request *req = msg;
796 int str_len[] = { req->path_len };
797
798 if (req->path_len < 0 || req->path_len >= PATH_MAX)
799 return -EINVAL;
800
801 if (msg_len != sizeof(*req) + req->path_len + 1)
802 return -EINVAL;
803
804 if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int)))
805 return -EINVAL;
806
807 return 0;
808 }
809
verify_statfs_resp(size_t msg_len, void *msg)810 static int verify_statfs_resp(size_t msg_len, void *msg)
811 {
812 struct statfs_response *resp = msg;
813
814 if (msg_len != sizeof(*resp))
815 return -EINVAL;
816
817 return 0;
818 }
819
hmdfs_statfs_verify(int flag, size_t msg_len, void *msg)820 static int hmdfs_statfs_verify(int flag, size_t msg_len, void *msg)
821 {
822 if (!msg || !msg_len)
823 return 0;
824
825 if (flag == C_REQUEST)
826 return verify_statfs_req(msg_len, msg);
827 else
828 return verify_statfs_resp(msg_len, msg);
829 }
830
verify_drop_push_req(size_t msg_len, void *msg)831 static int verify_drop_push_req(size_t msg_len, void *msg)
832 {
833 struct drop_push_request *req = msg;
834 int str_len[] = { req->path_len };
835
836 if (req->path_len < 0 || req->path_len >= PATH_MAX)
837 return -EINVAL;
838
839 if (msg_len != sizeof(*req) + req->path_len + 1)
840 return -EINVAL;
841
842 if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int)))
843 return -EINVAL;
844
845 return 0;
846 }
847
hmdfs_drop_push_verify(int flag, size_t msg_len, void *msg)848 static int hmdfs_drop_push_verify(int flag, size_t msg_len, void *msg)
849 {
850 if (!msg || !msg_len)
851 return 0;
852
853 if (flag == C_REQUEST)
854 return verify_drop_push_req(msg_len, msg);
855
856 return 0;
857 }
858
859 typedef int (*hmdfs_message_verify_func)(int, size_t, void *);
860
861 static const hmdfs_message_verify_func message_verify[F_SIZE] = {
862 [F_OPEN] = hmdfs_open_verify,
863 [F_READPAGE] = hmdfs_readpage_verify,
864 [F_WRITEPAGE] = hmdfs_writepage_verify,
865 [F_ITERATE] = hmdfs_iterate_verify,
866 [F_MKDIR] = hmdfs_mkdir_verify,
867 [F_RMDIR] = hmdfs_rmdir_verify,
868 [F_CREATE] = hmdfs_create_verify,
869 [F_UNLINK] = hmdfs_unlink_verify,
870 [F_RENAME] = hmdfs_rename_verify,
871 [F_SETATTR] = hmdfs_setattr_verify,
872 [F_STATFS] = hmdfs_statfs_verify,
873 [F_DROP_PUSH] = hmdfs_drop_push_verify,
874 [F_GETATTR] = hmdfs_getattr_verify,
875 [F_GETXATTR] = hmdfs_getxattr_verify,
876 [F_SETXATTR] = hmdfs_setxattr_verify,
877 [F_LISTXATTR] = hmdfs_listxattr_verify,
878 [F_ATOMIC_OPEN] = hmdfs_atomic_open_verify,
879 };
880
handle_bad_message(struct hmdfs_peer *con, struct hmdfs_head_cmd *head, int *err)881 static void handle_bad_message(struct hmdfs_peer *con,
882 struct hmdfs_head_cmd *head, int *err)
883 {
884 /*
885 * Bad message won't be awared by upper layer, so ETIME is
886 * always given to upper layer. It is prefer to pass EOPNOTSUPP
887 * to upper layer when bad message (eg. caused by wrong len)
888 * received.
889 */
890 if (head->operations.cmd_flag == C_RESPONSE) {
891 /*
892 * Change msg ret code. To let upper layer handle
893 * EOPNOTSUPP, hmdfs_message_verify() should return
894 * 0, so err code is modified either.
895 */
896 head->ret_code = cpu_to_le32(-EOPNOTSUPP);
897 *err = 0;
898 } else {
899 if (head->operations.command >= F_SIZE)
900 return;
901 /*
902 * Some request messages do not need to be responded.
903 * Even if a response is returned, the response msg
904 * is automatically ignored in hmdfs_response_recv().
905 * Therefore, it is normal to directly return a response.
906 */
907 if (need_response[head->operations.command])
908 hmdfs_send_err_response(con, head, -EOPNOTSUPP);
909 }
910 }
911
is_reserved_command(int command)912 bool is_reserved_command(int command)
913 {
914 if ((command >= F_RESERVED_1 && command <= F_RESERVED_4) ||
915 command == F_RESERVED_5 || command == F_RESERVED_6 ||
916 command == F_RESERVED_7 || command == F_RESERVED_8)
917 return true;
918 return false;
919 }
920
hmdfs_message_verify(struct hmdfs_peer *con, struct hmdfs_head_cmd *head, void *data)921 int hmdfs_message_verify(struct hmdfs_peer *con, struct hmdfs_head_cmd *head,
922 void *data)
923 {
924 int err = 0;
925 int flag, cmd, len_type;
926 size_t len, min, max;
927
928 if (!head)
929 return -EINVAL;
930
931 flag = head->operations.cmd_flag;
932 if (flag != C_REQUEST && flag != C_RESPONSE)
933 return -EINVAL;
934
935 cmd = head->operations.command;
936 if (cmd >= F_SIZE || cmd < F_OPEN || is_reserved_command(cmd)) {
937 err = -EINVAL;
938 goto handle_bad_msg;
939 }
940
941 len = le32_to_cpu(head->data_len) -
942 sizeof(struct hmdfs_head_cmd);
943 min = message_length[flag][cmd][HMDFS_MESSAGE_MIN_INDEX];
944 if (head->operations.command == F_ITERATE && flag == C_RESPONSE)
945 max = sizeof(struct slice_descriptor) + PAGE_SIZE;
946 else
947 max = message_length[flag][cmd][HMDFS_MESSAGE_MAX_INDEX];
948 len_type =
949 message_length[flag][cmd][HMDFS_MESSAGE_LEN_JUDGE_INDEX];
950
951 if (len_type == MESSAGE_LEN_JUDGE_RANGE) {
952 if (len < min || len > max) {
953 hmdfs_err(
954 "cmd %d -> %d message verify fail, len = %zu",
955 cmd, flag, len);
956 err = -EINVAL;
957 goto handle_bad_msg;
958 }
959 } else {
960 if (len != min && len != max) {
961 hmdfs_err(
962 "cmd %d -> %d message verify fail, len = %zu",
963 cmd, flag, len);
964 err = -EINVAL;
965 goto handle_bad_msg;
966 }
967 }
968
969 if (message_verify[cmd])
970 err = message_verify[cmd](flag, len, data);
971
972 if (err)
973 goto handle_bad_msg;
974
975 return err;
976
977 handle_bad_msg:
978 handle_bad_message(con, head, &err);
979 return err;
980 }
981