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
18size_t message_length[C_FLAG_SIZE][F_SIZE][HMDFS_MESSAGE_MIN_MAX];
19bool need_response[F_SIZE];
20
21void 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
274static 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
289static 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
307static 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
317static 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
328static 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
346static 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
356static 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
367static 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
384static 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
395static 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
413static 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
423static 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
434static 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
452static 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
462static 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
473static 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
491static 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
502static 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
520static 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
531static 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
554static 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
565static 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
583static 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
594static 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
611static 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
621static 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
632static 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
654static 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
670static 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
681static 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
704static 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
715static 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
735static 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
751static 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
762static 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
776static 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
793static 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
810static 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
820static 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
831static 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
848static 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
859typedef int (*hmdfs_message_verify_func)(int, size_t, void *);
860
861static 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
881static 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
912bool 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
921int 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
977handle_bad_msg:
978	handle_bad_message(con, head, &err);
979	return err;
980}
981