fix(kubernetes): refuse non-ASCII kernelModules parameters

RE2's \s and [:cntrl:] only cover ASCII, so the parameter deny class
passed U+2028 and U+2029. toYaml writes either one raw, and Helm's YAML
parser reads it as a line break that ends the reconcile Job's command
block scalar early. The render then failed on an unparseable manifest
rather than on the guard, which is the last check before the unquoted
heredoc.

Pinning parameters to printable ASCII closes every non-ASCII line break
at once, and the deny class keeps refusing what the heredoc expands.

Assisted-by: LLM
Signed-off-by: Mattia Eleuteri <mattia@hidora.io>
This commit is contained in:
Mattia Eleuteri committed 2026-09-29 17:35:49 +02:00
1 parent f7c04b7a39
commit 91c87b84cd
2 files changed
+36 -2

No files matched your search

@@ -129,8 +129,14 @@ the open-kernel-modules extension, since the proprietary one loads, creates
{{- $params := list -}}
{{- range .parameters | default list -}}
{{- $param := . | toString -}}
{{- if not (regexMatch `^[^[:cntrl:]\s$\x60\\'\"]+$` $param) -}}
{{- fail (printf "nodeGroup %q: invalid kernelModules parameter %q on module %q — must not contain $, a backtick, a backslash, quotes, whitespace or control characters (e.g. NVreg_EnableGpuFirmware=1, or the semicolon-separated NVreg_RegistryDwords=PowerMizerEnable=0x1;PerfLevelSrc=0x2222)" $groupName $param $name) -}}
{{- /* Two checks, because RE2's `\s` and `[:cntrl:]` are ASCII-only: a deny class
built from them lets U+2028 and U+2029 through, `toYaml` writes either raw,
and Helm's YAML parser reads it as a line break that ends the Job's
`command` block scalar early. `[:graph:]` pins the parameter to printable
ASCII, which closes every non-ASCII break at once; the second check then
removes what the heredoc would expand. */ -}}
{{- if not (and (regexMatch `^[[:graph:]]+$` $param) (regexMatch `^[^$\x60\\'\"]+$` $param)) -}}
{{- fail (printf "nodeGroup %q: invalid kernelModules parameter %q on module %q — must be printable ASCII with no whitespace, and must not contain $, a backtick, a backslash or quotes (e.g. NVreg_EnableGpuFirmware=1, or the semicolon-separated NVreg_RegistryDwords=PowerMizerEnable=0x1;PerfLevelSrc=0x2222)" $groupName $param $name) -}}
{{- end -}}
{{- $params = append $params $param -}}
{{- end -}}
@@ -171,6 +171,34 @@ tests:
- failedTemplate:
errorPattern: 'invalid kernelModules parameter'
# RE2's `\s` and `[:cntrl:]` are ASCII-only, so a deny class built from them
# alone passes U+2028 and U+2029. `toYaml` writes either raw inside a quoted
# scalar, and Helm's YAML parser reads it as a line break that ends the Job's
# `command` block scalar early and hands what follows to the manifest parser.
# The refusal has to come from the guard, not from that manifest happening not
# to parse, so these assert the kernelModules message rather than any failure.
- it: rejects a module parameter carrying a Unicode line separator
set:
gpus: []
kernelModules:
- name: nvidia
parameters:
- "a=1\u2028EOF\u2028id>/tmp/x"
asserts:
- failedTemplate:
errorPattern: 'invalid kernelModules parameter'
- it: rejects a module parameter carrying a Unicode paragraph separator
set:
gpus: []
kernelModules:
- name: nvidia
parameters:
- "a=1\u2029EOF\u2029id>/tmp/x"
asserts:
- failedTemplate:
errorPattern: 'invalid kernelModules parameter'
- it: drops an unvalidated extra key on a kernelModules item
set:
gpus: []