From 87184510cd15131c1f75811ff402ec323bc0a570 Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Sun, 1 Mar 2026 10:24:35 +0100 Subject: [PATCH] Remove leaks noise with PCAPDROID_TRACK_ALLOCS --- app/src/main/jni/core/jni_impl.c | 6 +++++- app/src/main/jni/core/log_writer.c | 15 ++++++++------- app/src/main/jni/core/pcapdroid.c | 25 +++++++------------------ app/src/main/jni/core/pcapdroid.h | 3 ++- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/app/src/main/jni/core/jni_impl.c b/app/src/main/jni/core/jni_impl.c index 36b22e07..1e85d1fe 100644 --- a/app/src/main/jni/core/jni_impl.c +++ b/app/src/main/jni/core/jni_impl.c @@ -1092,6 +1092,9 @@ Java_com_emanuelef_remote_1capture_CaptureService_getL7Protocols(JNIEnv *env, jc int num_protos = (int) ndpi_get_num_protocols(ndpi); ndpi_proto_defaults_t* proto_defaults = ndpi_get_proto_defaults(ndpi); + struct ndpi_bitmask masterProtos; + init_ndpi_protocols_bitmask(&masterProtos); + struct ndpi_bitmask unique_protos; ndpi_bitmask_alloc(&unique_protos, num_protos); @@ -1106,7 +1109,7 @@ Java_com_emanuelef_remote_1capture_CaptureService_getL7Protocols(JNIEnv *env, jc memset(&n_proto, 0, sizeof(n_proto)); n_proto.proto.master_protocol = proto_defaults[i].protoId; n_proto.proto.app_protocol = NDPI_PROTOCOL_UNKNOWN; - uint16_t proto = pd_ndpi2proto(n_proto); + uint16_t proto = pd_ndpi2proto(&masterProtos, n_proto); //log_d("protos: %d -> %d -> %d", i, proto_defaults[i].protoId, proto); if(!ndpi_bitmask_is_set(&unique_protos, proto)) { @@ -1122,6 +1125,7 @@ Java_com_emanuelef_remote_1capture_CaptureService_getL7Protocols(JNIEnv *env, jc } out: + ndpi_bitmask_free(&masterProtos); ndpi_bitmask_free(&unique_protos); if(!success) { (*env)->DeleteLocalRef(env, plist); diff --git a/app/src/main/jni/core/log_writer.c b/app/src/main/jni/core/log_writer.c index 9a761c63..a45e33fc 100644 --- a/app/src/main/jni/core/log_writer.c +++ b/app/src/main/jni/core/log_writer.c @@ -5,6 +5,7 @@ struct log_writer; +// NOTE: don't use memtrack.h (e.g. pd_malloc), as loggers are never free static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static struct log_writer **loggers = NULL; static int num_loggers = 0; @@ -20,8 +21,8 @@ struct log_writer { static void pd_destroy_logger(struct log_writer *logger) { if(logger->f) fclose(logger->f); - pd_free(logger->path); - pd_free(logger); + free(logger->path); + free(logger); } void pd_close_loggers() { @@ -29,7 +30,7 @@ void pd_close_loggers() { for(int i=0; ilevel = min_lvl; - logger->path = pd_strdup(path); + logger->path = strdup(path); if(!logger->path) { - pd_free(logger); + free(logger); return -errno; } pthread_mutex_lock(&mutex); - loggers = pd_realloc(loggers, sizeof(void*) * (num_loggers + 1)); + loggers = realloc(loggers, sizeof(void*) * (num_loggers + 1)); if(!loggers) { pd_destroy_logger(logger); rv = -1; diff --git a/app/src/main/jni/core/pcapdroid.c b/app/src/main/jni/core/pcapdroid.c index 24758c3e..204b3bba 100644 --- a/app/src/main/jni/core/pcapdroid.c +++ b/app/src/main/jni/core/pcapdroid.c @@ -47,9 +47,6 @@ char *pd_appver = (char*) ""; char *pd_device = (char*) ""; char *pd_os = (char*) ""; -static struct ndpi_bitmask masterProtos; -static bool masterProtosInit = false; - /* ******************************************************* */ /* NOTE: these must be reset during each run, as android may reuse the service */ @@ -68,7 +65,7 @@ static void conn_free_ndpi(pd_conn_t *data) { /* ******************************************************* */ -uint16_t pd_ndpi2proto(ndpi_protocol nproto) { +uint16_t pd_ndpi2proto(const struct ndpi_bitmask *masterProtos, ndpi_protocol nproto) { // The nDPI master/app protocol logic is not clear (e.g. the first packet of a DNS flow has // master_protocol unknown whereas the second has master_protocol set to DNS). We are not interested // in the app protocols, so just take the one that's not unknown. @@ -78,14 +75,9 @@ uint16_t pd_ndpi2proto(ndpi_protocol nproto) { if((l7proto == NDPI_PROTOCOL_HTTP_CONNECT) || (l7proto == NDPI_PROTOCOL_HTTP_PROXY)) l7proto = NDPI_PROTOCOL_HTTP; - if(!masterProtosInit) { - init_ndpi_protocols_bitmask(&masterProtos); - masterProtosInit = true; - } - // nDPI will still return a disabled protocol (via the bitmask) if it matches some // metadata for it (e.g. the SNI) - if(!ndpi_bitmask_is_set(&masterProtos, l7proto)) + if(!ndpi_bitmask_is_set(masterProtos, l7proto)) l7proto = NDPI_PROTOCOL_UNKNOWN; //log_d("PROTO: %d/%d -> %d", proto.master_protocol, proto.app_protocol, l7proto); @@ -251,12 +243,6 @@ struct ndpi_detection_module_struct* init_ndpi() { return(NULL); } - // needed by pd_get_proto_name (must be after finalize) - if(!masterProtosInit) { - init_ndpi_protocols_bitmask(&masterProtos); - masterProtosInit = true; - } - #ifdef FUZZING ndpi_cache = ndpi; #endif @@ -574,7 +560,7 @@ void pd_giveup_dpi(pcapdroid_t *pd, pd_conn_t *data, const zdtun_5tuple_t *tuple if(data->l7proto == NDPI_PROTOCOL_UNKNOWN) { struct ndpi_proto n_proto = ndpi_detection_giveup(pd->ndpi, data->ndpi_flow); - data->l7proto = pd_ndpi2proto(n_proto); + data->l7proto = pd_ndpi2proto(&pd->masterProtos, n_proto); data->encrypted_l7 = is_encrypted_l7(pd->ndpi, data->l7proto); } @@ -744,7 +730,7 @@ static void perform_dpi(pcapdroid_t *pd, pkt_context_t *pctx) { uint16_t old_proto = data->l7proto; struct ndpi_proto n_proto = ndpi_detection_process_packet(pd->ndpi, data->ndpi_flow, (const u_char *)pkt->buf, pkt->len, data->last_seen, NULL); - data->l7proto = pd_ndpi2proto(n_proto); + data->l7proto = pd_ndpi2proto(&pd->masterProtos, n_proto); if(old_proto != data->l7proto) { data->update_type |= CONN_UPDATE_INFO; @@ -1242,6 +1228,7 @@ int pd_run(pcapdroid_t *pd) { log_f("nDPI initialization failed"); return(-1); } + init_ndpi_protocols_bitmask(&pd->masterProtos); pd->ip_to_host = ip_lru_init(MAX_HOST_LRU_SIZE); @@ -1333,6 +1320,8 @@ int pd_run(pcapdroid_t *pd) { ndpi_exit_detection_module(pd->ndpi); #endif + ndpi_bitmask_free(&pd->masterProtos); + if(pd->pcap_dump.dumper) stop_pcap_dump(pd); diff --git a/app/src/main/jni/core/pcapdroid.h b/app/src/main/jni/core/pcapdroid.h index 71e6469b..d0a243b6 100644 --- a/app/src/main/jni/core/pcapdroid.h +++ b/app/src/main/jni/core/pcapdroid.h @@ -205,6 +205,7 @@ typedef struct pcapdroid { int new_conn_id; uint64_t now_ms; // Monotonic timestamp, see pd_refresh_time struct ndpi_detection_module_struct *ndpi; + struct ndpi_bitmask masterProtos; zdtun_t *zdt; ip_lru_t *ip_to_host; conn_array_t new_conns; @@ -434,7 +435,7 @@ const char* get_file_path(pcapdroid_t *pd, const char *subpath); static inline const char* get_cache_dir(pcapdroid_t *pd) { return get_cache_path(pd, ""); } static inline const char* get_files_dir(pcapdroid_t *pd) { return get_file_path(pd, ""); } char* get_appname_by_uid(pcapdroid_t *pd, int uid, char *buf, int bufsize); -uint16_t pd_ndpi2proto(ndpi_protocol proto); +uint16_t pd_ndpi2proto(const struct ndpi_bitmask *masterProtos, ndpi_protocol proto); #ifdef ANDROID