-
Notifications
You must be signed in to change notification settings - Fork 544
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: correctly quote and unquote strings in GRUB config
One of the fields in the GRUB config - boot arguments - contains user-controlled input. Talos supports variable expansion in `talos.config` parameter, and uses `${var}` syntax. In GRUB config, `}` is a special character, and introduction of `}` breaks config parsing both for GRUB and Talos. Correctly escape and unescape special characters. Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
- Loading branch information
Showing
6 changed files
with
172 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/export_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
package grub | ||
|
||
// Quote exported for testing. | ||
func Quote(s string) string { | ||
return quote(s) | ||
} | ||
|
||
// Unquote exported for testing. | ||
func Unquote(s string) string { | ||
return unquote(s) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/quote.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
package grub | ||
|
||
import ( | ||
"strings" | ||
) | ||
|
||
// quote according to (incomplete) GRUB quoting rules. | ||
// | ||
// See https://www.gnu.org/software/grub/manual/grub/html_node/Shell_002dlike-scripting.html | ||
func quote(s string) string { | ||
for _, c := range `\{}$|;<>"` { | ||
s = strings.ReplaceAll(s, string(c), `\`+string(c)) | ||
} | ||
|
||
return s | ||
} | ||
|
||
// unquote according to (incomplete) GRUB quoting rules. | ||
func unquote(s string) string { | ||
for _, c := range `{}$|;<>\"` { | ||
s = strings.ReplaceAll(s, `\`+string(c), string(c)) | ||
} | ||
|
||
return s | ||
} |
99 changes: 99 additions & 0 deletions
99
internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/quote_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
package grub_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub" | ||
) | ||
|
||
//nolint:dupl | ||
func TestQuote(t *testing.T) { | ||
t.Parallel() | ||
|
||
for _, test := range []struct { | ||
name string | ||
input string | ||
expected string | ||
}{ | ||
{ | ||
name: "empty", | ||
input: "", | ||
expected: "", | ||
}, | ||
{ | ||
name: "no special characters", | ||
input: "foo", | ||
expected: "foo", | ||
}, | ||
{ | ||
name: "backslash", | ||
input: `foo\`, | ||
expected: `foo\\`, | ||
}, | ||
{ | ||
name: "escaped backslash", | ||
input: `foo\$`, | ||
expected: `foo\\\$`, | ||
}, | ||
} { | ||
test := test | ||
|
||
t.Run(test.name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
actual := grub.Quote(test.input) | ||
|
||
if actual != test.expected { | ||
t.Fatalf("expected %q, got %q", test.expected, actual) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
//nolint:dupl | ||
func TestUnquote(t *testing.T) { | ||
t.Parallel() | ||
|
||
for _, test := range []struct { | ||
name string | ||
input string | ||
expected string | ||
}{ | ||
{ | ||
name: "empty", | ||
input: "", | ||
expected: "", | ||
}, | ||
{ | ||
name: "no special characters", | ||
input: "foo", | ||
expected: "foo", | ||
}, | ||
{ | ||
name: "backslash", | ||
input: `foo\\`, | ||
expected: `foo\`, | ||
}, | ||
{ | ||
name: "escaped backslash", | ||
input: `foo\\\$`, | ||
expected: `foo\$`, | ||
}, | ||
} { | ||
test := test | ||
|
||
t.Run(test.name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
actual := grub.Unquote(test.input) | ||
|
||
if actual != test.expected { | ||
t.Fatalf("expected %q, got %q", test.expected, actual) | ||
} | ||
}) | ||
} | ||
} |