zdump/ngdump: Perform sanity checks on path to dump image

Ensure that the path to a dump image specified in the NGDump meta file
of a dump device points to a valid location within the dump device.
Especially, disallow escaping from a dump device with a dump image path
using references to '..' or symbolic links pointing outside of the dump
device.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Alexander Egorenkov
2026-07-01 10:23:47 +02:00
committed by Jan Höppner
parent 6c6938d1e2
commit 1f68c1aaf3
3 changed files with 52 additions and 6 deletions

View File

@@ -32,6 +32,7 @@ static int open_dump_file(void)
{
char *mount_point = NULL;
char *filename = NULL;
int rc;
mount_point = util_strdup("/tmp/zdump-ngdump-XXXXXX");
@@ -46,7 +47,11 @@ static int open_dump_file(void)
goto fail_rmdir;
}
util_asprintf(&filename, "%s/%s", mount_point, l.meta.file);
rc = ngdump_get_dump_path(mount_point, &l.meta, &filename);
if (rc) {
warnx("Could not resolve path to dump file \"%s\"", l.meta.file);
goto fail_rmdir;
}
g.fh = zg_open(filename, O_RDONLY, ZG_CHECK);
free(filename);

View File

@@ -223,12 +223,10 @@ static int validate_meta(const char *mount_point, struct ngdump_meta *meta)
return -1;
}
util_asprintf(&filename, "%s/%s", mount_point, meta->file);
rc = access(filename, R_OK);
rc = ngdump_get_dump_path(mount_point, meta, &filename);
if (rc) {
warnx("Could not access dump file \"%s\"", meta->file);
goto out;
warnx("Could not resolve path to dump file \"%s\"", meta->file);
return -1;
}
rc = check_sha256sum(filename, meta->sha256sum);
@@ -608,3 +606,43 @@ int ngdump_get_dump_part(struct zg_fh *zg_fh, char **part_path)
return part_num;
}
int ngdump_get_dump_path(const char *mount_point,
const struct ngdump_meta *meta,
char **path)
{
char *filename = NULL;
char *real_path;
int rc;
util_asprintf(&filename, "%s/%s", mount_point, meta->file);
util_log_print(UTIL_LOG_DEBUG, "%s: Dump path %s\n",
__func__, filename);
real_path = realpath(filename, NULL);
free(filename);
if (!real_path)
return -1;
util_log_print(UTIL_LOG_DEBUG, "%s: Real dump path %s\n",
__func__, real_path);
/* Disallow escaping from a dump device with a relative path or
symbolic link. */
if (strncmp(mount_point, real_path, strlen(mount_point)) != 0)
goto fail_free_real_path;
rc = access(real_path, R_OK);
if (rc)
goto fail_free_real_path;
*path = real_path;
return 0;
fail_free_real_path:
free(real_path);
return -1;
}

View File

@@ -31,5 +31,8 @@ int ngdump_read_meta_from_device(const char *device, struct ngdump_meta *meta);
int ngdump_get_dump_part(struct zg_fh *zg_fh, char **part_path);
int ngdump_get_part_path(const char *disk_path, int part_num,
enum ngdump_disk_type ng_type, char **part_path);
int ngdump_get_dump_path(const char *mount_point,
const struct ngdump_meta *meta,
char **path);
#endif /* ZGETDUMP_NGDUMP_H */