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