From 28b24332d95f2f7df44ec7e7a5e0025bcadc6277 Mon Sep 17 00:00:00 2001 From: Alon Zahavi Date: Tue, 28 Nov 2023 11:15:26 +0000 Subject: sys/linux, pkg/host, executor: add NVMe-oF/TCP subsystem support Add new pseudo-syscall for creating a socket in init netns and connecting to NVMe-oF/TCP server on 127.0.0.1:4420. Also add descriptions for NVMe-oF/TCP. --- executor/common_linux.h | 48 ++- pkg/csource/generated.go | 47 ++- pkg/host/syscalls_linux.go | 5 + sys/linux/socket_nvme_of_tcp.txt | 632 +++++++++++++++++++++++++++++++++ sys/linux/socket_nvme_of_tcp.txt.const | 70 ++++ sys/linux/test/nvme | 6 + sys/linux/test/nvme_h2c_pdu | 7 + 7 files changed, 811 insertions(+), 4 deletions(-) create mode 100644 sys/linux/socket_nvme_of_tcp.txt create mode 100644 sys/linux/socket_nvme_of_tcp.txt.const create mode 100644 sys/linux/test/nvme create mode 100644 sys/linux/test/nvme_h2c_pdu diff --git a/executor/common_linux.h b/executor/common_linux.h index 42d352a52..2f10ae3d6 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -730,7 +730,7 @@ static void initialize_tun(void) } #endif -#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI +#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI || __NR_syz_socket_connect_nvme_tcp const int kInitNetNsFd = 201; // see kMaxFd #endif @@ -2484,6 +2484,50 @@ static long syz_init_net_socket(volatile long domain, volatile long type, volati #endif #endif +#if SYZ_EXECUTOR || __NR_syz_socket_connect_nvme_tcp +#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE +#include +#include +#include +#include +#include +#include +#include +#include + +static long syz_socket_connect_nvme_tcp() +{ + struct sockaddr_in nvme_local_address; + int netns = open("/proc/self/ns/net", O_RDONLY); + if (netns == -1) + return netns; + if (setns(kInitNetNsFd, 0)) + return -1; + int sock = syscall(__NR_socket, AF_INET, SOCK_STREAM, 0x0); + int err = errno; + if (setns(netns, 0)) + fail("setns(netns) failed"); + close(netns); + errno = err; + // We only connect to an NVMe-oF/TCP server on 127.0.0.1:4420 + nvme_local_address.sin_family = AF_INET; + nvme_local_address.sin_port = htobe16(4420); + nvme_local_address.sin_addr.s_addr = htobe32(0x7f000001); + err = syscall(__NR_connect, sock, &nvme_local_address, sizeof(nvme_local_address)); + if (err != 0) { + close(sock); + return -1; + } + return sock; +} +#else +static long syz_socket_connect_nvme_tcp() +{ + return syscall(__NR_socket, -1, 0, 0); +} +#endif +#endif + #if SYZ_EXECUTOR || SYZ_VHCI_INJECTION #include #include @@ -3851,7 +3895,7 @@ static void sandbox_common() prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setsid(); -#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI +#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI || __NR_syz_socket_connect_nvme_tcp int netns = open("/proc/self/ns/net", O_RDONLY); if (netns == -1) fail("open(/proc/self/ns/net) failed"); diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index 60a1ff964..4c3fae47c 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -3365,7 +3365,7 @@ static void initialize_tun(void) } #endif -#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI +#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI || __NR_syz_socket_connect_nvme_tcp const int kInitNetNsFd = 201; #endif @@ -6296,6 +6296,49 @@ static long syz_init_net_socket(volatile long domain, volatile long type, volati #endif #endif +#if SYZ_EXECUTOR || __NR_syz_socket_connect_nvme_tcp +#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE +#include +#include +#include +#include +#include +#include +#include +#include + +static long syz_socket_connect_nvme_tcp() +{ + struct sockaddr_in nvme_local_address; + int netns = open("/proc/self/ns/net", O_RDONLY); + if (netns == -1) + return netns; + if (setns(kInitNetNsFd, 0)) + return -1; + int sock = syscall(__NR_socket, AF_INET, SOCK_STREAM, 0x0); + int err = errno; + if (setns(netns, 0)) + fail("setns(netns) failed"); + close(netns); + errno = err; + nvme_local_address.sin_family = AF_INET; + nvme_local_address.sin_port = htobe16(4420); + nvme_local_address.sin_addr.s_addr = htobe32(0x7f000001); + err = syscall(__NR_connect, sock, &nvme_local_address, sizeof(nvme_local_address)); + if (err != 0) { + close(sock); + return -1; + } + return sock; +} +#else +static long syz_socket_connect_nvme_tcp() +{ + return syscall(__NR_socket, -1, 0, 0); +} +#endif +#endif + #if SYZ_EXECUTOR || SYZ_VHCI_INJECTION #include #include @@ -9212,7 +9255,7 @@ static void sandbox_common() prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setsid(); -#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI +#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_DEVLINK_PCI || __NR_syz_socket_connect_nvme_tcp int netns = open("/proc/self/ns/net", O_RDONLY); if (netns == -1) fail("open(/proc/self/ns/net) failed"); diff --git a/pkg/host/syscalls_linux.go b/pkg/host/syscalls_linux.go index 7037dc001..b1bcbfb8b 100644 --- a/pkg/host/syscalls_linux.go +++ b/pkg/host/syscalls_linux.go @@ -230,6 +230,10 @@ func isSyzInitNetSocketSupported(c *prog.Syscall, target *prog.Target, sandbox s return isSupportedSocket(c) } +func isSyzSocketConnectNvmeTCPSupported(c *prog.Syscall, target *prog.Target, sandbox string) (bool, string) { + return onlySandboxNone(sandbox) +} + func isSyzGenetlinkGetFamilyIDSupported(c *prog.Syscall, target *prog.Target, sandbox string) (bool, string) { fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_GENERIC) if fd == -1 { @@ -322,6 +326,7 @@ var syzkallSupport = map[string]func(*prog.Syscall, *prog.Target, string) (bool, "syz_clone": alwaysSupported, "syz_clone3": alwaysSupported, "syz_pkey_set": isSyzPkeySetSupported, + "syz_socket_connect_nvme_tcp": isSyzSocketConnectNvmeTCPSupported, } func isSupportedSyzkall(c *prog.Syscall, target *prog.Target, sandbox string) (bool, string) { diff --git a/sys/linux/socket_nvme_of_tcp.txt b/sys/linux/socket_nvme_of_tcp.txt new file mode 100644 index 000000000..0d256fe37 --- /dev/null +++ b/sys/linux/socket_nvme_of_tcp.txt @@ -0,0 +1,632 @@ +# Copyright 2018 syzkaller project authors. All rights reserved. +# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +include +include +include +include +include +include + +######################################### +### Generic NVMe over TCP ### + +nvme_of_msg { + pdu nvme_tcp_pdu + payload optional[buffer[in]] +} [packed] + +nvme_tcp_pdu [ + icreq nvme_tcp_icreq_pdu + icresp nvme_tcp_icresp_pdu + cmd nvme_tcp_cmd_pdu + rsp nvme_tcp_rsp_pdu + r2t nvme_tcp_r2t_pdu + data_h2c nvme_tcp_data_pdu_h2c + data_h2c_hdigest nvme_tcp_data_pdu_h2c_hdigest + data_h2c_no_hdigest nvme_tcp_data_pdu_h2c_no_hdigest + data_c2h nvme_tcp_data_pdu_c2h +] + +type nvme_tcp_hdr_t_const[PDU_TYPE, HLEN_SIZE] { + type const[PDU_TYPE, int8] + flags flags[nvme_tcp_pdu_flags, int8] + hlen const[HLEN_SIZE, int8] + pdo int8 + plen int32 +} [packed] + +type nvme_tcp_hdr_t_const_pdo[PDU_TYPE, HLEN_SIZE, PDO_SIZE] { + type const[PDU_TYPE, int8] + flags flags[nvme_tcp_pdu_flags, int8] + hlen const[HLEN_SIZE, int8] + pdo const[PDO_SIZE, int8] + plen int32 +} [packed] + +type nvme_tcp_hdr_t_const_plen[PDU_TYPE, HLEN_SIZE, PLEN_SIZE] { + type const[PDU_TYPE, int8] + flags flags[nvme_tcp_pdu_flags, int8] + hlen const[HLEN_SIZE, int8] + pdo int8 + plen const[PLEN_SIZE, int32] +} [packed] + +nvme_tcp_pdu_flags = NVME_TCP_F_HDGST, NVME_TCP_F_DDGST, NVME_TCP_F_DATA_LAST, NVME_TCP_F_DATA_SUCCESS + +nvme_tcp_digest_option = NVME_TCP_HDR_DIGEST_ENABLE, NVME_TCP_DATA_DIGEST_ENABLE + +nvme_tcp_fatal_error_status = 0, NVME_TCP_FES_INVALID_PDU_HDR, NVME_TCP_FES_PDU_SEQ_ERR, NVME_TCP_FES_HDR_DIGEST_ERR, NVME_TCP_FES_DATA_OUT_OF_RANGE, NVME_TCP_FES_R2T_LIMIT_EXCEEDED, NVME_TCP_FES_DATA_LIMIT_EXCEEDED, NVME_TCP_FES_UNSUPPORTED_PARAM + +nvme_tcp_pfv = NVME_TCP_PFV_1_0 + +define NVME_TCP_DATA_PDU_SIZE sizeof(struct nvme_tcp_data_pdu) +define NVME_TCP_ICREQ_PDU_SIZE sizeof(struct nvme_tcp_icreq_pdu) +define NVME_TCP_CMD_PDU_SIZE sizeof(struct nvme_tcp_cmd_pdu) +define NVME_TCP_ICRESP_PDU_SIZE sizeof(struct nvme_tcp_icresp_pdu) + +define NVME_TCP_DISC_PORT 8009 +define NVME_TCP_ADMIN_CCSZ SZ_8K +define NVME_TCP_DIGEST_LENGTH 4 +define NVME_TCP_MIN_MAXH2CDATA 4096 + +### End of generic ### +######################################### + +######################################### +### nvme_tcp_data_pdu ### + +type nvme_tcp_data_pdu[HDR_TYPE] { + hdr HDR_TYPE + command_id int16 + ttag int16 + data_offset int32 + data_length int32 + rsvd array[int8, 4] +} [size[NVME_TCP_DATA_PDU_SIZE]] + +type nvme_tcp_hdr_data_pdu_h2c nvme_tcp_hdr_t_const[nvme_tcp_h2c_data, NVME_TCP_DATA_PDU_SIZE] +type nvme_tcp_data_pdu_h2c nvme_tcp_data_pdu[nvme_tcp_hdr_data_pdu_h2c] + +type nvme_tcp_hdr_data_pdu_h2c_hdigest nvme_tcp_hdr_t_const_pdo[nvme_tcp_h2c_data, NVME_TCP_DATA_PDU_SIZE, NVME_TCP_HDR_H2C_DIGEST_PDO_HDIGEST] +type nvme_tcp_data_pdu_h2c_hdigest nvme_tcp_data_pdu[nvme_tcp_hdr_data_pdu_h2c_hdigest] + +type nvme_tcp_hdr_data_pdu_h2c_no_hdigest nvme_tcp_hdr_t_const_pdo[nvme_tcp_h2c_data, NVME_TCP_DATA_PDU_SIZE, NVME_TCP_HDR_H2C_DIGEST_PDO_NO_HDIGEST] +type nvme_tcp_data_pdu_h2c_no_hdigest nvme_tcp_data_pdu[nvme_tcp_hdr_data_pdu_h2c_no_hdigest] + +type nvme_tcp_hdr_data_pdu_c2h nvme_tcp_hdr_t_const[nvme_tcp_c2h_data, NVME_TCP_DATA_PDU_SIZE] +type nvme_tcp_data_pdu_c2h nvme_tcp_data_pdu[nvme_tcp_hdr_data_pdu_c2h] + +define NVME_TCP_HDR_H2C_DIGEST_PDO_HDIGEST NVME_TCP_DATA_PDU_SIZE + NVME_TCP_DIGEST_LENGTH +define NVME_TCP_HDR_H2C_DIGEST_PDO_NO_HDIGEST NVME_TCP_DATA_PDU_SIZE +define NVME_TCP_HDR_H2C_DIGEST_PLEN_HDIGEST_DDIGEST NVME_TCP_HDR_H2C_DIGEST_PDO_HDIGEST + NVME_TCP_DIGEST_LENGTH + +### End of nvme_tcp_r2t_pdu ### +######################################### + +######################################### +### nvme_tcp_r2t_pdu ### + +nvme_tcp_r2t_pdu { + hdr nvme_tcp_hdr_r2t_pdu + command_id int16 + ttag int16 + r2t_offset int32 + r2t_length int32 + rsvd array[const[0, int8], 4] +} [size[NVME_TCP_DATA_PDU_SIZE]] + +type nvme_tcp_hdr_r2t_pdu nvme_tcp_hdr_t_const[nvme_tcp_r2t, NVME_TCP_DATA_PDU_SIZE] + +### End of nvme_tcp_r2t_pdu ### +######################################### + +######################################### +### nvme_tcp_rsp_pdu ### + +nvme_tcp_rsp_pdu { + hdr nvme_tcp_hdr_rsp_pdu + cqe nvme_completion +} [size[NVME_TCP_DATA_PDU_SIZE]] + +nvme_completion { + result nvme_result + sq_head int16 + sq_id int16 + command_id int16 + status flags[nvme_tcp_fatal_error_status, int16] +} [packed] + +nvme_result [ + u16 int16 + u32 int32 + u64 int64 +] + +type nvme_tcp_hdr_rsp_pdu nvme_tcp_hdr_t_const[nvme_tcp_rsp, NVME_TCP_DATA_PDU_SIZE] + +### End of nvme_tcp_rsp_pdu ### +######################################### + +######################################### +### nvme_tcp_icresp_pdu ### + +nvme_tcp_icresp_pdu { + hdr nvme_tcp_hdr_icresp_pdu + pfv flags[nvme_tcp_pfv, int16] +# Linux NVMe driver only support cpda = 0 + cpda const[0, int8] + digest flags[nvme_tcp_digest_option, int8] + maxdata int32 + rsvd array[const[0, int8], 112] +} [size[NVME_TCP_ICRESP_PDU_SIZE]] + +type nvme_tcp_hdr_icresp_pdu nvme_tcp_hdr_t_const[nvme_tcp_icresp, NVME_TCP_ICRESP_PDU_SIZE] + +### End of nvme_tcp_icresp_pdu ### +######################################### + +######################################### +### nvme_tcp_icreq_pdu ### + +nvme_tcp_icreq_pdu { + hdr nvme_tcp_hdr_icreq_pdu + pfv flags[nvme_tcp_pfv, int16] +# Linux NVMe driver only support hcpda = 0 + hpda const[0, int8] + digest flags[nvme_tcp_digest_option, int8] + maxr2t int32 + rsvd array[const[0, int8], 112] +} [size[NVME_TCP_ICREQ_PDU_SIZE]] + +type nvme_tcp_hdr_icreq_pdu nvme_tcp_hdr_t_const_plen[nvme_tcp_icreq, NVME_TCP_ICREQ_PDU_SIZE, NVME_TCP_ICREQ_PDU_SIZE] + +### End of nvme_tcp_icreq_pdu ### +######################################### + +######################################### +### nvme_tcp_cmd_pdu ### + +nvme_tcp_cmd_pdu { + hdr nvme_tcp_hdr_cmd_pdu + cmd nvme_command +} [size[NVME_TCP_CMD_PDU_SIZE]] + +type nvme_tcp_hdr_cmd_pdu nvme_tcp_hdr_t_const_plen[nvme_tcp_cmd, NVME_TCP_CMD_PDU_SIZE, NVME_TCP_CMD_PDU_SIZE] + +nvme_command { + anon_union nvme_command_union +} + +nvme_command_union [ + common nvme_common_command + rw nvme_rw_command + identify nvme_identify + features nvme_features + create_cq nvme_create_cq + create_sq nvme_create_sq + delete_queue nvme_delete_queue + dlfw nvme_download_firmware + format nvme_format_cmd + dsm nvme_dsm_cmd + write_zeroes nvme_write_zeroes_cmd + zms nvme_zone_mgmt_send_cmd + zmr nvme_zone_mgmt_recv_cmd + abort nvme_abort_cmd + fabrics nvmf_common_command + connect nvmf_connect_command + prop_set nvmf_property_set_command + prop_get nvmf_property_get_command + auth_common nvmf_auth_common_command + auth_send nvmf_auth_send_command + auth_receive nvmf_auth_receive_command + dbbuf nvme_dbbuf + directive nvme_directive_cmd + get_log_page nvme_get_log_page_command +] + +nvme_get_log_page_command { + opcode const[nvme_admin_get_log_page, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 array[const[0, int64], 2] + dptr nvme_data_ptr + lid int8 + lsp int8 + numdl int16 + numdu int16 + rsvd11 const[0, int16] + anon_union nvme_get_log_page_command_anon_union + rsvd14 array[const[0, int8], 3] + csi int8 + rsvd15 const[0, int32] +} + +nvme_get_log_page_command_anon_union [ + anon_struct nvme_get_log_page_command_anon_union_anon_struct + lpo int64 +] + +nvme_get_log_page_command_anon_union_anon_struct { + lpol int32 + lpou int32 +} + +nvme_download_firmware { + opcode const[nvme_admin_download_fw, int8] + flags int8 + command_id int16 + rsvd1 array[const[0, int32], 5] + dptr nvme_data_ptr + numd int32 + offset int32 + rsvd12 array[const[0, int32], 4] +} + +nvme_format_cmd { + opcode const[nvme_admin_format_nvm, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 array[const[0, int64], 4] + cdw10 int32 + rsvd11 array[const[0, int32], 5] +} + +nvme_dsm_cmd { + opcode const[nvme_cmd_dsm, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 array[const[0, int64], 2] + dptr nvme_data_ptr + nr int32 + attributes int32 + rsvd12 array[const[0, int32], 4] +} + +nvme_write_zeroes_cmd { + opcode const[nvme_cmd_write_zeroes, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 const[0, int64] + metadata int64 + dptr nvme_data_ptr + slba int64 + length int16 + control int16 + dsmgmt int32 + reftag int32 + apptag int16 + appmask int16 +} + +nvme_zone_mgmt_send_cmd { + opcode const[nvme_cmd_zone_mgmt_send, int8] + flags int8 + command_id int16 + nsid int32 + cdw2 array[int32, 2] + metadata int64 + dptr nvme_data_ptr + slba int64 + cdw12 int32 + zsa int8 + select_all int8 + rsvd13 array[const[0, int8], 2] + cdw14 array[int32, 2] +} + +nvme_zone_mgmt_recv_cmd { + opcode const[nvme_cmd_zone_mgmt_recv, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 array[const[0, int64], 2] + dptr nvme_data_ptr + slba int64 + numd int32 + zra int8 + zrasf int8 + pr int8 + rsvd13 const[0, int8] + cdw14 array[int32, 2] +} + +nvme_abort_cmd { + opcode const[nvme_admin_abort_cmd, int8] + flags int8 + command_id int16 + rsvd1 array[const[0, int32], 9] + sqid int16 + cid int16 + rsvd11 array[const[0, int32], 5] +} + +nvmf_common_command { + opcode const[nvme_fabrics_command, int8] + resv1 int8 + command_id int16 + fctype int8 + resv2 array[int8, 35] + ts array[int8, 24] +} + +nvmf_connect_command { + opcode const[nvme_fabrics_command, int8] + resv1 const[0x40, int8] + command_id const[0x0, int16] + fctype const[nvme_fabrics_type_connect, int8] + resv2 array[int8, 19] + dptr nvme_data_ptr + recfmt int16 + qid int16 + sqsize int16 + cattr int8 + resv3 int8 + kato int32 + resv4 array[int8, 12] +} + +nvmf_property_set_command { + opcode const[nvme_fabrics_command, int8] + resv1 int8 + command_id int16 + fctype const[nvme_fabrics_type_property_set, int8] + resv2 array[int8, 35] + attrib const[0x0, int8] + resv3 array[int8, 3] + offset int32 + value int64 + resv4 array[int8, 8] +} + +nvmf_property_get_command { + opcode const[nvme_fabrics_command, int8] + resv1 int8 + command_id int16 + fctype const[nvme_fabrics_type_property_get, int8] + resv2 array[int8, 35] + attrib int8 + resv3 array[int8, 3] + offset int32 + resv4 array[int8, 16] +} + +nvmf_auth_common_command { + opcode const[nvme_fabrics_command, int8] + resv1 int8 + command_id int16 + fctype int8 + resv2 array[int8, 19] + dptr nvme_data_ptr + resv3 int8 + spsp0 int8 + spsp1 int8 + secp int8 + al_tl int32 + resv4 array[int8, 16] +} + +nvmf_auth_send_command { + opcode const[nvme_fabrics_command, int8] + resv1 int8 + command_id int16 + fctype const[nvme_fabrics_type_auth_send, int8] + resv2 array[int8, 19] + dptr nvme_data_ptr + resv3 int8 + spsp0 flags[sps_flags, int8] + spsp1 flags[sps_flags, int8] + secp flags[secp_flags, int8] + tl int32 + resv4 array[int8, 16] +} + +secp_flags = NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER, 0x0 +sps_flags = 0x1, 0x2 + +nvmf_auth_receive_command { + opcode const[nvme_fabrics_command, int8] + resv1 int8 + command_id int16 + fctype const[nvme_fabrics_type_auth_receive, int8] + resv2 array[int8, 19] + dptr nvme_data_ptr + resv3 int8 + spsp0 flags[sps_flags, int8] + spsp1 flags[sps_flags, int8] + secp flags[secp_flags, int8] + al int32 + resv4 array[int8, 16] +} + +nvme_dbbuf { + opcode const[nvme_admin_dbbuf, int8] + flags int8 + command_id int16 + rsvd1 array[const[0, int32], 5] + prp1 int64 + prp2 int64 + rsvd12 array[const[0, int32], 6] +} + +nvme_directive_cmd { + opcode flags[nvme_admin_directive_opcodes, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 array[const[0, int64], 2] + dptr nvme_data_ptr + numd int32 + doper int8 + dtype int8 + dspec int16 + endir int8 + tdtype int8 + rsvd15 const[0, int16] + rsvd16 array[int32, 3] +} + +nvme_admin_directive_opcodes = nvme_admin_directive_send, nvme_admin_directive_recv +##################### +##################### + +nvme_delete_queue { + opcode const[nvme_admin_delete_cq, int8] + flags int8 + command_id int16 + rsvd1 array[const[0, int32], 9] + qid int16 + rsvd10 const[0, int16] + rsvd11 array[const[0, int32], 5] +} + +nvme_create_sq { + opcode const[nvme_admin_create_sq, int8] + flags int8 + command_id int16 + rsvd1 array[const[0, int32], 5] + prp1 int64 + rsvd8 const[0, int64] + sqid int16 + qsize int16 + sq_flags int16 + cqid int16 + rsvd12 array[const[0, int32], 4] +} + +nvme_create_cq { + opcode const[nvme_admin_create_cq, int8] + flags int8 + command_id int16 + rsvd1 array[const[0, int32], 5] + prp1 int64 + rsvd8 const[0, int64] + cqid int16 + qsize int16 + cq_flags int16 + irq_vector int16 + rsvd12 array[const[0, int32], 4] +} + +nvme_features { + opcode flags[nvme_features_opcodes, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 array[const[0, int64], 2] + dptr nvme_data_ptr + fid int32 + dword11 int32 + dword12 int32 + dword13 int32 + dword14 int32 + dword15 int32 +} + +nvme_features_opcodes = nvme_admin_set_features, nvme_admin_get_features + +nvme_identify { + opcode const[nvme_admin_identify, int8] + flags int8 + command_id int16 + nsid int32 + rsvd2 array[const[0, int64], 2] + dptr nvme_data_ptr + cns int8 + rsvd3 const[0, int8] + ctrlid int16 + rsvd11 array[const[0, int8], 3] + csi int8 + rsvd12 array[const[0, int32], 4] +} + +nvme_common_command { + opcode flags[nvme_common_command_opcodes, int8] + flags int8 + command_id int16 + nsid int32 + cdw2 array[int32, 2] + metadata int64 + dptr nvme_data_ptr + cdws cdws_struct_group +} + +nvme_common_command_opcodes = nvme_cmd_resv_report, nvme_fabrics_command, nvme_cmd_write, nvme_admin_async_event, nvme_cmd_flush, nvme_cmd_read, nvme_cmd_write_zeroes, nvme_cmd_dsm, nvme_admin_security_recv, nvme_admin_security_send, nvme_cmd_flush, nvme_admin_get_log_page, nvme_admin_identify, nvme_admin_abort_cmd, nvme_admin_set_features, nvme_admin_get_features, nvme_admin_async_event, nvme_admin_keep_alive + +cdws_struct_group [ + cdws_anon cdws_anon_struct + cdws cdws_anon_struct +] + +cdws_anon_struct { + cdw10 int32 + cdw11 int32 + cdw12 int32 + cdw13 int32 + cdw14 int32 + cdw15 int32 +} + +nvme_data_ptr [ + anon_struct nvme_data_ptr_anon_struct + sgl nvme_sgl_desc + ksgl nvme_keyed_sgl_desc +] + +nvme_data_ptr_anon_struct { + prp1 int64 + prp2 int64 +} [packed] + +nvme_sgl_desc { + addr int64 + length int32 + rsvd array[const[0, int8], 3] + type int8 +} [packed] + +nvme_keyed_sgl_desc { + addr int64 + length array[int8, 3] + key array[int8, 4] + type int8 +} [packed] + +nvme_rw_command { + opcode flags[nvme_opcodes_rw, int8] + flags int8 + command_id int16 + nsid int32 + cdw2 int32 + cdw3 int32 + metadata int64 + dptr nvme_data_ptr + slba int64 + length int16 + control int16 + dsmgmt int32 + reftag int32 + apptag int16 + appmask int16 +} + +nvme_opcodes_rw = nvme_cmd_write, nvme_cmd_read, nvme_cmd_zone_append + +### End of nvme_tcp_cmd_pdu ### +######################################### + +######################################### + +resource nvme_sock[sock] + +syz_socket_connect_nvme_tcp() nvme_sock + +sendto$inet_nvme_of_msg(fd nvme_sock, pdu ptr[in, nvme_of_msg], len len[pdu], f const[0], addr const[0], addrlen const[0]) +sendto$inet_nvme_pdu(fd nvme_sock, pdu ptr[in, nvme_tcp_pdu], len len[pdu], f const[0], addr const[0], addrlen const[0]) +sendto$inet_nvme_icreq_pdu(fd nvme_sock, pdu ptr[in, nvme_tcp_icreq_pdu], len len[pdu], f const[0], addr const[0], addrlen const[0]) +recvmsg$inet_nvme(fd nvme_sock, msg ptr[inout, recv_msghdr], f flags[recv_flags]) +recvfrom$inet_nvme(fd nvme_sock, buf buffer[out], len len[buf], f flags[recv_flags], addr ptr[in, sockaddr_storage, opt], addrlen len[addr]) diff --git a/sys/linux/socket_nvme_of_tcp.txt.const b/sys/linux/socket_nvme_of_tcp.txt.const new file mode 100644 index 000000000..2b0d5162e --- /dev/null +++ b/sys/linux/socket_nvme_of_tcp.txt.const @@ -0,0 +1,70 @@ +# Code generated by syz-sysgen. DO NOT EDIT. +arches = 386, amd64, arm, arm64, mips64le, ppc64le, riscv64, s390x +NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER = 233 +NVME_TCP_ADMIN_CCSZ = 8192 +NVME_TCP_CMD_PDU_SIZE = 72 +NVME_TCP_DATA_DIGEST_ENABLE = 2 +NVME_TCP_DATA_PDU_SIZE = 24 +NVME_TCP_DIGEST_LENGTH = 4 +NVME_TCP_DISC_PORT = 8009 +NVME_TCP_FES_DATA_LIMIT_EXCEEDED = 5 +NVME_TCP_FES_DATA_OUT_OF_RANGE = 4 +NVME_TCP_FES_HDR_DIGEST_ERR = 3 +NVME_TCP_FES_INVALID_PDU_HDR = 1 +NVME_TCP_FES_PDU_SEQ_ERR = 2 +NVME_TCP_FES_R2T_LIMIT_EXCEEDED = 5 +NVME_TCP_FES_UNSUPPORTED_PARAM = 6 +NVME_TCP_F_DATA_LAST = 4 +NVME_TCP_F_DATA_SUCCESS = 8 +NVME_TCP_F_DDGST = 2 +NVME_TCP_F_HDGST = 1 +NVME_TCP_HDR_DIGEST_ENABLE = 1 +NVME_TCP_HDR_H2C_DIGEST_PDO_HDIGEST = 28 +NVME_TCP_HDR_H2C_DIGEST_PDO_NO_HDIGEST = 24 +NVME_TCP_HDR_H2C_DIGEST_PLEN_HDIGEST_DDIGEST = 32 +NVME_TCP_ICREQ_PDU_SIZE = 128 +NVME_TCP_ICRESP_PDU_SIZE = 128 +NVME_TCP_MIN_MAXH2CDATA = 4096 +NVME_TCP_PFV_1_0 = 0 +__NR_recvfrom = 207, 386:s390x:371, amd64:45, arm:292, mips64le:5044, ppc64le:337 +__NR_recvmsg = 212, 386:s390x:372, amd64:47, arm:297, mips64le:5046, ppc64le:342 +__NR_sendto = 206, 386:s390x:369, amd64:44, arm:290, mips64le:5043, ppc64le:335 +nvme_admin_abort_cmd = 8 +nvme_admin_async_event = 12 +nvme_admin_create_cq = 5 +nvme_admin_create_sq = 1 +nvme_admin_dbbuf = 124 +nvme_admin_delete_cq = 4 +nvme_admin_directive_recv = 26 +nvme_admin_directive_send = 25 +nvme_admin_download_fw = 17 +nvme_admin_format_nvm = 128 +nvme_admin_get_features = 10 +nvme_admin_get_log_page = 2 +nvme_admin_identify = 6 +nvme_admin_keep_alive = 24 +nvme_admin_security_recv = 130 +nvme_admin_security_send = 129 +nvme_admin_set_features = 9 +nvme_cmd_dsm = 9 +nvme_cmd_flush = 0 +nvme_cmd_read = 2 +nvme_cmd_resv_report = 14 +nvme_cmd_write = 1 +nvme_cmd_write_zeroes = 8 +nvme_cmd_zone_append = 125 +nvme_cmd_zone_mgmt_recv = 122 +nvme_cmd_zone_mgmt_send = 121 +nvme_fabrics_command = 127 +nvme_fabrics_type_auth_receive = 6 +nvme_fabrics_type_auth_send = 5 +nvme_fabrics_type_connect = 1 +nvme_fabrics_type_property_get = 4 +nvme_fabrics_type_property_set = 0 +nvme_tcp_c2h_data = 7 +nvme_tcp_cmd = 4 +nvme_tcp_h2c_data = 6 +nvme_tcp_icreq = 0 +nvme_tcp_icresp = 1 +nvme_tcp_r2t = 9 +nvme_tcp_rsp = 5 diff --git a/sys/linux/test/nvme b/sys/linux/test/nvme new file mode 100644 index 000000000..65fbb2d4d --- /dev/null +++ b/sys/linux/test/nvme @@ -0,0 +1,6 @@ +# requires: arch=amd64 + +# This connects to an NVMe server on 127.0.0.1:4420 and then close the connection + +r0 = syz_socket_connect_nvme_tcp() +close(r0) \ No newline at end of file diff --git a/sys/linux/test/nvme_h2c_pdu b/sys/linux/test/nvme_h2c_pdu new file mode 100644 index 000000000..3a313ed31 --- /dev/null +++ b/sys/linux/test/nvme_h2c_pdu @@ -0,0 +1,7 @@ +# requires: arch=amd64 + +# This connects to an NVMe-oF/TCP server and sends an H2C PDU + +r0 = syz_socket_connect_nvme_tcp() +sendto$inet_nvme_pdu(r0, &(0x7f00000001c0)=@data_h2c={{0x6, 0x0, 0x18, 0x0, 0x0}, 0x0, 0x0, 0x1, 0x0, "cfbf3586"}, 0x80, 0x0, 0x0, 0x0) +close(r0) -- cgit mrf-deployment