From eeb757f522994405584c6597cd4238faf264a545 Mon Sep 17 00:00:00 2001 From: waterwin Date: Fri, 26 May 2023 09:43:02 +0000 Subject: [PATCH] hmdfs: message verify Signed-off-by: waterwin --- fs/hmdfs/comm/message_verify.c | 878 +++++++++++++++++---------------- fs/hmdfs/comm/protocol.h | 35 +- fs/hmdfs/comm/socket_adapter.c | 4 - fs/hmdfs/hmdfs_server.c | 150 ------ fs/hmdfs/hmdfs_server.h | 4 - 5 files changed, 457 insertions(+), 614 deletions(-) diff --git a/fs/hmdfs/comm/message_verify.c b/fs/hmdfs/comm/message_verify.c index fd76658ef16d..019b7faac988 100644 --- a/fs/hmdfs/comm/message_verify.c +++ b/fs/hmdfs/comm/message_verify.c @@ -91,32 +91,6 @@ void hmdfs_message_verify_init(void) message_length[C_RESPONSE][F_READPAGE][HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_RANGE; - message_length[C_REQUEST][F_READPAGES][HMDFS_MESSAGE_MIN_INDEX] = - sizeof(struct readpages_request); - message_length[C_REQUEST][F_READPAGES][HMDFS_MESSAGE_MAX_INDEX] = - sizeof(struct readpages_request); - message_length[C_REQUEST][F_READPAGES][HMDFS_MESSAGE_LEN_JUDGE_INDEX] = - MESSAGE_LEN_JUDGE_BIN; - message_length[C_RESPONSE][F_READPAGES][HMDFS_MESSAGE_MIN_INDEX] = 0; - message_length[C_RESPONSE][F_READPAGES][HMDFS_MESSAGE_MAX_INDEX] = - HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE; - message_length[C_RESPONSE][F_READPAGES][HMDFS_MESSAGE_LEN_JUDGE_INDEX] = - MESSAGE_LEN_JUDGE_RANGE; - - message_length[C_REQUEST][F_READPAGES_OPEN][HMDFS_MESSAGE_MIN_INDEX] = - sizeof(struct readpages_open_request); - message_length[C_REQUEST][F_READPAGES_OPEN][HMDFS_MESSAGE_MAX_INDEX] = - sizeof(struct readpages_open_request) + PATH_MAX + 1; - message_length[C_REQUEST][F_READPAGES_OPEN][ - HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_RANGE; - message_length[C_RESPONSE][F_READPAGES_OPEN][HMDFS_MESSAGE_MIN_INDEX] = - 0; - message_length[C_RESPONSE][F_READPAGES_OPEN][HMDFS_MESSAGE_MAX_INDEX] = - sizeof(struct readpages_open_response) + - HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE; - message_length[C_RESPONSE][F_READPAGES_OPEN][ - HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_RANGE; - message_length[C_REQUEST][F_WRITEPAGE][HMDFS_MESSAGE_MIN_INDEX] = sizeof(struct writepage_request) + HMDFS_PAGE_SIZE; message_length[C_REQUEST][F_WRITEPAGE][HMDFS_MESSAGE_MAX_INDEX] = @@ -341,30 +315,43 @@ static bool path_contain_dotdot(const char *name, int len) } } -static int hmdfs_open_message_verify(int flag, size_t len, void *data) +static int is_str_msg_valid(char *msg, int str_len[], size_t str_num) { - struct open_request *req = NULL; - size_t tmp_len = 0; - int path_len; + int i = 0; + int pos = 0; - if (flag != C_REQUEST || !data) - return 0; + for (i = 0; i < str_num; i++) { + if (msg[pos + str_len[i]] != '\0' || + strnlen(msg + pos, PATH_MAX) != str_len[i]) { + return -EINVAL; + } - req = data; - path_len = le32_to_cpu(req->path_len); - tmp_len = strnlen(req->buf, PATH_MAX); - if (tmp_len == PATH_MAX || - tmp_len != len - sizeof(struct open_request) - 1 || - path_len != tmp_len) { - hmdfs_err("verify fail"); - return -EINVAL; + pos += str_len[i] + 1; } + return 0; +} + +static int verify_open_req(size_t msg_len, void *msg) +{ + struct open_request *req = msg; + int str_len[] = { req->path_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + str_len[0] = req->path_len; + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + /* * We only allow server to open file in hmdfs, thus we need to * make sure path don't contain "..". */ - if (path_contain_dotdot(req->buf, path_len)) { + if (path_contain_dotdot(req->buf, req->path_len)) { hmdfs_err("verify fail, path contain dotdot"); return -EINVAL; } @@ -372,490 +359,531 @@ static int hmdfs_open_message_verify(int flag, size_t len, void *data) return 0; } -static int hmdfs_atomic_open_verify(int flag, size_t len, void *data) +static int verify_open_resp(size_t msg_len, void *msg) { - struct atomic_open_request *req = NULL; - size_t total_len; - size_t path_len; - size_t max_path_size; - size_t file_len; - size_t max_file_size; + struct open_response *resp = msg; - if (flag != C_REQUEST || !data) + if (msg_len != sizeof(*resp)) + return -EINVAL; + + return 0; +} + +static int hmdfs_open_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) return 0; - req = data; - total_len = len - sizeof(*req); - max_path_size = min_t(size_t, PATH_MAX, total_len); - path_len = strnlen(req->buf, max_path_size); - /* file name need 2 byte at least */ - if (path_len == max_path_size || path_len + 3 > total_len) { - hmdfs_err("verify fail, len %zu, path_len %zu", len, path_len); + if (flag == C_REQUEST) + return verify_open_req(msg_len, msg); + else + return verify_open_resp(msg_len, msg); +} + +static int verify_atomic_open_req(size_t msg_len, void *msg) +{ + struct atomic_open_request *req = msg; + int str_len[] = { req->path_len, req->file_len}; + + if (req->path_len < 0 || req->path_len >= PATH_MAX || + req->file_len < 0 || req->file_len >= PATH_MAX) return -EINVAL; - } - max_file_size = min_t(size_t, NAME_MAX + 1, total_len - path_len - 1); - file_len = strnlen(req->buf + path_len + 1, max_file_size); + if (msg_len != sizeof(*req) + req->path_len + 1 + req->file_len + 1) + return -EINVAL; - if (file_len == max_file_size || - total_len != path_len + 1 + file_len + 1 || - le32_to_cpu(req->path_len) != path_len || - le32_to_cpu(req->file_len) != file_len) { - hmdfs_err("verify fail total len %zu path_len %zu, decalared path len %u, file_len %zu, decalared file_len %u", - total_len, path_len, le32_to_cpu(req->path_len), - file_len, le32_to_cpu(req->file_len) != file_len); + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) return -EINVAL; - } return 0; } -static int hmdfs_iterate_verify(int flag, size_t len, void *data) +static int verify_atomic_open_resp(size_t msg_len, void *msg) { - int err = 0; - struct readdir_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->path; - tmp_len = strnlen(tmp_char, PATH_MAX); - } else { - return err; - } + struct atomic_open_response *resp = msg; - if (le32_to_cpu(tmp_request->path_len) != tmp_len || - len - sizeof(struct readdir_request) - 1 != tmp_len) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } + if (msg_len != sizeof(*resp)) + return -EINVAL; - return err; + return 0; } -static int hmdfs_mkdir_verify(int flag, size_t len, void *data) +static int hmdfs_atomic_open_verify(int flag, size_t msg_len, void *msg) { - int err = 0; - struct mkdir_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_path_len = 0; - size_t tmp_name_len = 0; - size_t tmp_char_path_len = 0; - size_t tmp_char_name_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->path; - tmp_path_len = le32_to_cpu(tmp_request->path_len); - tmp_name_len = le32_to_cpu(tmp_request->name_len); - tmp_char_path_len = strnlen(tmp_char, PATH_MAX); - tmp_char_name_len = strnlen( - tmp_char + tmp_char_path_len + 1, NAME_MAX); - } else { - return err; - } + if (!msg || !msg_len) + return 0; - if (tmp_path_len != tmp_char_path_len || - tmp_name_len != tmp_char_name_len || - len - sizeof(struct mkdir_request) != - tmp_path_len + 1 + tmp_name_len + 1) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } - return err; + if (flag == C_REQUEST) + return verify_atomic_open_req(msg_len, msg); + else + return verify_atomic_open_resp(msg_len, msg); } -static int hmdfs_create_verify(int flag, size_t len, void *data) +static int verify_iterate_req(size_t msg_len, void *msg) { - int err = 0; - struct create_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_path_len = 0; - size_t tmp_name_len = 0; - size_t tmp_char_path_len = 0; - size_t tmp_char_name_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->path; - tmp_path_len = le32_to_cpu(tmp_request->path_len); - tmp_name_len = le32_to_cpu(tmp_request->name_len); - tmp_char_path_len = strnlen(tmp_char, PATH_MAX); - tmp_char_name_len = strnlen( - tmp_char + tmp_char_path_len + 1, NAME_MAX); - } else { - return err; - } + struct readdir_request *req = msg; + int str_len[] = { req->path_len }; - if (tmp_path_len != tmp_char_path_len || - tmp_name_len != tmp_char_name_len || - len - sizeof(struct create_request) != - tmp_path_len + 1 + tmp_name_len + 1) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } - return err; + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + + return 0; } -static int hmdfs_rmdir_verify(int flag, size_t len, void *data) +static int hmdfs_iterate_verify(int flag, size_t msg_len, void *msg) { - int err = 0; - struct rmdir_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_path_len = 0; - size_t tmp_name_len = 0; - size_t tmp_char_path_len = 0; - size_t tmp_char_name_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->path; - tmp_path_len = le32_to_cpu(tmp_request->path_len); - tmp_name_len = le32_to_cpu(tmp_request->name_len); - tmp_char_path_len = strnlen(tmp_char, PATH_MAX); - tmp_char_name_len = strnlen( - tmp_char + tmp_char_path_len + 1, NAME_MAX); - } else { - return err; - } + if (!msg || !msg_len) + return 0; - if (tmp_path_len != tmp_char_path_len || - tmp_name_len != tmp_char_name_len || - len - sizeof(struct rmdir_request) != - tmp_path_len + 1 + tmp_name_len + 1) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } + if (flag == C_REQUEST) + return verify_iterate_req(msg_len, msg); - return err; + return 0; } -static int hmdfs_unlink_verify(int flag, size_t len, void *data) +static int verify_mkdir_req(size_t msg_len, void *msg) { - int err = 0; - struct unlink_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_path_len = 0; - size_t tmp_name_len = 0; - size_t tmp_char_path_len = 0; - size_t tmp_char_name_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->path; - tmp_path_len = le32_to_cpu(tmp_request->path_len); - tmp_name_len = le32_to_cpu(tmp_request->name_len); - tmp_char_path_len = strnlen(tmp_char, PATH_MAX); - tmp_char_name_len = strnlen( - tmp_char + tmp_char_path_len + 1, NAME_MAX); - } else { - return err; - } + struct mkdir_request *req = msg; + int str_len[] = { req->path_len, req->name_len }; - if (tmp_path_len != tmp_char_path_len || - tmp_name_len != tmp_char_name_len || - len - sizeof(struct unlink_request) != - tmp_path_len + 1 + tmp_name_len + 1) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } + if (req->path_len < 0 || req->path_len >= PATH_MAX || + req->name_len < 0 || req->name_len >= PATH_MAX) + return -EINVAL; - return err; + if (msg_len != sizeof(*req) + req->path_len + 1 + req->name_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + + return 0; } -static int hmdfs_rename_verify(int flag, size_t len, void *data) +static int verify_mkdir_resp(size_t msg_len, void *msg) { - int err = 0; - struct rename_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_old_path_len = 0; - size_t tmp_new_path_len = 0; - size_t tmp_old_name_len = 0; - size_t tmp_new_name_len = 0; - size_t tmp_char_old_path_len = 0; - size_t tmp_char_new_path_len = 0; - size_t tmp_char_old_name_len = 0; - size_t tmp_char_new_name_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->path; - - tmp_old_path_len = - le32_to_cpu(tmp_request->old_path_len); - tmp_new_path_len = - le32_to_cpu(tmp_request->new_path_len); - tmp_old_name_len = - le32_to_cpu(tmp_request->old_name_len); - tmp_new_name_len = - le32_to_cpu(tmp_request->new_name_len); - - tmp_char_old_path_len = strnlen(tmp_char, PATH_MAX); - tmp_char_new_path_len = strnlen( - tmp_char + tmp_char_old_path_len + 1, PATH_MAX); - - tmp_char_old_name_len = - strnlen(tmp_char + tmp_char_old_path_len + 1 + - tmp_char_new_path_len + 1, - PATH_MAX); - tmp_char_new_name_len = - strnlen(tmp_char + tmp_char_old_path_len + 1 + - tmp_char_new_path_len + 1 + - tmp_char_old_name_len + 1, - PATH_MAX); - } else { - return err; - } + struct hmdfs_inodeinfo_response *resp = msg; - if (tmp_new_name_len != tmp_char_new_name_len || - tmp_old_name_len != tmp_char_old_name_len || - tmp_new_path_len != tmp_char_new_path_len || - tmp_old_path_len != tmp_char_old_path_len || - len - sizeof(struct rename_request) != - tmp_new_name_len + 1 + tmp_old_name_len + 1 + - tmp_new_path_len + 1 + tmp_old_path_len + - 1) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } + if (msg_len != sizeof(*resp)) + return -EINVAL; - return err; + return 0; } -static int hmdfs_setattr_verify(int flag, size_t len, void *data) +static int hmdfs_mkdir_verify(int flag, size_t msg_len, void *msg) { - int err = 0; - struct setattr_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->buf; - tmp_len = strnlen(tmp_char, PATH_MAX); - } else { - return err; - } + if (!msg || !msg_len) + return 0; - if (tmp_len != len - sizeof(struct setattr_request) - 1 || - le32_to_cpu(tmp_request->path_len) != tmp_len) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } + if (flag == C_REQUEST) + return verify_mkdir_req(msg_len, msg); + else + return verify_mkdir_resp(msg_len, msg); +} - return err; +static int verify_create_req(size_t msg_len, void *msg) +{ + struct create_request *req = msg; + int str_len[] = { req->path_len, req->name_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX || + req->name_len < 0 || req->name_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1 + req->name_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + + return 0; } -static int hmdfs_getattr_verify(int flag, size_t len, void *data) +static int verify_create_resp(size_t msg_len, void *msg) { - struct getattr_request *req = NULL; - size_t tmp_len; + struct hmdfs_inodeinfo_response *resp = msg; + + if (msg_len != sizeof(*resp)) + return -EINVAL; + + return 0; +} - if (flag != C_REQUEST || !data) +static int hmdfs_create_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) return 0; - req = data; - tmp_len = strnlen(req->buf, PATH_MAX); - if (tmp_len != len - sizeof(struct getattr_request) - 1 || - le32_to_cpu(req->path_len) != tmp_len) { - hmdfs_err("verify fail"); + if (flag == C_REQUEST) + return verify_create_req(msg_len, msg); + else + return verify_create_resp(msg_len, msg); +} + +static int verify_rmdir_req(size_t msg_len, void *msg) +{ + struct rmdir_request *req = msg; + int str_len[] = { req->path_len, req->name_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX || + req->name_len < 0 || req->name_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1 + req->name_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) return -EINVAL; - } return 0; } -static int hmdfs_getxattr_verify(int flag, size_t len, void *data) +static int hmdfs_rmdir_verify(int flag, size_t msg_len, void *msg) { - struct getxattr_request *req = NULL; - struct getxattr_response *resp = NULL; - size_t path_len = 0; - size_t name_len = 0; - size_t size = 0; + if (!msg || !msg_len) + return 0; + + if (flag == C_REQUEST) + return verify_rmdir_req(msg_len, msg); + + return 0; +} + +static int verify_unlink_req(size_t msg_len, void *msg) +{ + struct unlink_request *req = msg; + int str_len[] = { req->path_len, req->name_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX || + req->name_len < 0 || req->name_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1 + req->name_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; - if (!data) + return 0; +} + +static int hmdfs_unlink_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) return 0; - if (flag == C_REQUEST) { - req = data; - path_len = le32_to_cpu(req->path_len); - name_len = le32_to_cpu(req->name_len); - size = le32_to_cpu(req->size); - if (path_len >= PATH_MAX || - path_len != strnlen(req->buf, PATH_MAX) || - name_len != - strnlen(req->buf + path_len + 1, XATTR_NAME_MAX) || - size > HMDFS_XATTR_SIZE_MAX) - return -EINVAL; - } else { - resp = data; - size = le32_to_cpu(resp->size); - if (len != sizeof(struct getxattr_response) && - len < sizeof(struct getxattr_response) + size) - return -EINVAL; - } + if (flag == C_REQUEST) + return verify_unlink_req(msg_len, msg); + + return 0; +} + +static int verify_rename_req(size_t msg_len, void *msg) +{ + struct rename_request *req = msg; + int str_len[] = { req->old_path_len, req->new_path_len, + req->old_name_len, req->new_name_len }; + + if (req->old_path_len < 0 || req->old_path_len >= PATH_MAX || + req->new_path_len < 0 || req->new_path_len >= PATH_MAX || + req->old_name_len < 0 || req->old_name_len >= PATH_MAX || + req->new_name_len < 0 || req->new_name_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->old_path_len + 1 + + req->new_path_len + 1 + req->old_name_len + 1 + + req->new_name_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; return 0; } -static int hmdfs_setxattr_verify(int flag, size_t len, void *data) +static int hmdfs_rename_verify(int flag, size_t msg_len, void *msg) { - struct setxattr_request *req = NULL; - size_t path_len = 0; - size_t name_len = 0; - size_t size = 0; + if (!msg || !msg_len) + return 0; + + if (flag == C_REQUEST) + return verify_rename_req(msg_len, msg); + + return 0; +} - /* No need to verify response */ - if (flag != C_REQUEST || !data) +static int verify_setattr_req(size_t msg_len, void *msg) +{ + struct setattr_request *req = msg; + int str_len[] = { req->path_len }; + + req = msg; + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + + return 0; +} + +static int hmdfs_setattr_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) return 0; - req = data; - path_len = le32_to_cpu(req->path_len); - name_len = le32_to_cpu(req->name_len); - size = le32_to_cpu(req->size); - if (path_len >= PATH_MAX || path_len != strnlen(req->buf, PATH_MAX) || - name_len != strnlen(req->buf + path_len + 1, XATTR_NAME_MAX) || - len != path_len + name_len + size + 2 + - sizeof(struct setxattr_request) || - size > HMDFS_XATTR_SIZE_MAX) + if (flag == C_REQUEST) + return verify_setattr_req(msg_len, msg); + + return 0; +} + +static int verify_getattr_req(size_t msg_len, void *msg) +{ + struct getattr_request *req = msg; + int str_len[] = { req->path_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) return -EINVAL; return 0; } -static int hmdfs_listxattr_verify(int flag, size_t len, void *data) +static int verify_getattr_resp(size_t msg_len, void *msg) { - struct listxattr_request *req = NULL; - struct listxattr_response *resp = NULL; - size_t path_len = 0; - size_t size = 0; + struct getattr_response *resp = msg; + + if (msg_len != sizeof(*resp)) + return -EINVAL; + + return 0; +} - if (!data) +static int hmdfs_getattr_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) return 0; - if (flag == C_REQUEST) { - req = data; - path_len = le32_to_cpu(req->path_len); - size = le32_to_cpu(req->size); - if (path_len >= PATH_MAX || - path_len != strnlen(req->buf, PATH_MAX) || - size > HMDFS_LISTXATTR_SIZE_MAX) - return -EINVAL; - } else { - resp = data; - size = le32_to_cpu(resp->size); - if (len != sizeof(struct listxattr_response) && - len < sizeof(struct listxattr_response) + size) - return -EINVAL; - } + if (flag == C_REQUEST) + return verify_getattr_req(msg_len, msg); + else + return verify_getattr_resp(msg_len, msg); +} + +static int verify_getxattr_req(size_t msg_len, void *msg) +{ + struct getxattr_request *req = msg; + int str_len[] = { req->path_len, req->name_len}; + + if (req->path_len < 0 || req->path_len >= PATH_MAX || + req->name_len < 0 || req->name_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1 + req->name_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; return 0; } -static int hmdfs_writepage_verify(int flag, size_t len, void *data) +static int verify_getxattr_resp(size_t msg_len, void *msg) { - struct writepage_request *req = NULL; - __u32 count; + struct getxattr_response *resp = msg; + + if (msg_len < sizeof(*resp)) + return -EINVAL; + + return 0; +} - if (flag != C_REQUEST || !data) +static int hmdfs_getxattr_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) return 0; - req = data; - count = le32_to_cpu(req->count); - if (count == 0 || count > HMDFS_PAGE_SIZE || - len - sizeof(struct writepage_request) != HMDFS_PAGE_SIZE) { - hmdfs_err("verify fail, count is %d", count); + if (flag == C_REQUEST) + return verify_getxattr_req(msg_len, msg); + else + return verify_getxattr_resp(msg_len, msg); +} + +static int verify_setxattr_req(size_t msg_len, void *msg) +{ + struct setxattr_request *req = msg; + int str_len[] = { req->path_len, req->name_len}; + + if (req->path_len < 0 || req->path_len >= PATH_MAX || + req->name_len < 0 || req->name_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1 + req->name_len + 1 + + req->size) + return -EINVAL; + + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) return -EINVAL; - } return 0; } -static int hmdfs_statfs_verify(int flag, size_t len, void *data) +static int hmdfs_setxattr_verify(int flag, size_t msg_len, void *msg) { - int err = 0; - struct statfs_request *tmp_request = NULL; - char *tmp_char = NULL; - size_t tmp_len = 0; - - if (flag == C_REQUEST) { - if (data) { - tmp_request = data; - tmp_char = tmp_request->path; - tmp_len = strnlen(tmp_char, PATH_MAX); - } else { - return err; - } + if (!msg || !msg_len) + return 0; - if (le32_to_cpu(tmp_request->path_len) != tmp_len || - tmp_len != len - sizeof(struct statfs_request) - 1) { - err = -EINVAL; - hmdfs_err("verify fail"); - return err; - } - } + if (flag == C_REQUEST) + return verify_setxattr_req(msg_len, msg); - return err; + return 0; +} + +static int verify_listxattr_req(size_t msg_len, void *msg) +{ + struct listxattr_request *req = msg; + int str_len[] = { req->path_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + + return 0; +} + +static int verify_listxattr_resp(size_t msg_len, void *msg) +{ + struct listxattr_response *resp = msg; + + if (msg_len < sizeof(*resp)) + return -EINVAL; + + return 0; } -static int hmdfs_readpages_verify(int flag, size_t len, void *data) +static int hmdfs_listxattr_verify(int flag, size_t msg_len, void *msg) { - struct readpages_request *req = NULL; - unsigned int size; + if (!msg || !msg_len) + return 0; - if (flag != C_REQUEST || !data) + if (flag == C_REQUEST) + return verify_listxattr_req(msg_len, msg); + else + return verify_listxattr_resp(msg_len, msg); +} + +static int hmdfs_readpage_verify(int flag, size_t msg_len, void *msg) +{ + struct readpage_request *req = NULL; + + if (flag != C_REQUEST || !msg || !msg_len) return 0; - req = data; - size = le32_to_cpu(req->size); - if (size > HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE) { - hmdfs_err("verify fail, invalid req->size %u", size); + req = msg; + if (msg_len != sizeof(*req)) return -EINVAL; - } return 0; } -static int hmdfs_readpages_open_verify(int flag, size_t len, void *data) +static int hmdfs_writepage_verify(int flag, size_t msg_len, void *msg) { - struct readpages_open_request *req = NULL; - unsigned int size; - size_t tmp_len; + struct writepage_request *req = NULL; - if (flag != C_REQUEST || !data) + if (flag != C_REQUEST || !msg || !msg_len) return 0; - req = data; - size = le32_to_cpu(req->size); - tmp_len = strnlen(req->buf, PATH_MAX); - if (tmp_len + 1 != len - sizeof(*req) || - le32_to_cpu(req->path_len) != tmp_len || - size > HMDFS_READPAGES_NR_MAX * HMDFS_PAGE_SIZE) { - hmdfs_err("verify fail, req->size %u", size); + req = msg; + if (req->count <= 0 || req->count > HMDFS_PAGE_SIZE) + return -EINVAL; + + if (msg_len != sizeof(*req) + HMDFS_PAGE_SIZE) + return -EINVAL; + + return 0; +} + +static int verify_statfs_req(size_t msg_len, void *msg) +{ + struct statfs_request *req = msg; + int str_len[] = { req->path_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + + return 0; +} + +static int verify_statfs_resp(size_t msg_len, void *msg) +{ + struct statfs_response *resp = msg; + + if (msg_len != sizeof(*resp)) + return -EINVAL; + + return 0; +} + +static int hmdfs_statfs_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) + return 0; + + if (flag == C_REQUEST) + return verify_statfs_req(msg_len, msg); + else + return verify_statfs_resp(msg_len, msg); +} + +static int verify_drop_push_req(size_t msg_len, void *msg) +{ + struct drop_push_request *req = msg; + int str_len[] = { req->path_len }; + + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->path, str_len, sizeof(str_len) / sizeof(int))) return -EINVAL; - } + + return 0; +} + +static int hmdfs_drop_push_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) + return 0; + + if (flag == C_REQUEST) + return verify_drop_push_req(msg_len, msg); return 0; } @@ -863,22 +891,22 @@ static int hmdfs_readpages_open_verify(int flag, size_t len, void *data) typedef int (*hmdfs_message_verify_func)(int, size_t, void *); static const hmdfs_message_verify_func message_verify[F_SIZE] = { - [F_OPEN] = hmdfs_open_message_verify, + [F_OPEN] = hmdfs_open_verify, + [F_READPAGE] = hmdfs_readpage_verify, [F_WRITEPAGE] = hmdfs_writepage_verify, [F_ITERATE] = hmdfs_iterate_verify, [F_MKDIR] = hmdfs_mkdir_verify, - [F_CREATE] = hmdfs_create_verify, [F_RMDIR] = hmdfs_rmdir_verify, + [F_CREATE] = hmdfs_create_verify, [F_UNLINK] = hmdfs_unlink_verify, [F_RENAME] = hmdfs_rename_verify, [F_SETATTR] = hmdfs_setattr_verify, [F_STATFS] = hmdfs_statfs_verify, + [F_DROP_PUSH] = hmdfs_drop_push_verify, [F_GETATTR] = hmdfs_getattr_verify, [F_GETXATTR] = hmdfs_getxattr_verify, [F_SETXATTR] = hmdfs_setxattr_verify, [F_LISTXATTR] = hmdfs_listxattr_verify, - [F_READPAGES] = hmdfs_readpages_verify, - [F_READPAGES_OPEN] = hmdfs_readpages_open_verify, [F_ATOMIC_OPEN] = hmdfs_atomic_open_verify, }; @@ -928,8 +956,10 @@ int hmdfs_message_verify(struct hmdfs_peer *con, struct hmdfs_head_cmd *head, return -EINVAL; cmd = head->operations.command; - if (cmd >= F_SIZE || cmd < F_OPEN || cmd == F_RESERVED_0 || - (cmd >= F_RESERVED_1 && cmd <= F_RESERVED_4) || cmd == F_RESERVED_5) { + if (cmd >= F_SIZE || cmd < F_OPEN || + (cmd >= F_RESERVED_1 && cmd <= F_RESERVED_4) || + cmd == F_RESERVED_5 || cmd == F_RESERVED_6 || + cmd == F_RESERVED_7 || cmd == F_RESERVED_8) { err = -EINVAL; goto handle_bad_msg; } diff --git a/fs/hmdfs/comm/protocol.h b/fs/hmdfs/comm/protocol.h index a873143f20d7..c63dd116253d 100644 --- a/fs/hmdfs/comm/protocol.h +++ b/fs/hmdfs/comm/protocol.h @@ -177,15 +177,15 @@ enum FILE_CMD { F_STATFS = 16, F_CONNECT_REKEY = 17, F_DROP_PUSH = 18, - F_RESERVED_0 = 19, + F_RESERVED_6 = 19, F_GETATTR = 20, F_FSYNC = 21, F_SYNCFS = 22, F_GETXATTR = 23, F_SETXATTR = 24, F_LISTXATTR = 25, - F_READPAGES = 26, - F_READPAGES_OPEN = 27, + F_RESERVED_7 = 26, + F_RESERVED_8 = 27, F_ATOMIC_OPEN = 28, F_SIZE, }; @@ -261,35 +261,6 @@ struct readpage_response { char buf[0]; } __packed; -struct readpages_request { - __le64 file_ver; - __le32 file_id; - __le32 size; - __le64 index; - __le64 reserved; -} __packed; - -struct readpages_response { - char buf[0]; -} __packed; - -struct readpages_open_request { - __u8 file_type; - __u8 reserved1[3]; - __le32 flags; - __le32 path_len; - __le32 size; - __le64 index; - __le64 reserved2; - char buf[0]; -} __packed; - -struct readpages_open_response { - struct open_response open_resp; - __le64 reserved[4]; - char buf[0]; -} __packed; - struct writepage_request { __le64 file_ver; __le32 file_id; diff --git a/fs/hmdfs/comm/socket_adapter.c b/fs/hmdfs/comm/socket_adapter.c index 0404c2a79d3a..944e9c12e556 100644 --- a/fs/hmdfs/comm/socket_adapter.c +++ b/fs/hmdfs/comm/socket_adapter.c @@ -49,8 +49,6 @@ static const request_callback s_recv_callbacks[F_SIZE] = { [F_GETXATTR] = hmdfs_server_getxattr, [F_SETXATTR] = hmdfs_server_setxattr, [F_LISTXATTR] = hmdfs_server_listxattr, - [F_READPAGES] = hmdfs_server_readpages, - [F_READPAGES_OPEN] = hmdfs_server_readpages_open, [F_ATOMIC_OPEN] = hmdfs_server_atomic_open, }; @@ -844,14 +842,12 @@ static int hmdfs_request_recv(struct hmdfs_peer *con, case F_GETXATTR: case F_SETXATTR: case F_LISTXATTR: - case F_READPAGES_OPEN: case F_ATOMIC_OPEN: ret = hmdfs_msg_handle_async(con, head, buf, con->req_handle_wq, hmdfs_request_work_fn); break; case F_WRITEPAGE: case F_READPAGE: - case F_READPAGES: hmdfs_msg_handle_sync(con, head, buf); ret = 0; break; diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index fc0274233970..7e7460a7be6a 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -754,156 +754,6 @@ void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_send_err_response(con, cmd, ret); } -static struct readpages_response *alloc_readpages_resp(unsigned int len) -{ - struct readpages_response *resp = NULL; - - if (len > HMDFS_PAGE_SIZE) - resp = vmalloc(len); - else - resp = kmalloc(len, GFP_KERNEL); - - return resp; -} - -static void free_readpages_resp(struct readpages_response *resp, - unsigned int len) -{ - if (len > HMDFS_PAGE_SIZE) - vfree(resp); - else - kfree(resp); -} - -void hmdfs_server_readpages(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) -{ - struct readpages_request *req = data; - __u64 file_ver; - __u32 file_id; - struct file *file = NULL; - loff_t pos; - struct readpages_response *resp = NULL; - ssize_t ret = 0; - size_t read_len; - - file_id = le32_to_cpu(req->file_id); - file_ver = le64_to_cpu(req->file_ver); - file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) { - ret = PTR_ERR(file); - goto fail; - } - - read_len = (size_t)le32_to_cpu(req->size); - if (read_len == 0) - goto fail_put_file; - - resp = alloc_readpages_resp(read_len); - if (!resp) { - ret = -ENOMEM; - goto fail_put_file; - } - - pos = (loff_t)le64_to_cpu(req->index) << HMDFS_PAGE_OFFSET; - ret = kernel_read(file, resp->buf, read_len, &pos); - if (ret < 0) { - ret = -EIO; - goto fail_free_resp; - } - - hmdfs_sendmessage_response(con, cmd, ret, resp, 0); - hmdfs_close_path(file); - free_readpages_resp(resp, read_len); - return; - -fail_free_resp: - free_readpages_resp(resp, read_len); -fail_put_file: - hmdfs_close_path(file); -fail: - hmdfs_send_err_response(con, cmd, ret); -} - -static int hmdfs_do_readpages_open(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, - struct readpages_open_request *recv, - struct hmdfs_open_info *info, - struct readpages_open_response *resp) -{ - int ret = 0; - loff_t pos = 0; - - info->file = hmdfs_open_file(con, recv->buf, recv->file_type, - &info->file_id); - if (IS_ERR(info->file)) - return PTR_ERR(info->file); - - ret = hmdfs_get_open_info(con, recv->file_type, recv->buf, info); - if (ret) - goto fail_close; - - pos = (loff_t)le64_to_cpu(recv->index) << HMDFS_PAGE_OFFSET; - ret = kernel_read(info->file, resp->buf, le32_to_cpu(recv->size), &pos); - if (ret < 0) - goto fail_close; - - hmdfs_update_open_response(con, cmd, info, &resp->open_resp); - memset(resp->reserved, 0, sizeof(resp->reserved)); - ret = hmdfs_sendmessage_response(con, cmd, sizeof(*resp) + ret, resp, - 0); - if (ret) { - hmdfs_err("sending msg response failed, file_id %d, err %d", - info->file_id, ret); - ret = 0; - goto fail_close; - } - return 0; - -fail_close: - remove_file_from_conn(con, info->file_id); - hmdfs_close_path(info->file); - return ret; -} - -void hmdfs_server_readpages_open(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) -{ - struct readpages_open_request *recv = data; - struct readpages_open_response *resp = NULL; - int ret = -EINVAL; - size_t read_len = 0; - size_t resp_len = 0; - struct hmdfs_open_info *info = NULL; - - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - ret = -ENOMEM; - goto fail; - } - - read_len = (size_t)le32_to_cpu(recv->size); - if (read_len == 0) { - ret = -EINVAL; - goto fail_free_info; - } - resp_len = read_len + sizeof(*resp); - resp = vmalloc(resp_len); - if (!resp) { - ret = -ENOMEM; - goto fail_free_info; - } - - ret = hmdfs_do_readpages_open(con, cmd, recv, info, resp); - - vfree(resp); -fail_free_info: - kfree(info); -fail: - if (ret) - hmdfs_send_err_response(con, cmd, ret); -} - static bool need_rebuild_dcache(struct hmdfs_dcache_header *h, struct hmdfs_time_t time, unsigned int precision) diff --git a/fs/hmdfs/hmdfs_server.h b/fs/hmdfs/hmdfs_server.h index 740d06f8b3a5..e832c7ff85be 100644 --- a/fs/hmdfs/hmdfs_server.h +++ b/fs/hmdfs/hmdfs_server.h @@ -37,10 +37,6 @@ void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, void *data); void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, void *data); -void hmdfs_server_readpages(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data); -void hmdfs_server_readpages_open(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data); void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, void *data); -- Gitee