From 307c10773b030638607d121fd7d8d9a027f18629 Mon Sep 17 00:00:00 2001 From: "Antonio M. Ferreira, Ph.D." Date: Wed, 8 Jul 2026 11:46:16 -0600 Subject: [PATCH] fix: heap overflows in mdpocket arg-copy, fparams, energy grid output Three heap-buffer-overflow fixes on the 4.2.3 release baseline: * src/mdparams.c:135 (get_mdpocket_args): my_malloc(sizeof(args[i])) only allocates sizeof(char*)=8 bytes, then strcpy copies the whole argv element. Any argv token > 7 chars (always true for argv[0], the program path) overruns the heap. Deterministic, input-independent: aborts even on 'mdpocket -h'. Manifests as glibc 'malloc(): corrupted top size' on glibc 2.35 (undetected on 2.39, where it silently corrupts). Fix: allocate strlen(args[i]) + 1. Located via AddressSanitizer; not addressed by upstream #180 (fix_overflow, which fixed writepocket.c). * src/fparams.c (get_fpocket_args): 'char *residue_string[N]' should be 'char residue_string[N]', and strcpy(&residue_string, ...) should target the array. Matches the fix conda-forge already carries as a feedstock patch. * src/energy.c:99,104 (calculate_pocket_energy_grids): sprintf into a fixed char[350] can write up to 384 bytes for long output paths. Use snprintf bounded by sizeof(final_path). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/energy.c | 4 ++-- src/fparams.c | 4 ++-- src/mdparams.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/energy.c b/src/energy.c index a5a7c777..324ec80e 100644 --- a/src/energy.c +++ b/src/energy.c @@ -96,12 +96,12 @@ void calculate_pocket_energy_grids(c_lst_pockets *pockets, s_fparams *params, s_ - sprintf(final_path, "%s/pockets/pocket_%d_vdw.dx", out_path, pocket_number); + snprintf(final_path, sizeof(final_path), "%s/pockets/pocket_%d_vdw.dx", out_path, pocket_number); f_vdw = fopen(final_path, "w"); write_grid(pocket_vdw_grid, f_vdw); fclose(f_vdw); - sprintf(final_path, "%s/pockets/pocket_%d_elec.dx", out_path, pocket_number); + snprintf(final_path, sizeof(final_path), "%s/pockets/pocket_%d_elec.dx", out_path, pocket_number); f_elec = fopen(final_path, "w"); write_grid(pocket_elec_grid, f_elec); fclose(f_elec); diff --git a/src/fparams.c b/src/fparams.c index feea5100..8ee306f8 100644 --- a/src/fparams.c +++ b/src/fparams.c @@ -122,7 +122,7 @@ s_fparams *get_fpocket_args(int nargs, char **args) opterr = 0; char *pt; char *apt; - char *residue_string[M_MAX_CUSTOM_POCKET_LEN]; + char residue_string[M_MAX_CUSTOM_POCKET_LEN]; short custom_ligand_i = 0; const char *separators = ",:"; static struct option fplong_options[] = {/*long options args located in fparams.h*/ @@ -293,7 +293,7 @@ s_fparams *get_fpocket_args(int nargs, char **args) rest = par->custom_pocket_arg; while ((pt = strtok_r(rest, ".", &rest))) { - strcpy(&residue_string, pt); + strcpy(residue_string, pt); rest2 = residue_string; apti = 0; while ((apt = strtok_r(rest2, ":", &rest2))) diff --git a/src/mdparams.c b/src/mdparams.c index ea50170e..f671dc4a 100644 --- a/src/mdparams.c +++ b/src/mdparams.c @@ -132,7 +132,7 @@ s_mdparams* get_mdpocket_args(int nargs, char **args) { char *str_list_file = NULL; char **args_copy = my_malloc(sizeof (char**) *nargs); for (i = 0; i < nargs; i++) { - args_copy[i] = my_malloc(sizeof (args[i])); + args_copy[i] = my_malloc(strlen(args[i]) + 1); strcpy(args_copy[i], args[i]); }