Hello community,

here is the log from the commit of package singularity for openSUSE:Factory 
checked in at 2020-09-21 17:26:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/singularity (Old)
 and      /work/SRC/openSUSE:Factory/.singularity.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "singularity"

Mon Sep 21 17:26:50 2020 rev:20 rq:835372 version:3.6.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/singularity/singularity.changes  2020-09-15 
16:28:28.322607236 +0200
+++ /work/SRC/openSUSE:Factory/.singularity.new.4249/singularity.changes        
2020-09-21 17:31:09.768357685 +0200
@@ -1,0 +2,22 @@
+Fri Sep 18 07:29:10 UTC 2020 - Ana Guerrero Lopez <aguerr...@suse.com>
+
+- New version 3.6.3, addresses the following security issues:
+  - CVE-2020-25039, bsc#1176705
+  When a Singularity action command (run, shell, exec) is run with 
+  the fakeroot or user namespace option, Singularity will extract 
+  a container image to a temporary sandbox directory. 
+  Due to insecure permissions on the temporary directory it is possible 
+  for any user with access to the system to read the contents of the image. 
+  Additionally, if the image contains a world-writable file or directory, 
+  it is possible for a user to inject arbitrary content into the running 
+  container. 
+  - CVE-2020-25040, bsc#1176707
+  When a Singularity command that results in a container 
+  build operation is executed, it is possible for a user with access 
+  to the system to read the contents of the image during the build. 
+  Additionally, if the image contains a world-writable file or directory, 
+  it is possible for a user to inject arbitrary content into the running 
+  build, which in certain circumstances may enable arbitrary code execution 
+  during the build and/or when the built container is run.
+
+-------------------------------------------------------------------

Old:
----
  singularity-3.6.2.tar.gz

New:
----
  singularity-3.6.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ singularity.spec ++++++
--- /var/tmp/diff_new_pack.EhsKrW/_old  2020-09-21 17:31:15.168362782 +0200
+++ /var/tmp/diff_new_pack.EhsKrW/_new  2020-09-21 17:31:15.172362785 +0200
@@ -23,7 +23,7 @@
 License:        BSD-3-Clause-LBNL
 Group:          Productivity/Clustering/Computing
 Name:           singularity
-Version:        3.6.2
+Version:        3.6.3
 Release:        0
 # https://spdx.org/licenses/BSD-3-Clause-LBNL.html
 URL:            https://github.com/hpcng/singularity

++++++ singularity-3.6.2.tar.gz -> singularity-3.6.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/CHANGELOG.md new/singularity/CHANGELOG.md
--- old/singularity/CHANGELOG.md        2020-08-25 20:50:09.000000000 +0200
+++ new/singularity/CHANGELOG.md        2020-09-15 16:05:03.000000000 +0200
@@ -9,6 +9,43 @@
 
 _The old changelog can be found in the `release-2.6` branch_
 
