diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 7ae7348ef3..a0540262e4 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -445,3 +445,21 @@ jobs: -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-dpdk_21.11 /odp/scripts/ci/check.sh - if: ${{ failure() }} uses: ./.github/actions/run-failure-log + + Run_sanitizer: + runs-on: ubuntu-20.04 + env: + OS: ubuntu_22.04 + strategy: + fail-fast: false + matrix: + flags: ['-fsanitize=address'] + steps: + - uses: actions/checkout@v4 + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}" + -e CFLAGS="-O0 -g -Wno-error ${{matrix.flags}}" + -e CXXFLAGS="-O0 -g -Wno-error ${{matrix.flags}}" + -e LDFLAGS="-g ${{matrix.flags}}" + $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh + - if: ${{ failure() }} + uses: ./.github/actions/run-failure-log diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index f4218fd9ce..a361bb1241 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -783,6 +783,8 @@ int main(int argc, char *argv[]) if (odp_pool_destroy(pool)) ODPH_ERR("err: odp_pool_destroy error\n"); + free(args->if_name); + args_error: odp_shm_free(shm); @@ -1281,9 +1283,7 @@ static int parse_args(int argc, char *argv[], appl_args_t *appl_args) if (ret) { usage(); - - if (appl_args->if_name) - free(appl_args->if_name); + free(appl_args->if_name); } /* reset optind from the getopt lib */ diff --git a/example/ipsec_api/odp_ipsec.c b/example/ipsec_api/odp_ipsec.c index a67a3a1e8c..b6cc9ee22c 100644 --- a/example/ipsec_api/odp_ipsec.c +++ b/example/ipsec_api/odp_ipsec.c @@ -45,6 +45,7 @@ #include #else static void init_stream_db(void) {} +static void deinit_stream_db(void) {} static void resolve_stream_db(void) {} static int create_stream_db_inputs(void) { @@ -1154,9 +1155,9 @@ main(int argc, char *argv[]) shm = odp_shm_lookup("shm_sp_db"); if (odp_shm_free(shm) != 0) ODPH_ERR("Error: shm free shm_sp_db failed\n"); - shm = odp_shm_lookup("stream_db"); - if (odp_shm_free(shm) != 0) - ODPH_ERR("Error: shm free stream_db failed\n"); + + deinit_stream_db(); + if (odp_shm_free(global->shm)) { ODPH_ERR("Error: shm free global data failed\n"); exit(EXIT_FAILURE); diff --git a/example/ipsec_crypto/odp_ipsec.c b/example/ipsec_crypto/odp_ipsec.c index 92e32d301a..490d2ad0ac 100644 --- a/example/ipsec_crypto/odp_ipsec.c +++ b/example/ipsec_crypto/odp_ipsec.c @@ -46,6 +46,7 @@ #include #else static void init_stream_db(void) {} +static void deinit_stream_db(void) {} static void resolve_stream_db(void) {} static int create_stream_db_inputs(void) { @@ -1437,9 +1438,9 @@ main(int argc, char *argv[]) shm = odp_shm_lookup("shm_sp_db"); if (odp_shm_free(shm) != 0) ODPH_ERR("Error: shm free shm_sp_db failed\n"); - shm = odp_shm_lookup("stream_db"); - if (odp_shm_free(shm) != 0) - ODPH_ERR("Error: shm free stream_db failed\n"); + + deinit_stream_db(); + if (odp_shm_free(global->shm)) { ODPH_ERR("Error: shm free global data failed\n"); exit(EXIT_FAILURE); diff --git a/example/ipsec_crypto/odp_ipsec_stream.c b/example/ipsec_crypto/odp_ipsec_stream.c index 330b4cc54c..505ee900bc 100644 --- a/example/ipsec_crypto/odp_ipsec_stream.c +++ b/example/ipsec_crypto/odp_ipsec_stream.c @@ -40,13 +40,14 @@ typedef struct ODP_PACKED stream_pkt_hdr_s { uint8_t data[]; /**< Incrementing data stream */ } stream_pkt_hdr_t; +static const char *shm_name = "stream_db"; stream_db_t *stream_db; void init_stream_db(void) { odp_shm_t shm; - shm = odp_shm_reserve("stream_db", + shm = odp_shm_reserve(shm_name, sizeof(stream_db_t), ODP_CACHE_LINE_SIZE, 0); @@ -65,6 +66,28 @@ void init_stream_db(void) memset(stream_db, 0, sizeof(*stream_db)); } +void deinit_stream_db(void) +{ + stream_db_entry_t *stream = NULL; + + for (stream = stream_db->list; NULL != stream; stream = stream->next) { + free(stream->input.intf); + free(stream->output.intf); + } + + odp_shm_t shm = odp_shm_lookup(shm_name); + + if (shm == ODP_SHM_INVALID) { + ODPH_ERR("Error: shared mem not found.\n"); + exit(EXIT_FAILURE); + } + + if (odp_shm_free(shm)) { + ODPH_ERR("Error: shared mem free failed.\n"); + exit(EXIT_FAILURE); + } +} + int create_stream_db_entry(char *input) { int pos = 0; diff --git a/example/ipsec_crypto/odp_ipsec_stream.h b/example/ipsec_crypto/odp_ipsec_stream.h index 8e1e936dd6..c6bbb618b0 100644 --- a/example/ipsec_crypto/odp_ipsec_stream.h +++ b/example/ipsec_crypto/odp_ipsec_stream.h @@ -31,14 +31,14 @@ typedef struct stream_db_entry_s { uint32_t verified; /**< Number successfully verified */ const EVP_MD *evp_md; /**< Digest method */ struct { - const char *intf; /**< Input interface name */ + char *intf; /**< Input interface name */ odp_pktio_t pktio; /**< Input PktI/O interface */ uint32_t ah_seq; /**< AH sequence number if present */ uint32_t esp_seq; /**< ESP sequence number if present */ ipsec_cache_entry_t *entry; /**< IPsec to apply on input */ } input; struct { - const char *intf; /**< Output interface name */ + char *intf; /**< Output interface name */ odp_pktio_t pktio; /**< Output PktI/O interface */ ipsec_cache_entry_t *entry; /**t IPsec to verify on output */ } output; @@ -58,6 +58,9 @@ extern stream_db_t *stream_db; /** Initialize stream database global control structure */ void init_stream_db(void); +/** Deinitialize stream database global control structure */ +void deinit_stream_db(void); + /** * Create an stream DB entry * diff --git a/example/simple_pipeline/odp_simple_pipeline.c b/example/simple_pipeline/odp_simple_pipeline.c index ad80bc3947..3a05bf1c5b 100644 --- a/example/simple_pipeline/odp_simple_pipeline.c +++ b/example/simple_pipeline/odp_simple_pipeline.c @@ -922,6 +922,9 @@ int main(int argc, char **argv) odph_thread_join(thr_tbl, num_threads); + free(global->appl.if_names); + free(global->appl.if_str); + if (odp_pktio_close(global->if0)) { printf("Error: failed to close interface %s\n", argv[1]); exit(EXIT_FAILURE); diff --git a/helper/Makefile.am b/helper/Makefile.am index 6e1ce583f1..f7685a2218 100644 --- a/helper/Makefile.am +++ b/helper/Makefile.am @@ -82,7 +82,7 @@ __LIB__libodphelper_la_LIBADD += $(LIBCLI_LIBS) lib_LTLIBRARIES = $(LIB)/libodphelper.la -CHECK_GLOBALS_REGEX = " (odph_|_deprecated_odph_)" +CHECK_GLOBALS_REGEX = " (odph_|_deprecated_odph_|__odr_asan)" TESTS_ENVIRONMENT = \ LIBTOOL="$(LIBTOOL)" \ diff --git a/helper/hashtable.c b/helper/hashtable.c index 28c23a58c8..4aa0c3f8bf 100644 --- a/helper/hashtable.c +++ b/helper/hashtable.c @@ -36,7 +36,7 @@ typedef struct odph_hash_node { * Its length is key_size + value_size, * suppose key_size = m; value_size = n; * its structure is like: - * k_byte1 k_byte2...k_byten v_byte1...v_bytem + * k_byte1 k_byte2...k_bytem v_byte1...v_byten */ char content[]; } odph_hash_node; diff --git a/helper/test/table.c b/helper/test/table.c index fb17e8a370..59a572818e 100644 --- a/helper/test/table.c +++ b/helper/test/table.c @@ -5,22 +5,6 @@ #include #include -/** - * Address Resolution Protocol (ARP) - * Description: Once a route has been identified for an IP packet (so the - * output interface and the IP address of the next hop station are known), - * the MAC address of the next hop station is needed in order to send this - * packet onto the next leg of the journey towards its destination - * (as identified by its destination IP address). The MAC address of the next - * hop station becomes the destination MAC address of the outgoing - * Ethernet frame. - * Hash table name: ARP table - * Number of keys: Thousands - * Key format: The pair of (Output interface, Next Hop IP address), - * which is typically 5 bytes for IPv4 and 17 bytes for IPv6. - * value (data): MAC address of the next hop station (6 bytes). - */ - int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) { odp_instance_t instance; @@ -29,13 +13,13 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) odph_table_t tmp_tbl; odph_table_ops_t *test_ops; char tmp[32]; - char ip_addr1[] = "12345678"; - char ip_addr2[] = "11223344"; - char ip_addr3[] = "55667788"; - char mac_addr1[] = "0A1122334401"; - char mac_addr2[] = "0A1122334402"; - char mac_addr3[] = "0B4433221101"; - char mac_addr4[] = "0B4433221102"; + char key1[] = "1234"; + char key2[] = "1122"; + char key3[] = "3344"; + char value1[] = "0A1122334401"; + char value2[] = "0A1122334402"; + char value3[] = "0B4433221101"; + char value4[] = "0B4433221102"; ret = odp_init_global(&instance, NULL, NULL); if (ret != 0) { @@ -51,49 +35,49 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) printf("test hash table:\n"); test_ops = &odph_hash_table_ops; - table = test_ops->f_create("test", 2, 4, 16); + table = test_ops->f_create("test", 2, sizeof(key1), sizeof(value1)); if (table == NULL) { printf("table create fail\n"); return -1; } - ret += test_ops->f_put(table, &ip_addr1, mac_addr1); + ret += test_ops->f_put(table, &key1, value1); - ret += test_ops->f_put(table, &ip_addr2, mac_addr2); + ret += test_ops->f_put(table, &key2, value2); - ret += test_ops->f_put(table, &ip_addr3, mac_addr3); + ret += test_ops->f_put(table, &key3, value3); if (ret != 0) { printf("put value fail\n"); return -1; } - ret = test_ops->f_get(table, &ip_addr1, &tmp, 32); + ret = test_ops->f_get(table, &key1, &tmp, 32); if (ret != 0) { printf("get value fail\n"); return -1; } printf("\t1 get '123' tmp = %s,\n", tmp); - ret = test_ops->f_put(table, &ip_addr1, mac_addr4); + ret = test_ops->f_put(table, &key1, value4); if (ret != 0) { printf("repeat put value fail\n"); return -1; } - ret = test_ops->f_get(table, &ip_addr1, &tmp, 32); - if (ret != 0 || strcmp(tmp, mac_addr4) != 0) { + ret = test_ops->f_get(table, &key1, &tmp, 32); + if (ret != 0 || memcmp(tmp, value4, sizeof(value4)) != 0) { printf("get value fail\n"); return -1; } printf("\t2 repeat get '123' value = %s\n", tmp); - ret = test_ops->f_remove(table, &ip_addr1); + ret = test_ops->f_remove(table, &key1); if (ret != 0) { printf("remove value fail\n"); return -1; } - ret = test_ops->f_get(table, &ip_addr1, tmp, 32); + ret = test_ops->f_get(table, &key1, tmp, 32); if (ret == 0) { printf("remove value fail actually\n"); return -1; diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 2b0d436d94..d1d4828490 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -492,7 +492,7 @@ if ODP_PKTIO_PCAP __LIB__libodp_linux_la_LIBADD += $(PCAP_LIBS) endif -CHECK_GLOBALS_REGEX = " (odp_|_odp_|_deprecated_odp_|miniz_|mz_|tdefl_|tinfl_|mp_hdlr_init_odp_pool_ops)" +CHECK_GLOBALS_REGEX = " (odp_|_odp_|_deprecated_odp_|miniz_|mz_|tdefl_|tinfl_|mp_hdlr_init_odp_pool_ops|__odr_asan)" TESTS_ENVIRONMENT = \ LIBTOOL="$(LIBTOOL)" \ diff --git a/platform/linux-generic/example/ml/mnist.c b/platform/linux-generic/example/ml/mnist.c index 4c10663026..28720a3fdb 100644 --- a/platform/linux-generic/example/ml/mnist.c +++ b/platform/linux-generic/example/ml/mnist.c @@ -56,8 +56,8 @@ static int read_digit_csv(const char *file_name, uint8_t *expected_digit, float size = ftell(digit_file); rewind(digit_file); - tmp = malloc(size); - memset(tmp, 0, size); + tmp = malloc(size + 1); + memset(tmp, 0, size + 1); num_elem = fread(tmp, size, 1, digit_file); fclose(digit_file); diff --git a/platform/linux-generic/example/ml/model_explorer.c b/platform/linux-generic/example/ml/model_explorer.c index bd449b032d..408b96c039 100644 --- a/platform/linux-generic/example/ml/model_explorer.c +++ b/platform/linux-generic/example/ml/model_explorer.c @@ -73,6 +73,11 @@ int main(int argc, char *argv[]) odp_ml_model_print(ml_model); + if (odp_ml_model_destroy(ml_model)) { + printf("odp_ml_model_destroy failed.\n"); + ret = -1; + } + odp_term: if (odp_term_local()) { printf("Local term failed.\n"); diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index cddd46591e..b28e638906 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -1435,7 +1435,7 @@ static int dpdk_pktio_init(void) if (numa_nodes <= 0) numa_nodes = 1; - char mem_str[mem_str_len * numa_nodes]; + char mem_str[mem_str_len * numa_nodes + 1]; for (i = 0; i < numa_nodes; i++) sprintf(&mem_str[i * mem_str_len], "%d,", DPDK_MEMORY_MB); diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c index fe689a9ae9..02b4d467a9 100644 --- a/platform/linux-generic/pktio/pcap.c +++ b/platform/linux-generic/pktio/pcap.c @@ -193,10 +193,12 @@ static int pcapif_promisc_mode_set(pktio_entry_t *pktio_entry, } if (pcap_setfilter(pcap->rx, &bpf) != 0) { + pcap_freecode(&bpf); _ODP_ERR("failed to set promisc mode filter: %s\n", pcap_geterr(pcap->rx)); return -1; } + pcap_freecode(&bpf); pcap->promisc = enable; return 0; diff --git a/test/performance/odp_l2fwd_run.sh b/test/performance/odp_l2fwd_run.sh index d2d6cc28d8..ae5bdef186 100755 --- a/test/performance/odp_l2fwd_run.sh +++ b/test/performance/odp_l2fwd_run.sh @@ -71,17 +71,10 @@ run_l2fwd() GEN_PID=$! - # this just turns off output buffering so that you still get periodic - # output while piping to tee, as long as stdbuf is available. - if [ "$(which stdbuf)" != "" ]; then - STDBUF="stdbuf -o 0" - else - STDBUF= - fi LOG=odp_l2fwd_tmp.log # Max 2 workers - $STDBUF odp_l2fwd${EXEEXT} -i $IF1,$IF2 -m 0 -t 5 -c 2 | tee $LOG + odp_l2fwd${EXEEXT} -i $IF1,$IF2 -m 0 -t 5 -c 2 | tee $LOG ret=${PIPESTATUS[0]} kill -2 ${GEN_PID} diff --git a/test/performance/odp_pktio_ordered_run.sh b/test/performance/odp_pktio_ordered_run.sh index 010bbb3212..017c970915 100755 --- a/test/performance/odp_pktio_ordered_run.sh +++ b/test/performance/odp_pktio_ordered_run.sh @@ -19,15 +19,7 @@ if [ ! -f ${PCAP_IN} ]; then exit 1 fi -# This just turns off output buffering so that you still get periodic -# output while piping to tee, as long as stdbuf is available. -if [ "$(which stdbuf)" != "" ]; then - STDBUF="stdbuf -o 0" -else - STDBUF= -fi - -$STDBUF ${TEST_DIR}/odp_pktio_ordered${EXEEXT} \ +${TEST_DIR}/odp_pktio_ordered${EXEEXT} \ -i pcap:in=${PCAP_IN}:loops=$LOOPS,pcap:out=${PCAP_OUT} \ -t $DURATION | tee $LOG ret=${PIPESTATUS[0]} diff --git a/test/validation/api/traffic_mngr/traffic_mngr.c b/test/validation/api/traffic_mngr/traffic_mngr.c index f0f7039a6d..ca44c59a29 100644 --- a/test/validation/api/traffic_mngr/traffic_mngr.c +++ b/test/validation/api/traffic_mngr/traffic_mngr.c @@ -65,7 +65,8 @@ #define MAX_PKTS 1000u #define PKT_BUF_SIZE 1460 -#define MAX_PAYLOAD 1400 +#define MIN_HDR_LEN (ODPH_ETHHDR_LEN + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN) +#define MAX_PAYLOAD (PKT_BUF_SIZE - MIN_HDR_LEN) #define USE_IPV4 false #define USE_IPV6 true #define USE_UDP false @@ -799,6 +800,12 @@ static odp_packet_t make_pkt(odp_pool_t pkt_pool, uint8_t *buf, *pkt_class_ptr, next_hdr; int rc; + if (payload_len > MAX_PAYLOAD) { + ODPH_ERR("packet payload length of %u exceeds MAX_PAYLOAD of %u\n", + payload_len, MAX_PAYLOAD); + return ODP_PACKET_INVALID; + } + l4_hdr_len = pkt_info->use_tcp ? ODPH_TCPHDR_LEN : ODPH_UDPHDR_LEN; l3_hdr_len = pkt_info->use_ipv6 ? ODPH_IPV6HDR_LEN : ODPH_IPV4HDR_LEN; vlan_hdr_len = pkt_info->use_vlan ? ODPH_VLANHDR_LEN : 0;