• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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