Hello community, here is the log from the commit of package singularity for openSUSE:Factory checked in at 2020-10-20 16:17:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/singularity (Old) and /work/SRC/openSUSE:Factory/.singularity.new.3486 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "singularity" Tue Oct 20 16:17:55 2020 rev:21 rq:842715 version:3.6.4 Changes: -------- --- /work/SRC/openSUSE:Factory/singularity/singularity.changes 2020-09-21 17:31:09.768357685 +0200 +++ /work/SRC/openSUSE:Factory/.singularity.new.3486/singularity.changes 2020-10-20 16:24:23.478407021 +0200 @@ -1,0 +2,11 @@ +Tue Oct 20 07:56:37 UTC 2020 - Ana Guerrero Lopez <aguerr...@suse.com> + +- New version 3.6.4 addresses a security issue: + - CVE-2020-15229, bsc#1177901 + Due to insecure handling of path traversal and the lack of path + sanitization within unsquashfs, it is possible to overwrite/create + files on the host filesystem during the extraction of a crafted + squashfs filesystem. Affects unprivileged execution of SIF/SquashFS + images, and image builds from SIF/SquashFS images. + +------------------------------------------------------------------- Old: ---- singularity-3.6.3.tar.gz New: ---- singularity-3.6.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ singularity.spec ++++++ --- /var/tmp/diff_new_pack.r8Hxhn/_old 2020-10-20 16:24:25.238407855 +0200 +++ /var/tmp/diff_new_pack.r8Hxhn/_new 2020-10-20 16:24:25.238407855 +0200 @@ -23,7 +23,7 @@ License: BSD-3-Clause-LBNL Group: Productivity/Clustering/Computing Name: singularity -Version: 3.6.3 +Version: 3.6.4 Release: 0 # https://spdx.org/licenses/BSD-3-Clause-LBNL.html URL: https://github.com/hpcng/singularity ++++++ singularity-3.6.3.tar.gz -> singularity-3.6.4.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-09-15 16:05:03.000000000 +0200 +++ new/singularity/CHANGELOG.md 2020-10-13 16:36:52.000000000 +0200 @@ -9,6 +9,27 @@ _The old changelog can be found in the `release-2.6` branch_ +# v3.6.4 - [2020-10-13] + +## Security related fixes + +Singularity 3.6.4 addresses the following security issue. + + - [CVE-2020-15229](https://github.com/hpcng/singularity/security/advisories/GHSA-7gcp-w6ww-2xv9): + Due to insecure handling of path traversal and the lack of path + sanitization within unsquashfs (a distribution provided utility + used by Singularity), it is possible to overwrite/create files on + the host filesystem during the extraction of a crafted squashfs + filesystem. Affects unprivileged execution of SIF / SquashFS + images, and image builds from SIF / SquashFS images. + +## Bug Fixes + + - Update scs-library-client to support `library://` backends using an + 3rd party S3 object store that does not strictly conform to v4 + signature spec. + + # v3.6.3 - [2020-09-15] ## Security related fixes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/INSTALL.md new/singularity/INSTALL.md --- old/singularity/INSTALL.md 2020-09-15 16:05:03.000000000 +0200 +++ new/singularity/INSTALL.md 2020-10-13 16:36:52.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.3 +$ git checkout v3.6.4 ``` ## Compiling Singularity @@ -132,7 +132,7 @@ and use it to install the RPM like this: ``` -$ export VERSION=3.6.3 # this is the singularity version, change as you need +$ export VERSION=3.6.4 # 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 && \ @@ -148,7 +148,7 @@ $ cd $GOPATH/src/github.com/sylabs/singularity && \ ./mconfig && \ make -C builddir rpm && \ - sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/singularity-3.6.2*.x86_64.rpm # or whatever version you built + sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/singularity-3.6.4*.x86_64.rpm # or whatever version you built ``` To build an rpm with an alternative install prefix set RPMPREFIX on the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/VERSION new/singularity/VERSION --- old/singularity/VERSION 2020-09-15 16:11:54.000000000 +0200 +++ new/singularity/VERSION 2020-10-13 16:39:02.000000000 +0200 @@ -1 +1 @@ -3.6.3 +3.6.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/go.mod new/singularity/go.mod --- old/singularity/go.mod 2020-09-14 22:14:11.000000000 +0200 +++ new/singularity/go.mod 2020-10-13 15:51:07.000000000 +0200 @@ -44,7 +44,7 @@ github.com/sylabs/json-resp v0.7.0 github.com/sylabs/scs-build-client v0.1.4 github.com/sylabs/scs-key-client v0.5.1 - github.com/sylabs/scs-library-client v0.5.5 + github.com/sylabs/scs-library-client v0.5.7 github.com/sylabs/sif v1.2.1 github.com/vbauerster/mpb/v4 v4.12.2 github.com/vishvananda/netlink v1.0.1-0.20190618143317-99a56c251ae6 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/go.sum new/singularity/go.sum --- old/singularity/go.sum 2020-09-14 22:14:11.000000000 +0200 +++ new/singularity/go.sum 2020-10-13 15:51:07.000000000 +0200 @@ -533,8 +533,8 @@ github.com/sylabs/scs-build-client v0.1.4/go.mod h1:HxxopmlbGhWbHjaLBlTlcnV10NuMJnbf90Lj9yyW+YA= github.com/sylabs/scs-key-client v0.5.1 h1:Gig1O0Rs926UJtXyKJLAYn5Kn2Wmi3g5VupOWNizvnE= github.com/sylabs/scs-key-client v0.5.1/go.mod h1:iKD05EsmJMGaxKhcjjwh/thEShfaWmky1qo24zHE0pw= -github.com/sylabs/scs-library-client v0.5.5 h1:sjCtA1VbkZfGjdbbZ0SHbrCVOlqDmFLvjTqz2/m2u7Y= -github.com/sylabs/scs-library-client v0.5.5/go.mod h1:aGApgDIqM7Seuk0BHztl+vow4cY6NlDFS5jViCDu90U= +github.com/sylabs/scs-library-client v0.5.7 h1:qJACZ/rJByKle7HyeG/iGZxcc39vAJezVMDLr5YV73E= +github.com/sylabs/scs-library-client v0.5.7/go.mod h1:DqZKmwqx8B3PbYS0YrETlCVUviOTz+ZQewoLqWjU2AI= github.com/sylabs/sif v1.2.1 h1:BvNER55n5ppPzVO8TFxADfM8xMaZKdHur7BR5Yf3leE= github.com/sylabs/sif v1.2.1/go.mod h1:gLZA1tQWzKe8lr4Pt+iUP+rJUPcDXZJjs/142yRwmVE= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/pkg/image/unpacker/squashfs.go new/singularity/pkg/image/unpacker/squashfs.go --- old/singularity/pkg/image/unpacker/squashfs.go 2020-08-24 18:37:07.000000000 +0200 +++ new/singularity/pkg/image/unpacker/squashfs.go 2020-10-13 16:36:52.000000000 +0200 @@ -1,3 +1,4 @@ +// Copyright (c) 2020, Control Command Inc. All rights reserved. // Copyright (c) 2019, Sylabs Inc. All rights reserved. // This software is licensed under a 3-clause BSD license. Please consult the // LICENSE.md file distributed with the sources of this project regarding your @@ -17,6 +18,33 @@ "github.com/sylabs/singularity/pkg/sylog" ) +const ( + stdinFile = "/proc/self/fd/0" +) + +var cmdFunc func(unsquashfs string, dest string, filename string, rootless bool) (*exec.Cmd, error) + +// unsquashfsCmd is the command instance for executing unsquashfs command +// in a non sandboxed environment when this package is used for unit tests. +func unsquashfsCmd(unsquashfs string, dest string, filename string, rootless bool) (*exec.Cmd, error) { + args := make([]string, 0) + if rootless { + args = append(args, "-user-xattrs") + } + // remove the destination directory if any, if the directory is + // not empty (typically during image build), the unsafe option -f is + // set, this is unfortunately required by image build + if err := os.Remove(dest); err != nil && !os.IsNotExist(err) { + if !os.IsExist(err) { + return nil, fmt.Errorf("failed to remove %s: %s", dest, err) + } + // unsafe mode + args = append(args, "-f") + } + args = append(args, "-d", dest, filename) + return exec.Command(unsquashfs, args...), nil +} + // Squashfs represents a squashfs unpacker. type Squashfs struct { UnsquashfsPath string @@ -41,7 +69,7 @@ // pipe over stdin by default stdin := true - filename := "/proc/self/fd/0" + filename := stdinFile if _, ok := reader.(*os.File); !ok { // use the destination parent directory to store the @@ -71,9 +99,12 @@ // have to fall back to not using that option on failure. if os.Geteuid() != 0 { sylog.Debugf("Rootless extraction. Trying -user-xattrs for unsquashfs") - args := []string{"-user-xattrs", "-f", "-d", dest, filename} - args = append(args, files...) - cmd := exec.Command(s.UnsquashfsPath, args...) + + cmd, err := cmdFunc(s.UnsquashfsPath, dest, filename, true) + if err != nil { + return fmt.Errorf("command error: %s", err) + } + cmd.Args = append(cmd.Args, files...) if stdin { cmd.Stdin = reader } @@ -85,7 +116,7 @@ // Invalid options give output... // SYNTAX: unsquashfs [options] filesystem [directories or files to extract] - if bytes.HasPrefix(o, []byte("SYNTAX")) { + if bytes.Contains(o, []byte("SYNTAX")) { sylog.Warningf("unsquashfs does not support -user-xattrs. Images with system xattrs may fail to extract") } else { // A different error is fatal @@ -93,9 +124,11 @@ } } - args := []string{"-f", "-d", dest, filename} - args = append(args, files...) - cmd := exec.Command(s.UnsquashfsPath, args...) + cmd, err := cmdFunc(s.UnsquashfsPath, dest, filename, false) + if err != nil { + return fmt.Errorf("command error: %s", err) + } + cmd.Args = append(cmd.Args, files...) if stdin { cmd.Stdin = reader } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/pkg/image/unpacker/squashfs_no_singularity.go new/singularity/pkg/image/unpacker/squashfs_no_singularity.go --- old/singularity/pkg/image/unpacker/squashfs_no_singularity.go 1970-01-01 01:00:00.000000000 +0100 +++ new/singularity/pkg/image/unpacker/squashfs_no_singularity.go 2020-10-13 16:36:52.000000000 +0200 @@ -0,0 +1,12 @@ +// Copyright (c) 2020, Control Command Inc. All rights reserved. +// This software is licensed under a 3-clause BSD license. Please consult the +// LICENSE.md file distributed with the sources of this project regarding your +// rights to use or distribute this software. + +// +build !singularity_engine + +package unpacker + +func init() { + cmdFunc = unsquashfsCmd +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/pkg/image/unpacker/squashfs_singularity.go new/singularity/pkg/image/unpacker/squashfs_singularity.go --- old/singularity/pkg/image/unpacker/squashfs_singularity.go 1970-01-01 01:00:00.000000000 +0100 +++ new/singularity/pkg/image/unpacker/squashfs_singularity.go 2020-10-13 16:36:52.000000000 +0200 @@ -0,0 +1,228 @@ +// Copyright (c) 2020, Control Command Inc. All rights reserved. +// This software is licensed under a 3-clause BSD license. Please consult the +// LICENSE.md file distributed with the sources of this project regarding your +// rights to use or distribute this software. + +// +build singularity_engine + +package unpacker + +import ( + "bytes" + "debug/elf" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" + + "github.com/sylabs/singularity/internal/pkg/buildcfg" +) + +func init() { + cmdFunc = unsquashfsSandboxCmd +} + +// getLibraries returns the libraries required by the elf binary, +// the binary path must be absolute. +func getLibraries(binary string) ([]string, error) { + libs := make([]string, 0) + + exe, err := elf.Open(binary) + if err != nil { + return nil, err + } + defer exe.Close() + + interp := "" + + // look for the interpreter + for _, p := range exe.Progs { + if p.Type != elf.PT_INTERP { + continue + } + buf := make([]byte, 4096) + n, err := p.ReadAt(buf, 0) + if err != nil && err != io.EOF { + return nil, err + } else if n > cap(buf) { + return nil, fmt.Errorf("buffer too small to store interpreter") + } + // trim null byte to avoid an execution failure with + // an invalid argument error + interp = string(bytes.Trim(buf, "\x00")) + } + + // this is a static binary, nothing to do + if interp == "" { + return libs, nil + } + + // run interpreter to list library dependencies for the + // corresponding binary, eg: + // /lib64/ld-linux-x86-64.so.2 --list <program> + // /lib/ld-musl-x86_64.so.1 --list <program> + errBuf := new(bytes.Buffer) + buf := new(bytes.Buffer) + + cmd := exec.Command(interp, "--list", binary) + cmd.Stdout = buf + cmd.Stderr = errBuf + + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("while getting library dependencies: %s\n%s", err, errBuf.String()) + } + + // parse the output to get matches for ' /an/absolute/path (' + re := regexp.MustCompile(`[[:blank:]]?(\/.*)[[:blank:]]\(`) + + match := re.FindAllStringSubmatch(buf.String(), -1) + for _, m := range match { + if len(m) < 2 { + continue + } + lib := m[1] + has := false + for _, l := range libs { + if l == lib { + has = true + break + } + } + if !has { + libs = append(libs, lib) + } + } + + return libs, nil +} + +// unsquashfsSandboxCmd is the command instance for executing unsquashfs command +// in a sandboxed environment with singularity. +func unsquashfsSandboxCmd(unsquashfs string, dest string, filename string, rootless bool) (*exec.Cmd, error) { + const ( + // will contain both dest and filename inside the sandbox + rootfsImageDir = "/image" + ) + + // create the sandbox temporary directory + tmpdir := filepath.Dir(dest) + rootfs, err := ioutil.TempDir(tmpdir, "tmp-rootfs-") + if err != nil { + return nil, fmt.Errorf("failed to create chroot directory: %s", err) + } + + overwrite := false + + // remove the destination directory if any, if the directory is + // not empty (typically during image build), the unsafe option -f is + // set, this is unfortunately required by image build + if err := os.Remove(dest); err != nil && !os.IsNotExist(err) { + if !os.IsExist(err) { + return nil, fmt.Errorf("failed to remove %s: %s", dest, err) + } + overwrite = true + } + + // map destination into the sandbox + rootfsDest := filepath.Join(rootfsImageDir, filepath.Base(dest)) + + // sandbox required directories + rootfsDirs := []string{ + // unsquashfs get available CPU from /sys/devices/system/cpu/online + filepath.Join(rootfs, "/sys"), + filepath.Join(rootfs, "/dev"), + filepath.Join(rootfs, rootfsImageDir), + } + + for _, d := range rootfsDirs { + if err := os.Mkdir(d, 0700); err != nil { + return nil, fmt.Errorf("while creating %s: %s", d, err) + } + } + + // the decision to use user namespace is left to singularity + // which will detect automatically depending of the configuration + // what workflow it could use + args := []string{ + "-q", + "exec", + "--no-home", + "--no-nv", + "--no-rocm", + "-C", + "--no-init", + "--writable", + "-B", fmt.Sprintf("%s:%s", tmpdir, rootfsImageDir), + } + + if filename != stdinFile { + filename = filepath.Join(rootfsImageDir, filepath.Base(filename)) + } + + // get the library dependencies of unsquashfs + libs, err := getLibraries(unsquashfs) + if err != nil { + return nil, err + } + libraryPath := make([]string, 0) + + roFiles := []string{ + unsquashfs, + } + + // add libraries for bind mount and also generate + // LD_LIBRARY_PATH + for _, l := range libs { + dir := filepath.Dir(l) + roFiles = append(roFiles, l) + has := false + for _, lp := range libraryPath { + if lp == dir { + has = true + break + } + } + if !has { + libraryPath = append(libraryPath, dir) + } + } + + // create files and directories in the sandbox and + // add singularity bind mount options + for _, b := range roFiles { + file := filepath.Join(rootfs, b) + dir := filepath.Dir(file) + if err := os.MkdirAll(dir, 0700); err != nil { + return nil, fmt.Errorf("while creating %s: %s", dir, err) + } + if err := ioutil.WriteFile(file, []byte(""), 0600); err != nil { + return nil, fmt.Errorf("while creating %s: %s", file, err) + } + args = append(args, "-B", fmt.Sprintf("%s:%s:ro", b, b)) + } + + // singularity sandbox + args = append(args, rootfs) + + // unsquashfs execution arguments + args = append(args, unsquashfs) + if rootless { + args = append(args, "-user-xattrs") + } + if overwrite { + args = append(args, "-f") + } + args = append(args, "-d", rootfsDest, filename) + + cmd := exec.Command(filepath.Join(buildcfg.BINDIR, "singularity"), args...) + cmd.Dir = "/" + cmd.Env = []string{ + fmt.Sprintf("LD_LIBRARY_PATH=%s", strings.Join(libraryPath, string(os.PathListSeparator))), + } + + return cmd, nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/pkg/image/unpacker/squashfs_test.go new/singularity/pkg/image/unpacker/squashfs_test.go --- old/singularity/pkg/image/unpacker/squashfs_test.go 2020-07-19 23:38:50.000000000 +0200 +++ new/singularity/pkg/image/unpacker/squashfs_test.go 2020-10-13 16:36:52.000000000 +0200 @@ -1,3 +1,4 @@ +// Copyright (c) 2020, Control Command Inc. All rights reserved. // Copyright (c) 2019, Sylabs Inc. All rights reserved. // This software is licensed under a 3-clause BSD license. Please consult the // LICENSE.md file distributed with the sources of this project regarding your @@ -106,3 +107,8 @@ t.Errorf("file extraction failed, %s is missing", path) } } + +func TestMain(m *testing.M) { + cmdFunc = unsquashfsCmd + os.Exit(m.Run()) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/singularity.spec new/singularity/singularity.spec --- old/singularity/singularity.spec 2020-09-15 16:11:43.000000000 +0200 +++ new/singularity/singularity.spec 2020-10-13 16:38:57.000000000 +0200 @@ -29,12 +29,12 @@ Summary: Application and environment virtualization Name: singularity -Version: 3.6.3 +Version: 3.6.4 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.3.tar.gz +Source: %{name}-3.6.4.tar.gz ExclusiveOS: linux # RPM_BUILD_ROOT wasn't being set ... for some reason %if "%{sles_version}" == "11" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go new/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go --- old/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go 2020-09-15 16:11:54.000000000 +0200 +++ new/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go 2020-10-13 16:39:02.000000000 +0200 @@ -24,6 +24,9 @@ // prevent a round-trip to the server. The server will return HTTP status // 400 if the requsted multipart upload size is less than 5MiB. minimumPartSize = 64 * 1024 * 1024 + + // OptionS3Compliant indicates a 100% S3 compatible object store is being used by backend library server + OptionS3Compliant = "s3compliant" ) // UploadCallback defines an interface used to perform a call-out to @@ -307,6 +310,12 @@ c.Logger.Logf("Multi-part upload: ID=[%s] totalParts=[%d] partSize=[%d]", response.UploadID, response.TotalParts, fileSize) + // Enable S3 compliancy mode by default + val := response.Options[OptionS3Compliant] + s3Compliant := val == "" || val == "true" + + c.Logger.Logf("S3 compliant option: %v", s3Compliant) + // maintain list of completed parts which will be passed to the completion function completedParts := []CompletedPart{} @@ -324,12 +333,16 @@ UploadID: response.UploadID, } - etag, err := c.multipartUploadPart(ctx, nPart, mgr, callback) + // include "X-Amz-Content-Sha256" header only if object store is 100% S3 compatible + etag, err := c.multipartUploadPart(ctx, nPart, mgr, callback, s3Compliant) if err != nil { // error uploading part c.Logger.Logf("Error uploading part %d: %v", nPart, err) - return c.abortMultipartUpload(ctx, mgr) + if err := c.abortMultipartUpload(ctx, mgr); err != nil { + c.Logger.Logf("Error aborting multipart upload: %v", err) + } + return err } // append completed part info to list @@ -470,18 +483,23 @@ return chunkHash, err } -func (c *Client) multipartUploadPart(ctx context.Context, partNumber int, m *uploadManager, callback UploadCallback) (string, error) { - // calculate sha256sum of part being uploaded - chunkHash, err := getPartSHA256Sum(m.Source, int64(m.Size)) - if err != nil { - c.Logger.Logf("Error calculating SHA256 checksum: %v", err) - return "", err - } +func (c *Client) multipartUploadPart(ctx context.Context, partNumber int, m *uploadManager, callback UploadCallback, includeSHA256ChecksumHeader bool) (string, error) { + var chunkHash string + var err error + + if includeSHA256ChecksumHeader { + // calculate sha256sum of part being uploaded + chunkHash, err = getPartSHA256Sum(m.Source, int64(m.Size)) + if err != nil { + c.Logger.Logf("Error calculating SHA256 checksum: %v", err) + return "", err + } - // rollback file pointer to beginning of part - if _, err := m.Source.Seek(-(int64(m.Size)), io.SeekCurrent); err != nil { - c.Logger.Logf("Error repositioning file pointer: %v", err) - return "", err + // rollback file pointer to beginning of part + if _, err := m.Source.Seek(-(int64(m.Size)), io.SeekCurrent); err != nil { + c.Logger.Logf("Error repositioning file pointer: %v", err) + return "", err + } } // send request to cloud-library for presigned PUT url @@ -512,7 +530,9 @@ // add headers to be signed req.ContentLength = m.Size - req.Header.Add("x-amz-content-sha256", chunkHash) + if includeSHA256ChecksumHeader { + req.Header.Add("x-amz-content-sha256", chunkHash) + } resp, err := http.DefaultClient.Do(req.WithContext(ctx)) if err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go new/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go --- old/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go 2020-09-15 16:11:54.000000000 +0200 +++ new/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go 2020-10-13 16:39:02.000000000 +0200 @@ -72,9 +72,10 @@ // MultipartUpload - Contains data for multipart image upload start request type MultipartUpload struct { - UploadID string `json:"uploadID"` - TotalParts int `json:"totalParts"` - PartSize int64 `json:"partSize"` + UploadID string `json:"uploadID"` + TotalParts int `json:"totalParts"` + PartSize int64 `json:"partSize"` + Options map[string]string `json:"options"` } // MultipartUploadStartResponse - Response from the API for a multipart image upload start request diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/singularity/vendor/modules.txt new/singularity/vendor/modules.txt --- old/singularity/vendor/modules.txt 2020-09-15 16:11:54.000000000 +0200 +++ new/singularity/vendor/modules.txt 2020-10-13 16:39:02.000000000 +0200 @@ -369,7 +369,7 @@ github.com/sylabs/scs-build-client/client # github.com/sylabs/scs-key-client v0.5.1 github.com/sylabs/scs-key-client/client -# github.com/sylabs/scs-library-client v0.5.5 +# github.com/sylabs/scs-library-client v0.5.7 github.com/sylabs/scs-library-client/client # github.com/sylabs/sif v1.2.1 github.com/sylabs/sif/internal/app/siftool