+# v3.6.3 - [2020-09-15]
+
+## Security related fixes
+
+Singularity 3.6.3 addresses the following security issues.
+
+  - 
[CVE-2020-25039](https://github.com/hpcng/singularity/security/advisories/GHSA-w6v2-qchm-grj7):
+    When a Singularity action command (run, shell, exec) is run with
+    the fakeroot or user namespace option, Singularity will extract a
+    container image to a temporary sandbox directory. Due to insecure
+    permissions on the temporary directory it is possible for any user
+    with access to the system to read the contents of the
+    image. Additionally, if the image contains a world-writable file
+    or directory, it is possible for a user to inject arbitrary
+    content into the running container.
+
+  - 
[CVE-2020-25040](https://github.com/hpcng/singularity/security/advisories/GHSA-jv9c-w74q-6762):
+    When a Singularity command that results in a container build
+    operation is executed, it is possible for a user with access to
+    the system to read the contents of the image during the
+    build. Additionally, if the image contains a world-writable file
+    or directory, it is possible for a user to inject arbitrary
+    content into the running build, which in certain circumstances may
+    enable arbitrary code execution during the build and/or when the
+    built container is run.
+
+## Bug Fixes
+
+  - Add CAP_MKNOD in capability bounding set of RPC to fix issue with
+    cryptsetup when decrypting image from within a docker container.
+  - Fix decryption issue when using both IPC and PID namespaces.
+  - Fix unsupported builtins panic from shell interpreter and add umask
+    support for definition file scripts.
+  - Do not load keyring in prepare_linux if ECL not enabled.
+  - Ensure sandbox option overrides remote build destination.
+
+
 # v3.6.2 - [2020-08-25]
 
 ## New features / functionalities
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/INSTALL.md new/singularity/INSTALL.md
--- old/singularity/INSTALL.md  2020-08-25 20:50:09.000000000 +0200
+++ new/singularity/INSTALL.md  2020-09-15 16:05:03.000000000 +0200
@@ -89,7 +89,7 @@
 To build a stable version of Singularity, check out a [release 
tag](https://github.com/sylabs/singularity/tags) before compiling:
 
 ```
-$ git checkout v3.6.2
+$ git checkout v3.6.3
 ```
 
 ## Compiling Singularity
@@ -132,7 +132,7 @@
 and use it to install the RPM like this: 
 
 ```
-$ export VERSION=3.6.2  # this is the singularity version, change as you need
+$ export VERSION=3.6.3  # this is the singularity version, change as you need
 
 $ wget 
https://github.com/sylabs/singularity/releases/download/v${VERSION}/singularity-${VERSION}.tar.gz
 && \
     rpmbuild -tb singularity-${VERSION}.tar.gz && \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/VERSION new/singularity/VERSION
--- old/singularity/VERSION     2020-08-26 00:51:09.000000000 +0200
+++ new/singularity/VERSION     2020-09-15 16:11:54.000000000 +0200
@@ -1 +1 @@
-3.6.2
+3.6.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/cmd/internal/cli/actions_linux.go 
new/singularity/cmd/internal/cli/actions_linux.go
--- old/singularity/cmd/internal/cli/actions_linux.go   2020-08-17 
19:13:16.000000000 +0200
+++ new/singularity/cmd/internal/cli/actions_linux.go   2020-09-15 
16:05:03.000000000 +0200
@@ -45,27 +45,30 @@
        "golang.org/x/sys/unix"
 )
 
-func convertImage(filename string, unsquashfsPath string) (string, error) {
+// convertImage extracts the image found at filename to directory dir within a 
temporary directory
+// tempDir. If the unsquashfs binary is not located, the binary at 
unsquashfsPath is used. It is
+// the caller's responsibility to remove tempDir when no longer needed.
+func convertImage(filename string, unsquashfsPath string) (tempDir, imageDir 
string, err error) {
        img, err := imgutil.Init(filename, false)
        if err != nil {
-               return "", fmt.Errorf("could not open image %s: %s", filename, 
err)
+               return "", "", fmt.Errorf("could not open image %s: %s", 
filename, err)
        }
        defer img.File.Close()
 
        part, err := img.GetRootFsPartition()
        if err != nil {
-               return "", fmt.Errorf("while getting root filesystem in %s: 
%s", filename, err)
+               return "", "", fmt.Errorf("while getting root filesystem in %s: 
%s", filename, err)
        }
 
        // squashfs only
        if part.Type != imgutil.SQUASHFS {
-               return "", fmt.Errorf("not a squashfs root filesystem")
+               return "", "", fmt.Errorf("not a squashfs root filesystem")
        }
 
        // create a reader for rootfs partition
        reader, err := imgutil.NewPartitionReader(img, "", 0)
        if err != nil {
-               return "", fmt.Errorf("could not extract root filesystem: %s", 
err)
+               return "", "", fmt.Errorf("could not extract root filesystem: 
%s", err)
        }
        s := unpacker.NewSquashfs()
        if !s.HasUnsquashfs() && unsquashfsPath != "" {
@@ -82,18 +85,28 @@
        }
 
        // create temporary sandbox
-       dir, err := ioutil.TempDir(tmpdir, "rootfs-")
+       tempDir, err = ioutil.TempDir(tmpdir, "rootfs-")
        if err != nil {
-               return "", fmt.Errorf("could not create temporary sandbox: %s", 
err)
+               return "", "", fmt.Errorf("could not create temporary sandbox: 
%s", err)
+       }
+       defer func() {
+               if err != nil {
+                       os.RemoveAll(tempDir)
+               }
+       }()
+
+       // create an inner dir to extract to, so we don't clobber the secure 
permissions on the tmpDir.
+       imageDir = filepath.Join(tempDir, "root")
+       if err := os.Mkdir(imageDir, 0755); err != nil {
+               return "", "", fmt.Errorf("could not create root directory: 
%s", err)
        }
 
        // extract root filesystem
-       if err := s.ExtractAll(reader, dir); err != nil {
-               os.RemoveAll(dir)
-               return "", fmt.Errorf("root filesystem extraction failed: %s", 
err)
+       if err := s.ExtractAll(reader, imageDir); err != nil {
+               return "", "", fmt.Errorf("root filesystem extraction failed: 
%s", err)
        }
 
-       return dir, err
+       return tempDir, imageDir, err
 }
 
 // checkHidepid checks if hidepid is set on /proc mount point, when this
@@ -650,13 +663,13 @@
                        }
                        sylog.Verbosef("User namespace requested, convert image 
%s to sandbox", image)
                        sylog.Infof("Convert SIF file to sandbox...")
-                       dir, err := convertImage(image, unsquashfsPath)
+                       tempDir, imageDir, err := convertImage(image, 
unsquashfsPath)
                        if err != nil {
                                sylog.Fatalf("while extracting %s: %s", image, 
err)
                        }
-                       engineConfig.SetImage(dir)
-                       engineConfig.SetDeleteImage(true)
-                       generator.AddProcessEnv("SINGULARITY_CONTAINER", dir)
+                       engineConfig.SetImage(imageDir)
+                       engineConfig.SetDeleteTempDir(tempDir)
+                       generator.AddProcessEnv("SINGULARITY_CONTAINER", 
imageDir)
 
                        // if '--disable-cache' flag, then remove original SIF 
after converting to sandbox
                        if disableCache {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/cmd/internal/cli/build_linux.go 
new/singularity/cmd/internal/cli/build_linux.go
--- old/singularity/cmd/internal/cli/build_linux.go     2020-08-21 
20:55:51.000000000 +0200
+++ new/singularity/cmd/internal/cli/build_linux.go     2020-09-15 
15:38:45.000000000 +0200
@@ -12,6 +12,7 @@
        "os"
        osExec "os/exec"
        "runtime"
+       "strings"
        "syscall"
 
        "github.com/spf13/cobra"
@@ -126,17 +127,27 @@
                sylog.Fatalf("Unable to build from %s: %v", spec, err)
        }
 
+       // path SIF from remote builder should be placed
+       rbDst := dst
        if buildArgs.sandbox {
+               if strings.HasPrefix(dst, "library://") {
+                       // image destination is the library.
+                       sylog.Fatalf("Library URI detected as destination, 
sandbox builds are incompatible with library destinations.")
+               }
+
                // create temporary file to download sif
                f, err := ioutil.TempFile(tmpDir, "remote-build-")
                if err != nil {
                        sylog.Fatalf("Could not create temporary directory: 
%s", err)
                }
-               os.Remove(f.Name())
-               dest := f.Name()
+               f.Close()
+
+               // override remote build destation to temporary file for 
conversion to a sandbox
+               rbDst = f.Name()
+               sylog.Debugf("Overriding remote build destination to temporary 
file: %s", rbDst)
 
                // remove downloaded sif
-               defer os.Remove(f.Name())
+               defer os.Remove(rbDst)
 
                // build from sif downloaded in tmp location
                defer func() {
@@ -146,7 +157,7 @@
                                sylog.Fatalf("failed to create an image cache 
handle")
                        }
 
-                       d, err := types.NewDefinitionFromURI("localimage" + 
"://" + dest)
+                       d, err := types.NewDefinitionFromURI("localimage" + 
"://" + rbDst)
                        if err != nil {
                                sylog.Fatalf("Unable to create definition for 
sandbox build: %v", err)
                        }
@@ -175,7 +186,7 @@
                }()
        }
 
-       b, err := remotebuilder.New(dst, buildArgs.libraryURL, def, 
buildArgs.detached, forceOverwrite, buildArgs.builderURL, authToken, 
buildArgs.arch)
+       b, err := remotebuilder.New(rbDst, buildArgs.libraryURL, def, 
buildArgs.detached, forceOverwrite, buildArgs.builderURL, authToken, 
buildArgs.arch)
        if err != nil {
                sylog.Fatalf("Failed to create builder: %v", err)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/cmd/starter/c/starter.c 
new/singularity/cmd/starter/c/starter.c
--- old/singularity/cmd/starter/c/starter.c     2020-08-24 18:37:07.000000000 
+0200
+++ new/singularity/cmd/starter/c/starter.c     2020-09-14 22:26:41.000000000 
+0200
@@ -373,6 +373,7 @@
     /* required by cryptsetup */
     priv->capabilities.bounding = capflag(CAP_SYS_ADMIN);
     priv->capabilities.bounding |= capflag(CAP_IPC_LOCK);
+    priv->capabilities.bounding |= capflag(CAP_MKNOD);
 
     debugf("Set RPC privileges\n");
     apply_privileges(priv, current);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/e2e/run/run.go 
new/singularity/e2e/run/run.go
--- old/singularity/e2e/run/run.go      2020-08-24 18:37:07.000000000 +0200
+++ new/singularity/e2e/run/run.go      2020-09-14 22:26:41.000000000 +0200
@@ -166,6 +166,18 @@
                e2e.ExpectExit(0),
        )
 
+       // Ensure decryption works with containall (IPC and PID namespaces)
+       cmdArgs = []string{"--containall", imgPath}
+       c.env.RunSingularity(
+               t,
+               e2e.AsSubtest("env var passphrase with containall"),
+               e2e.WithProfile(e2e.UserProfile),
+               e2e.WithCommand("run"),
+               e2e.WithArgs(cmdArgs...),
+               e2e.WithEnv(append(os.Environ(), passphraseEnvVar)),
+               e2e.ExpectExit(0),
+       )
+
        // Specifying the passphrase on the command line should always fail
        cmdArgs = []string{"--passphrase", e2e.Passphrase, imgPath}
        c.env.RunSingularity(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/internal/pkg/build/build.go 
new/singularity/internal/pkg/build/build.go
--- old/singularity/internal/pkg/build/build.go 2020-08-21 20:55:51.000000000 
+0200
+++ new/singularity/internal/pkg/build/build.go 2020-09-15 16:05:03.000000000 
+0200
@@ -13,13 +13,13 @@
        "os"
        "os/signal"
        "path/filepath"
+       "strings"
        "syscall"
 
        "github.com/sylabs/singularity/internal/pkg/util/fs"
        "github.com/sylabs/singularity/pkg/util/fs/proc"
        "github.com/sylabs/singularity/pkg/util/singularityconf"
 
-       uuid "github.com/satori/go.uuid"
        "github.com/sylabs/singularity/internal/pkg/build/apps"
        "github.com/sylabs/singularity/internal/pkg/build/assemblers"
        "github.com/sylabs/singularity/internal/pkg/build/sources"
@@ -113,14 +113,16 @@
                if conf.Format == "sandbox" {
                        rootfsParent = filepath.Dir(conf.Dest)
                }
-               rootfs := filepath.Join(rootfsParent, 
"rootfs-"+uuid.NewV1().String())
+               parentPath, err := ioutil.TempDir(rootfsParent, "build-temp-")
+               if err != nil {
+                       return nil, fmt.Errorf("failed to create build parent 
dir: %w", err)
+               }
 
                var s stage
-               var err error
                if conf.Opts.EncryptionKeyInfo != nil {
-                       s.b, err = types.NewEncryptedBundle(rootfs, 
conf.Opts.TmpDir, conf.Opts.EncryptionKeyInfo)
+                       s.b, err = types.NewEncryptedBundle(parentPath, 
conf.Opts.TmpDir, conf.Opts.EncryptionKeyInfo)
                } else {
-                       s.b, err = types.NewBundle(rootfs, conf.Opts.TmpDir)
+                       s.b, err = types.NewBundle(parentPath, conf.Opts.TmpDir)
                }
                if err != nil {
                        return nil, err
@@ -134,7 +136,7 @@
                        // the old behavior which is to create the temporary 
rootfs inside
                        // $TMPDIR and copy the final root filesystem to the 
destination
                        // provided
-                       if s.b.RootfsPath != rootfs {
+                       if !strings.HasPrefix(s.b.RootfsPath, parentPath) {
                                sandboxCopy = true
                                sylog.Warningf("The underlying filesystem on 
which resides %q won't allow to set ownership, "+
                                        "as a consequence the sandbox could not 
preserve image's files/directories ownerships", conf.Dest)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/internal/pkg/build/sources/conveyorPacker_oci.go 
new/singularity/internal/pkg/build/sources/conveyorPacker_oci.go
--- old/singularity/internal/pkg/build/sources/conveyorPacker_oci.go    
2020-08-17 19:13:16.000000000 +0200
+++ new/singularity/internal/pkg/build/sources/conveyorPacker_oci.go    
2020-09-15 16:05:03.000000000 +0200
@@ -96,7 +96,7 @@
                        cp.srcRef, err = ociarchive.ParseReference(ref)
                } else {
                        // As non-root we need to do a dumb tar extraction first
-                       tmpDir, err := ioutil.TempDir(cp.b.Opts.TmpDir, 
"temp-oci-")
+                       tmpDir, err := ioutil.TempDir(b.TmpDir, "temp-oci-")
                        if err != nil {
                                return fmt.Errorf("could not create temporary 
oci directory: %v", err)
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/internal/pkg/runtime/engine/singularity/cleanup_linux.go 
new/singularity/internal/pkg/runtime/engine/singularity/cleanup_linux.go
--- old/singularity/internal/pkg/runtime/engine/singularity/cleanup_linux.go    
2020-08-24 18:37:07.000000000 +0200
+++ new/singularity/internal/pkg/runtime/engine/singularity/cleanup_linux.go    
2020-09-15 16:05:03.000000000 +0200
@@ -50,9 +50,8 @@
                }
        }
 
-       if e.EngineConfig.GetDeleteImage() {
-               image := e.EngineConfig.GetImage()
-               sylog.Verbosef("Removing image %s", image)
+       if tempDir := e.EngineConfig.GetDeleteTempDir(); tempDir != "" {
+               sylog.Verbosef("Removing image tempDir %s", tempDir)
                sylog.Infof("Cleaning up image...")
 
                var err error
@@ -63,12 +62,12 @@
                        // context and can get permission denied error during
                        // image removal, so we execute "rm -rf /tmp/image" via
                        // the fakeroot engine
-                       err = fakerootCleanup(image)
+                       err = fakerootCleanup(tempDir)
                } else {
-                       err = os.RemoveAll(image)
+                       err = os.RemoveAll(tempDir)
                }
                if err != nil {
-                       sylog.Errorf("failed to delete container image %s: %s", 
image, err)
+                       sylog.Errorf("failed to delete container image tempDir 
%s: %s", tempDir, err)
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/internal/pkg/runtime/engine/singularity/prepare_linux.go 
new/singularity/internal/pkg/runtime/engine/singularity/prepare_linux.go
--- old/singularity/internal/pkg/runtime/engine/singularity/prepare_linux.go    
2020-08-17 19:13:16.000000000 +0200
+++ new/singularity/internal/pkg/runtime/engine/singularity/prepare_linux.go    
2020-09-14 22:26:41.000000000 +0200
@@ -41,6 +41,7 @@
        "github.com/sylabs/singularity/pkg/util/fs/proc"
        "github.com/sylabs/singularity/pkg/util/namespaces"
        "github.com/sylabs/singularity/pkg/util/singularityconf"
+       "golang.org/x/crypto/openpgp"
        "golang.org/x/sys/unix"
 )
 
@@ -1166,9 +1167,16 @@
                                return fmt.Errorf("while validating ECL 
configuration: %s", err)
                        }
 
-                       kr, err := sypgp.PublicKeyRing()
-                       if err != nil {
-                               return fmt.Errorf("while obtaining keyring for 
ECL: %s", err)
+                       // Only try to load the keyring here if the ECL is 
active.
+                       // Otherwise pass through an empty keyring rather than 
avoiding calling
+                       // the ECL functions as this keeps the logic for 
applying / ignoring ECL in a
+                       // single location.
+                       var kr openpgp.KeyRing = openpgp.EntityList{}
+                       if ecl.Activated {
+                               kr, err = sypgp.PublicKeyRing()
+                               if err != nil {
+                                       return fmt.Errorf("while obtaining 
keyring for ECL: %s", err)
+                               }
                        }
 
                        if ok, err := ecl.ShouldRunFp(img.File, kr); err != nil 
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/internal/pkg/runtime/engine/singularity/process_linux.go 
new/singularity/internal/pkg/runtime/engine/singularity/process_linux.go
--- old/singularity/internal/pkg/runtime/engine/singularity/process_linux.go    
2020-08-24 18:37:07.000000000 +0200
+++ new/singularity/internal/pkg/runtime/engine/singularity/process_linux.go    
2020-09-14 22:26:41.000000000 +0200
@@ -22,6 +22,7 @@
        "reflect"
        "regexp"
        "runtime"
+       "strconv"
        "strings"
        "sync"
        "syscall"
@@ -757,6 +758,24 @@
        return nil
 }
 
+func umaskBuiltin(ctx context.Context, argv []string) error {
+       hc := interp.HandlerCtx(ctx)
+
+       if len(argv) == 0 {
+               old := unix.Umask(0)
+               unix.Umask(old)
+               fmt.Fprintf(hc.Stdout, "%#.4o\n", old)
+       } else {
+               umask, err := strconv.ParseUint(argv[0], 8, 16)
+               if err != nil {
+                       return fmt.Errorf("umask: %s: invalid octal number: 
%s", argv[0], err)
+               }
+               unix.Umask(int(umask))
+       }
+
+       return nil
+}
+
 // runActionScript interprets and executes the action script within
 // an embedded shell interpreter.
 func runActionScript(engineConfig *singularityConfig.EngineConfig) ([]string, 
[]string, error) {
@@ -794,6 +813,7 @@
        shell.RegisterShellBuiltin("fixpath", fixPathBuiltin)
        shell.RegisterShellBuiltin("hash", hashBuiltin)
        shell.RegisterShellBuiltin("unescape", unescapeBuiltin)
+       shell.RegisterShellBuiltin("umask_builtin", umaskBuiltin)
 
        // exec builtin won't execute the command but instead
        // it returns arguments and environment variables and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/internal/pkg/runtime/engine/singularity/rpc/server/server_linux.go
 
new/singularity/internal/pkg/runtime/engine/singularity/rpc/server/server_linux.go
--- 
old/singularity/internal/pkg/runtime/engine/singularity/rpc/server/server_linux.go
  2020-08-24 18:37:07.000000000 +0200
+++ 
new/singularity/internal/pkg/runtime/engine/singularity/rpc/server/server_linux.go
  2020-09-14 22:26:41.000000000 +0200
@@ -89,7 +89,20 @@
                return capErr
        }
 
+       pid := 0
+
        if hasIPC {
+               // we can't rely on os.Getpid since this process may
+               // be in the container PID namespace
+               self, err := os.Readlink("/proc/self")
+               if err != nil {
+                       return err
+               }
+               pid, err = strconv.Atoi(self)
+               if err != nil {
+                       return err
+               }
+
                // cryptsetup requires to run in the host IPC namespace
                // so we enter temporarily in the host IPC namespace
                // via the master processus ID if its greater than zero
@@ -106,7 +119,7 @@
                }
 
                if hasIPC {
-                       e := namespaces.Enter(os.Getpid(), "ipc")
+                       e := namespaces.Enter(pid, "ipc")
                        if err == nil && e != nil {
                                err = fmt.Errorf("while joining container IPC 
namespace: %s", e)
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/internal/pkg/util/fs/files/action_scripts.go 
new/singularity/internal/pkg/util/fs/files/action_scripts.go
--- old/singularity/internal/pkg/util/fs/files/action_scripts.go        
2020-08-21 20:55:51.000000000 +0200
+++ new/singularity/internal/pkg/util/fs/files/action_scripts.go        
2020-09-14 22:26:41.000000000 +0200
@@ -16,6 +16,16 @@
 
 export PWD
 
+unsupported_builtin() {
+    sylog warning "$1 is not supported by this shell interpreter"
+}
+
+# create alias for unsupported builtin that trigger a panic
+alias umask="umask_builtin"
+alias trap="unsupported_builtin trap"
+alias fg="unsupported_builtin fg"
+alias bg="unsupported_builtin bg"
+
 clear_env() {
     local IFS=$'\n'
 
@@ -69,6 +79,7 @@
 }
 
 clear_env
+shopt -s expand_aliases
 
 if test -d "/.singularity.d/env"; then
     for __script__ in /.singularity.d/env/*.sh; do
@@ -116,6 +127,7 @@
     source "/.singularity.d/env/99-runtimevars.sh"
 fi
 
+shopt -u expand_aliases
 restore_env
 
 # See https://github.com/sylabs/singularity/issues/2721,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/pkg/build/types/bundle.go 
new/singularity/pkg/build/types/bundle.go
--- old/singularity/pkg/build/types/bundle.go   2020-08-17 19:13:16.000000000 
+0200
+++ new/singularity/pkg/build/types/bundle.go   2020-09-15 16:05:03.000000000 
+0200
@@ -30,6 +30,8 @@
 
        RootfsPath string `json:"rootfsPath"` // where actual fs to chroot will 
appear
        TmpDir     string `json:"tmpPath"`    // where temp files required 
during build will appear
+
+       parentPath string // parent directory for RootfsPath
 }
 
 // Options defines build time behavior to be executed on the bundle.
@@ -73,13 +75,13 @@
 }
 
 // NewEncryptedBundle creates an Encrypted Bundle environment.
-func NewEncryptedBundle(rootfs, tempDir string, keyInfo *crypt.KeyInfo) (b 
*Bundle, err error) {
-       return newBundle(rootfs, tempDir, keyInfo)
+func NewEncryptedBundle(parentPath, tempDir string, keyInfo *crypt.KeyInfo) (b 
*Bundle, err error) {
+       return newBundle(parentPath, tempDir, keyInfo)
 }
 
 // NewBundle creates a Bundle environment.
-func NewBundle(rootfs, tempDir string) (b *Bundle, err error) {
-       return newBundle(rootfs, tempDir, nil)
+func NewBundle(parentPath, tempDir string) (b *Bundle, err error) {
+       return newBundle(parentPath, tempDir, nil)
 }
 
 // RunSection iterates through the sections specified in a bundle
@@ -100,7 +102,7 @@
 // Remove cleans up any bundle files.
 func (b *Bundle) Remove() error {
        var errors []string
-       for _, dir := range []string{b.TmpDir, b.RootfsPath} {
+       for _, dir := range []string{b.TmpDir, b.parentPath} {
                if err := fs.ForceRemoveAll(dir); err != nil {
                        errors = append(errors, fmt.Sprintf("could not remove 
%q: %v", dir, err))
                }
@@ -141,11 +143,19 @@
        }
 }
 
-// newBundle creates a minimum bundle with root filesystem in rootfs.
+// newBundle creates a minimum bundle with root filesystem in parentPath.
 // Any temporary files created during build process will be in 
tempDir/bundle-temp-*
 // directory, that will be cleaned up after successful build.
-func newBundle(rootfs, tempDir string, keyInfo *crypt.KeyInfo) (*Bundle, 
error) {
-       rootfsPath := rootfs
+
+//
+// TODO: much of the logic in this func should likely be re-factored to func 
newBuild in the
+// internal/pkg/build package, since it is the sole caller and has conditional 
logic which depends
+// on implementation details of this package. In particular, chown() handling 
should be done at the
+// build level, rather than the bundle level, to avoid repetition during 
multi-stage builds, and
+// clarify responsibility for cleanup of the various directories that are 
created during the build
+// process.
+func newBundle(parentPath, tempDir string, keyInfo *crypt.KeyInfo) (*Bundle, 
error) {
+       rootfsPath := filepath.Join(parentPath, "rootfs")
 
        tmpPath, err := ioutil.TempDir(tempDir, "bundle-temp-")
        if err != nil {
@@ -155,6 +165,7 @@
 
        if err := os.MkdirAll(rootfsPath, 0755); err != nil {
                cleanupDir(tmpPath)
+               cleanupDir(parentPath)
                return nil, fmt.Errorf("could not create %q: %v", rootfsPath, 
err)
        }
 
@@ -164,14 +175,25 @@
        if err != nil {
                cleanupDir(tmpPath)
                cleanupDir(rootfsPath)
+               cleanupDir(parentPath)
                return nil, err
        } else if !can {
-               defer cleanupDir(rootfsPath)
+               cleanupDir(rootfsPath)
+               cleanupDir(parentPath)
 
-               rootfsNewPath := filepath.Join(tempDir, 
filepath.Base(rootfsPath))
-               if rootfsNewPath != rootfsPath {
-                       if err := os.MkdirAll(rootfsNewPath, 0755); err != nil {
+               // If the supplied rootfs was not inside tempDir (as is the 
case during a sandbox build),
+               // try tempDir as a fallback.
+               if !strings.HasPrefix(parentPath, tempDir) {
+                       parentPath, err = ioutil.TempDir(tempDir, "build-temp-")
+                       if err != nil {
+                               cleanupDir(tmpPath)
+                               return nil, fmt.Errorf("failed to create rootfs 
directory: %v", err)
+                       }
+                       // Create an inner dir, so we don't clobber the secure 
permissions on the surrounding dir.
+                       rootfsNewPath := filepath.Join(parentPath, "rootfs")
+                       if err := os.Mkdir(rootfsNewPath, 0755); err != nil {
                                cleanupDir(tmpPath)
+                               cleanupDir(parentPath)
                                return nil, fmt.Errorf("could not create rootfs 
dir in %q: %v", rootfsNewPath, err)
                        }
                        // check that chown works with the underlying 
filesystem pointed
@@ -180,10 +202,12 @@
                        if err != nil {
                                cleanupDir(tmpPath)
                                cleanupDir(rootfsNewPath)
+                               cleanupDir(parentPath)
                                return nil, err
                        } else if !can {
                                cleanupDir(tmpPath)
                                cleanupDir(rootfsNewPath)
+                               cleanupDir(parentPath)
                                sylog.Errorf("Could not set files/directories 
ownership, if %s is on a network filesystem, "+
                                        "you must set TMPDIR to a local path 
(eg: TMPDIR=/var/tmp singularity build ...)", rootfsNewPath)
                                return nil, fmt.Errorf("ownership change not 
allowed in %s, aborting", tempDir)
@@ -195,6 +219,7 @@
        sylog.Debugf("Created directory %q for the bundle", rootfsPath)
 
        return &Bundle{
+               parentPath:  parentPath,
                RootfsPath:  rootfsPath,
                TmpDir:      tmpPath,
                JSONObjects: make(map[string][]byte),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/pkg/runtime/engine/singularity/config/config.go 
new/singularity/pkg/runtime/engine/singularity/config/config.go
--- old/singularity/pkg/runtime/engine/singularity/config/config.go     
2020-08-24 18:37:07.000000000 +0200
+++ new/singularity/pkg/runtime/engine/singularity/config/config.go     
2020-09-15 16:05:03.000000000 +0200
@@ -148,7 +148,7 @@
        NoPrivs           bool              `json:"noPrivs,omitempty"`
        NoHome            bool              `json:"noHome,omitempty"`
        NoInit            bool              `json:"noInit,omitempty"`
-       DeleteImage       bool              `json:"deleteImage,omitempty"`
+       DeleteTempDir     string            `json:"deleteTempDir,omitempty"`
        Fakeroot          bool              `json:"fakeroot,omitempty"`
        SignalPropagation bool              `json:"signalPropagation,omitempty"`
 }
@@ -711,14 +711,16 @@
        return e.JSON.Fakeroot
 }
 
-// GetDeleteImage returns if container image must be deleted after use.
-func (e *EngineConfig) GetDeleteImage() bool {
-       return e.JSON.DeleteImage
+// GetDeleteTempDir returns the path of the temporary directory containing the 
root filesystem
+// which must be deleted after use. If no deletion is required, the empty 
string is returned.
+func (e *EngineConfig) GetDeleteTempDir() string {
+       return e.JSON.DeleteTempDir
 }
 
-// SetDeleteImage sets if container image must be deleted after use.
-func (e *EngineConfig) SetDeleteImage(delete bool) {
-       e.JSON.DeleteImage = delete
+// SetDeleteTempDir sets dir as the path of the temporary directory containing 
the root filesystem,
+// which must be deleted after use.
+func (e *EngineConfig) SetDeleteTempDir(dir string) {
+       e.JSON.DeleteTempDir = dir
 }
 
 // SetSignalPropagation sets if engine must propagate signals from
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/singularity.spec 
new/singularity/singularity.spec
--- old/singularity/singularity.spec    2020-08-26 00:50:55.000000000 +0200
+++ new/singularity/singularity.spec    2020-09-15 16:11:43.000000000 +0200
@@ -29,12 +29,12 @@
 
 Summary: Application and environment virtualization
 Name: singularity
-Version: 3.6.2
+Version: 3.6.3
 Release: 1%{?dist}
 # https://spdx.org/licenses/BSD-3-Clause-LBNL.html
 License: BSD-3-Clause-LBNL
 URL: https://www.sylabs.io/singularity/
-Source: %{name}-3.6.2.tar.gz
+Source: %{name}-3.6.3.tar.gz
 ExclusiveOS: linux
 # RPM_BUILD_ROOT wasn't being set ... for some reason
 %if "%{sles_version}" == "11"


Reply via email to