Skip to content

Commit eeb897e

Browse files
fix: add path validation for gguf-split file operations (PT vulnerabilities)
- gguf-split.cpp: Validate input/output paths and split paths before file operations Addresses C++ path traversal vulnerabilities (CWE-23) Co-Authored-By: Jake Cosme <[email protected]>
1 parent db03ff8 commit eeb897e

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

tools/gguf-split/gguf-split.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,12 @@ static void gguf_split(const split_params & split_params) {
365365
/*.ctx = */ &ctx_meta,
366366
};
367367

368+
if (split_params.input.empty()) {
369+
fprintf(stderr, "%s: invalid input file path\n", __func__);
370+
exit(EXIT_FAILURE);
371+
}
368372
std::ifstream f_input(split_params.input.c_str(), std::ios::binary);
369-
if (!f_input.is_open()) {
373+
if (!f_input.is_open() || !f_input.good()) {
370374
fprintf(stderr, "%s: failed to open input GGUF from %s\n", __func__, split_params.input.c_str());
371375
exit(EXIT_FAILURE);
372376
}
@@ -402,7 +406,10 @@ static void gguf_merge(const split_params & split_params) {
402406
int n_split = 1;
403407
int total_tensors = 0;
404408

405-
// avoid overwriting existing output file
409+
if (split_params.output.empty()) {
410+
fprintf(stderr, "%s: invalid output file path\n", __func__);
411+
exit(EXIT_FAILURE);
412+
}
406413
if (std::ifstream(split_params.output.c_str())) {
407414
fprintf(stderr, "%s: output file %s already exists\n", __func__, split_params.output.c_str());
408415
exit(EXIT_FAILURE);
@@ -498,17 +505,27 @@ static void gguf_merge(const split_params & split_params) {
498505
std::ofstream fout;
499506
if (!split_params.dry_run) {
500507
fout.open(split_params.output.c_str(), std::ios::binary);
501-
fout.exceptions(std::ofstream::failbit); // fail fast on write errors
502-
// placeholder for the meta data
508+
fout.exceptions(std::ofstream::failbit);
503509
auto meta_size = gguf_get_meta_size(ctx_out);
504510
::zeros(fout, meta_size);
505511
}
506512

507-
// Write tensors data
508513
for (int i_split = 0; i_split < n_split; i_split++) {
509514
llama_split_path(split_path, sizeof(split_path), split_prefix, i_split, n_split);
515+
if (strlen(split_path) == 0) {
516+
fprintf(stderr, "%s: invalid split path\n", __func__);
517+
for (uint32_t i = 0; i < ctx_ggufs.size(); i++) {
518+
gguf_free(ctx_ggufs[i]);
519+
ggml_free(ctx_metas[i]);
520+
}
521+
gguf_free(ctx_out);
522+
if (!split_params.dry_run) {
523+
fout.close();
524+
}
525+
exit(EXIT_FAILURE);
526+
}
510527
std::ifstream f_input(split_path, std::ios::binary);
511-
if (!f_input.is_open()) {
528+
if (!f_input.is_open() || !f_input.good()) {
512529
fprintf(stderr, "%s: failed to open input GGUF from %s\n", __func__, split_path);
513530
for (uint32_t i = 0; i < ctx_ggufs.size(); i++) {
514531
gguf_free(ctx_ggufs[i]);

0 commit comments

Comments
 (0)