From 91c87b84cdafbddca349cca175c80cb5dfc1fc58 Mon Sep 17 00:00:00 2001 From: Mattia Eleuteri Date: Tue, 29 Sep 2026 17:35:49 +0200 Subject: [PATCH] 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 --- .../kubernetes-nodes/templates/_helpers.tpl | 10 +++++-- .../tests/kernel_modules_test.yaml | 28 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/apps/kubernetes-nodes/templates/_helpers.tpl b/packages/apps/kubernetes-nodes/templates/_helpers.tpl index 2e8b21495..8acc468b9 100644 --- a/packages/apps/kubernetes-nodes/templates/_helpers.tpl +++ b/packages/apps/kubernetes-nodes/templates/_helpers.tpl @@ -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 -}} diff --git a/packages/apps/kubernetes-nodes/tests/kernel_modules_test.yaml b/packages/apps/kubernetes-nodes/tests/kernel_modules_test.yaml index 516c30411..aaf39cedb 100644 --- a/packages/apps/kubernetes-nodes/tests/kernel_modules_test.yaml +++ b/packages/apps/kubernetes-nodes/tests/kernel_modules_test.yaml @@ -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: []