diff --git a/src/internal/runtime/cgroup/cgroup.go b/src/internal/runtime/cgroup/cgroup.go
index f2e9da3..428c188 100644
--- a/src/internal/runtime/cgroup/cgroup.go
+++ b/src/internal/runtime/cgroup/cgroup.go
@@ -396,7 +396,10 @@
return len(target) == i || target[i] == '/' // must match at path boundary
}
-var errInvalidEscape error = stringError("invalid path escape sequence")
+var (
+ errInvalidEscape error = stringError("invalid path escape sequence")
+ errPathTooLong error = stringError("path too long")
+)
// unescapePath copies in to out, unescaping escape sequences generated by
// Linux's show_path.
@@ -410,14 +413,11 @@
//
// Also see escapePath in cgroup_linux_test.go.
func unescapePath(out []byte, in []byte) (int, error) {
- // Not strictly necessary, but simplifies the implementation and will
- // always hold in users.
- if len(out) < len(in) {
- throw("output too small")
- }
-
var outi, ini int
for ini < len(in) {
+ if outi >= len(out) {
+ return outi, errPathTooLong
+ }
c := in[ini]
if c != '\\' {
out[outi] = c
@@ -434,18 +434,21 @@
return outi, errInvalidEscape
}
- var outc byte
+ var outc int
for i := range 3 {
c := in[ini+1+i]
- if c < '0' || c > '9' {
+ if c < '0' || c > '7' {
return outi, errInvalidEscape
}
outc *= 8
- outc += c - '0'
+ outc += int(c - '0')
}
- out[outi] = outc
+ if outc > 0xFF {
+ return outi, errInvalidEscape
+ }
+ out[outi] = byte(outc)
outi++
ini += 4
diff --git a/src/internal/runtime/cgroup/cgroup_test.go b/src/internal/runtime/cgroup/cgroup_test.go
index 6d4fe12..001e374 100644
--- a/src/internal/runtime/cgroup/cgroup_test.go
+++ b/src/internal/runtime/cgroup/cgroup_test.go
@@ -543,3 +543,23 @@
}
})
}
+
+func TestUnescapeInvalidPath(t *testing.T) {
+ for _, in := range []string{
+ `/a/b\c`,
+ `/a/b\01`,
+ `/a/b\018`,
+ `/a/b\01c`,
+ `/a/b\777`,
+ `01234567890123456789`, // too long
+ `\001\002\003\004\005\006\007\010\011`, // too long
+ } {
+ out := make([]byte, 8)
+ t.Run(in, func(t *testing.T) {
+ _, err := cgroup.UnescapePath(out, []byte(in))
+ if err == nil {
+ t.Errorf("unescapePath got nil err, want non-nil")
+ }
+ })
+ }
+}