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