diff --git a/zdev/dracut/95zdev/parse-zdev.sh b/zdev/dracut/95zdev/parse-zdev.sh index 31979f8b..a87e0bcb 100644 --- a/zdev/dracut/95zdev/parse-zdev.sh +++ b/zdev/dracut/95zdev/parse-zdev.sh @@ -41,9 +41,19 @@ if [ $zdev_auto -eq 1 ] ; then chzdev --import "$zdev_fw_file" $zdev_base_args # Get information about DPM environment - for line in $($zdev_id) ; do - eval "$line" - done + tmp="/tmp/zdev_id.env" + if "$zdev_id" >"$tmp"; then + while IFS='=' read -r key val; do + case "$key" in + ZDEV_*) + val=${val#\"} + val=${val%\"} + export "$key=$val" + ;; + esac + done <"$tmp" + fi + rm -f "$tmp" if [ "$ZDEV_IS_DPM,$ZDEV_NEST_LEVEL,$ZDEV_HYPERVISOR_0" = "1,1,LPAR" ] ; then # Manually iterate over existing PCI devices - there is a udev rule diff --git a/zdev/include/sanitize.h b/zdev/include/sanitize.h new file mode 100644 index 00000000..764a65f5 --- /dev/null +++ b/zdev/include/sanitize.h @@ -0,0 +1,32 @@ +/* + * zdev - Modify and display the persistent configuration of devices + * + * Copyright IBM Corp. 2026 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#ifndef SANITIZE_H +#define SANITIZE_H + +#include +#include + +/* Valid control-program identifier special characters */ +#define VALID_CPNAME "/" + +static inline int is_safe_char(unsigned char c, const char *set) +{ + return isalnum(c) || strchr(set, c); +} + +static inline void sanitize(char *s, const char *set) +{ + for (; *s; s++) { + if (!is_safe_char((unsigned char)*s, set)) + *s = '_'; + } +} + +#endif /* SANITIZE_H */ diff --git a/zdev/src/zdev_id.c b/zdev/src/zdev_id.c index a98acdd8..e64066ec 100644 --- a/zdev/src/zdev_id.c +++ b/zdev/src/zdev_id.c @@ -13,6 +13,7 @@ #include #include +#include "sanitize.h" #include "zdev.h" #include "zdev_id.h" @@ -69,6 +70,7 @@ static void process_sysinfo(const char *filename) free(substr); } else if (sscanf(line, "VM%*d Control Program: %ms ", &substr) == 1) { + sanitize(substr, VALID_CPNAME); array_add(&cps, &num_cps, substr); free(substr); }