From 61b5dafa8dcf74ffd5b601594b646c62a0209c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 28 Apr 2024 16:05:19 +0200 Subject: [PATCH 1/6] incus/storage: Show usage when no driver passed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber --- cmd/incus/storage.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/incus/storage.go b/cmd/incus/storage.go index 2a871398efa..ef051c12765 100644 --- a/cmd/incus/storage.go +++ b/cmd/incus/storage.go @@ -123,6 +123,12 @@ func (c *cmdStorageCreate) Run(cmd *cobra.Command, args []string) error { return err } + // Require a proper driver name. + if strings.Contains(args[1], "=") { + _ = cmd.Help() + return fmt.Errorf(i18n.G("Invalid number of arguments")) + } + // If stdin isn't a terminal, read text from it if !termios.IsTerminal(getStdinFd()) { contents, err := io.ReadAll(os.Stdin) From 864f14f600511942452c122d28c5c5d6f35b721f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 28 Apr 2024 16:16:54 +0200 Subject: [PATCH 2/6] incusd/storage/drivers/dir: Tweak path validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #792 Signed-off-by: Stéphane Graber --- internal/server/storage/drivers/driver_dir.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/server/storage/drivers/driver_dir.go b/internal/server/storage/drivers/driver_dir.go index b8a9ac4b77e..dba20534852 100644 --- a/internal/server/storage/drivers/driver_dir.go +++ b/internal/server/storage/drivers/driver_dir.go @@ -77,7 +77,8 @@ func (d *dir) Create() error { // Check that if within INCUS_DIR, we're at our expected spot. cleanSource := filepath.Clean(sourcePath) - if strings.HasPrefix(cleanSource, internalUtil.VarPath()) && cleanSource != GetPoolMountPath(d.name) { + varPath := strings.TrimRight(internalUtil.VarPath(), "/") + "/" + if (cleanSource == internalUtil.VarPath() || strings.HasPrefix(cleanSource, varPath)) && cleanSource != GetPoolMountPath(d.name) { return fmt.Errorf("Source path '%s' is within the Incus directory", cleanSource) } From d634c75638513f39a048691b4745961e35cc0624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 28 Apr 2024 16:28:06 +0200 Subject: [PATCH 3/6] incusd/backup: Show profile list on lookup error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #790 Signed-off-by: Stéphane Graber --- cmd/incusd/api_internal.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/incusd/api_internal.go b/cmd/incusd/api_internal.go index 1a6d2198409..b4bd1c9a10f 100644 --- a/cmd/incusd/api_internal.go +++ b/cmd/incusd/api_internal.go @@ -732,7 +732,7 @@ func internalImportFromBackup(ctx context.Context, s *state.State, projectName s return err }) if err != nil { - return fmt.Errorf("Failed loading profiles for instance: %w", err) + return fmt.Errorf("Failed loading profiles (%v) for instance: %w", strings.Join(backupConf.Container.Profiles, ", "), err) } // Add root device if needed. @@ -844,7 +844,7 @@ func internalImportFromBackup(ctx context.Context, s *state.State, projectName s return err }) if err != nil { - return fmt.Errorf("Failed loading profiles for instance snapshot %q: %w", snapInstName, err) + return fmt.Errorf("Failed loading profiles (%v) for instance snapshot %q: %w", strings.Join(snap.Profiles, ", "), snapInstName, err) } // Add root device if needed. From 8092e2741cdec6a4853544cbe0ca3a6fecbf171f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 28 Apr 2024 16:45:56 +0200 Subject: [PATCH 4/6] incusd/apparmor/lxc: Allow access to binfmt_misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber --- internal/server/apparmor/instance_lxc.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/internal/server/apparmor/instance_lxc.go b/internal/server/apparmor/instance_lxc.go index c5135830baf..e2104ea2cc2 100644 --- a/internal/server/apparmor/instance_lxc.go +++ b/internal/server/apparmor/instance_lxc.go @@ -73,7 +73,6 @@ profile "{{ .name }}" flags=(attach_disconnected,mediate_deleted) { deny /proc/kcore rwklx, deny /proc/sysrq-trigger rwklx, deny /proc/acpi/** rwklx, - deny /proc/sys/fs/** wklx, # Handle securityfs (access handled separately) mount fstype=securityfs -> /sys/kernel/security/, @@ -322,7 +321,21 @@ profile "{{ .name }}" flags=(attach_disconnected,mediate_deleted) { mount options=(rw,move) /sys?*{,/**}, # Block dangerous paths under /proc/sys - deny /proc/sys/[^kn]*{,/**} wklx, + deny /proc/sys/[^fkn]*{,/**} wklx, + deny /proc/sys/f[^s]*{,/**} wklx, + deny /proc/sys/fs/[^b]*{,/**} wklx, + deny /proc/sys/fs/b[^i]*{,/**} wklx, + deny /proc/sys/fs/bi[^n]*{,/**} wklx, + deny /proc/sys/fs/bin[^f]*{,/**} wklx, + deny /proc/sys/fs/binf[^m]*{,/**} wklx, + deny /proc/sys/fs/binfm[^t]*{,/**} wklx, + deny /proc/sys/fs/binfmt[^_]*{,/**} wklx, + deny /proc/sys/fs/binfmt_[^m]*{,/**} wklx, + deny /proc/sys/fs/binfmt_m[^i]*{,/**} wklx, + deny /proc/sys/fs/binfmt_mi[^s]*{,/**} wklx, + deny /proc/sys/fs/binfmt_mis[^c]*{,/**} wklx, + deny /proc/sys/fs/binfmt_misc?*{,/**} wklx, + deny /proc/sys/fs?*{,/**} wklx, deny /proc/sys/k[^e]*{,/**} wklx, deny /proc/sys/ke[^r]*{,/**} wklx, deny /proc/sys/ker[^n]*{,/**} wklx, From ff1290c627dca42f4c0538453ef60b610be0ee6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 28 Apr 2024 16:47:14 +0200 Subject: [PATCH 5/6] incusd/apparmor/lxc: Refresh generated rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber --- internal/server/apparmor/instance_lxc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/server/apparmor/instance_lxc.go b/internal/server/apparmor/instance_lxc.go index e2104ea2cc2..5ac00887cbd 100644 --- a/internal/server/apparmor/instance_lxc.go +++ b/internal/server/apparmor/instance_lxc.go @@ -374,7 +374,7 @@ profile "{{ .name }}" flags=(attach_disconnected,mediate_deleted) { deny /proc/sys/net?*{,/**} wklx, # Block dangerous paths under /sys - deny /sys/[^fdck]*{,/**} wklx, + deny /sys/[^fdc]*{,/**} wklx, deny /sys/c[^l]*{,/**} wklx, deny /sys/cl[^a]*{,/**} wklx, deny /sys/cla[^s]*{,/**} wklx, @@ -404,7 +404,7 @@ profile "{{ .name }}" flags=(attach_disconnected,mediate_deleted) { deny /sys/devices/virtual?*{,/**} wklx, deny /sys/devices?*{,/**} wklx, deny /sys/f[^s]*{,/**} wklx, - deny /sys/fs/[^cb]*{,/**} wklx, + deny /sys/fs/[^bc]*{,/**} wklx, deny /sys/fs/b[^p]*{,/**} wklx, deny /sys/fs/bp[^f]*{,/**} wklx, deny /sys/fs/bpf?*{,/**} wklx, From c50747f6173048d36d4311f99ede7fde0cf21d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 28 Apr 2024 17:39:29 +0200 Subject: [PATCH 6/6] incusd/storage: Handle instance volume size on import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #798 Signed-off-by: Stéphane Graber --- internal/server/storage/backend.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/internal/server/storage/backend.go b/internal/server/storage/backend.go index 1b7da39887d..276ddb1567c 100644 --- a/internal/server/storage/backend.go +++ b/internal/server/storage/backend.go @@ -760,6 +760,18 @@ func (b *backend) CreateInstanceFromBackup(srcBackup backup.Info, srcData io.Rea volumeConfig = srcBackup.Config.Volume.Config } + // Get instance root size information. + if srcBackup.Config != nil && srcBackup.Config.Container != nil { + _, rootConfig, err := internalInstance.GetRootDiskDevice(srcBackup.Config.Container.ExpandedDevices) + if err == nil && rootConfig["size"] != "" { + if volumeConfig == nil { + volumeConfig = map[string]string{} + } + + volumeConfig["size"] = rootConfig["size"] + } + } + vol := b.GetVolume(volType, contentType, volStorageName, volumeConfig) importRevert := revert.New() @@ -795,6 +807,11 @@ func (b *backend) CreateInstanceFromBackup(srcBackup backup.Info, srcData io.Rea }) } + // Make sure the size isn't part of the instance volume after initial creation. + if volumeConfig != nil { + delete(volumeConfig, "size") + } + // Update information in the backup.yaml file. err = vol.MountTask(func(mountPath string, op *operations.Operation) error { return backup.UpdateInstanceConfig(b.state.DB.Cluster, srcBackup, mountPath)