Skip to content

Commit 4ebffce

Browse files
committed
fix(unikontainers): validate containerID before path constructio
1 parent 5c9b935 commit 4ebffce

4 files changed

Lines changed: 32 additions & 8 deletions

File tree

cmd/urunc/create.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ var createCommand = &cli.Command{
9090
func createUnikontainer(cmd *cli.Command, uruncCfg *unikontainers.UruncConfig) (err error) {
9191
err = nil
9292
containerID := cmd.Args().First()
93-
if containerID == "" {
94-
err = fmt.Errorf("container id cannot be empty")
93+
if err = unikontainers.ValidateID(containerID); err != nil {
9594
return err
9695
}
9796
metrics.SetLoggerContainerID(containerID)

cmd/urunc/delete.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323

2424
"github.com/sirupsen/logrus"
2525
"github.com/urfave/cli/v3"
26+
"github.com/urunc-dev/urunc/pkg/unikontainers"
2627
)
2728

2829
var deleteCommand = &cli.Command{
@@ -58,8 +59,8 @@ status of "ubuntu01" as "stopped" the following will delete resources held for
5859
if err != nil {
5960
if errors.Is(err, os.ErrNotExist) {
6061
containerID := cmd.Args().First()
61-
if containerID == "" {
62-
return ErrEmptyContainerID
62+
if err = unikontainers.ValidateID(containerID); err != nil {
63+
return err
6364
}
6465
rootDir := cmd.String("root")
6566
containerDir := filepath.Join(rootDir, containerID)

cmd/urunc/utils.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ const (
3636
maxArgs // Checks for a maximum number of arguments.
3737
)
3838

39-
var ErrEmptyContainerID = errors.New("container ID can not be empty")
40-
4139
// checkArgs checks the number of arguments provided in the command-line context
4240
// against the expected number, based on the specified checkType.
4341
func checkArgs(cmd *cli.Command, expected, checkType int) error {
@@ -69,8 +67,8 @@ func checkArgs(cmd *cli.Command, expected, checkType int) error {
6967

7068
func getUnikontainer(cmd *cli.Command) (*unikontainers.Unikontainer, error) {
7169
containerID := cmd.Args().First()
72-
if containerID == "" {
73-
return nil, ErrEmptyContainerID
70+
if err := unikontainers.ValidateID(containerID); err != nil {
71+
return nil, err
7472
}
7573

7674
// We have already made sure in main.go that root is not nil

pkg/unikontainers/unikontainers.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var uniklog = logrus.WithField("subsystem", "unikontainers")
5151
var ErrQueueProxy = errors.New("this a queue proxy container")
5252
var ErrNotUnikernel = errors.New("this is not a unikernel container")
5353
var ErrNotExistingNS = errors.New("the namespace does not exist")
54+
var ErrInvalidContainerID = errors.New("invalid container ID")
5455

5556
// Unikontainer holds the data necessary to create, manage and delete unikernel containers
5657
type Unikontainer struct {
@@ -63,8 +64,30 @@ type Unikontainer struct {
6364
Conn *net.UnixConn
6465
}
6566

67+
// ValidateID checks containerID against the allowed character set,
68+
func ValidateID(id string) error {
69+
if id == "" {
70+
return ErrInvalidContainerID
71+
}
72+
for i := 0; i < len(id); i++ {
73+
c := id[i]
74+
switch {
75+
case c >= 'a' && c <= 'z':
76+
case c >= 'A' && c <= 'Z':
77+
case c >= '0' && c <= '9':
78+
case c == '_', c == '+', c == '-', c == '.':
79+
default:
80+
return fmt.Errorf("%w: invalid character %q in id %q", ErrInvalidContainerID, c, id)
81+
}
82+
}
83+
return nil
84+
}
85+
6686
// New parses the bundle and creates a new Unikontainer object
6787
func New(bundlePath string, containerID string, rootDir string, cfg *UruncConfig) (*Unikontainer, error) {
88+
if err := ValidateID(containerID); err != nil {
89+
return nil, err
90+
}
6891
spec, err := loadSpec(bundlePath)
6992
if err != nil {
7093
return nil, err
@@ -113,6 +136,9 @@ func New(bundlePath string, containerID string, rootDir string, cfg *UruncConfig
113136

114137
// Get retrieves unikernel data from disk to create a Unikontainer object
115138
func Get(containerID string, rootDir string) (*Unikontainer, error) {
139+
if err := ValidateID(containerID); err != nil {
140+
return nil, err
141+
}
116142
u := &Unikontainer{}
117143
containerDir := filepath.Join(rootDir, containerID)
118144
stateFilePath := filepath.Join(containerDir, stateFilename)

0 commit comments

Comments
 (0)