[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#990880: marked as done (unblock: nomad/0.12.10+dfsg1-3)



Your message dated Sun, 11 Jul 2021 10:10:18 +0200
with message-id <CAM8zJQuVk3HPSy0ejot8n4yx9DrW+KO3Yo8hbZmh1EesZJzezQ@mail.gmail.com>
and subject line Re: Bug#990880: unblock: nomad/0.12.10+dfsg1-3
has caused the Debian Bug report #990880,
regarding unblock: nomad/0.12.10+dfsg1-3
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
990880: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=990880
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: team+pkg-go@tracker.debian.org

This is a pre-approval request before I upload nomad to unstable to
fix a security problem (CVE-2021-32575). Thanks in advance, and keep
up the great work!

[ Reason ]
See #990581 for more information: there is a CAP_NET_RAW capability
issue in Nomad that is fixed in a later upstream version.

[ Impact ]
Quoted from https://discuss.hashicorp.com/t/hcsec-2021-14-nomad-bridge-networking-mode-allows-arp-spoofing-from-other-bridged-tasks-on-same-node/24296

  It was discovered that processes launched by the docker, exec, and java
  task drivers that make use of Nomad’s bridge networking mode can
  perform ARP spoofing attacks against other tasks on the same node.
  Specifically, tasks making use of bridge networking are susceptible to
  other tasks on the same node performing DoS and MITM attacks due to the
  default enablement of the CAP_NET_RAW 6 Linux capability by these task
  drivers.

[ Tests ]
The upstream patch adds unit tests to the package's test suite.

[ Risks ]
The patch is not trivial, but its logic is not hard to follow.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

unblock nomad/0.12.10+dfsg1-3
diff -Nru nomad-0.12.10+dfsg1/debian/changelog nomad-0.12.10+dfsg1/debian/changelog
--- nomad-0.12.10+dfsg1/debian/changelog	2021-05-09 10:14:36.000000000 +0300
+++ nomad-0.12.10+dfsg1/debian/changelog	2021-07-10 02:29:09.000000000 +0300
@@ -1,3 +1,11 @@
+nomad (0.12.10+dfsg1-3) unstable; urgency=medium
+
+  * Team upload.
+  * Adapt the upstream patch for CVE-2021-32575 and add it as
+    the disable-cap-net-raw patch. Closes: #990581
+
+ -- Peter Pentchev <roam@debian.org>  Sat, 10 Jul 2021 02:29:09 +0300
+
 nomad (0.12.10+dfsg1-2) unstable; urgency=medium
 
   * Disabled "TestConfig_outgoingWrapper_OK" (Closes: #987644).
diff -Nru nomad-0.12.10+dfsg1/debian/patches/disable-cap-net-raw.patch nomad-0.12.10+dfsg1/debian/patches/disable-cap-net-raw.patch
--- nomad-0.12.10+dfsg1/debian/patches/disable-cap-net-raw.patch	1970-01-01 02:00:00.000000000 +0200
+++ nomad-0.12.10+dfsg1/debian/patches/disable-cap-net-raw.patch	2021-07-05 23:47:53.000000000 +0300
@@ -0,0 +1,592 @@
+Description: drivers/docker+exec+java: disable net_raw capability by default
+ The default Linux Capabilities set enabled by the docker, exec, and
+ java task drivers includes CAP_NET_RAW (for making ping just work),
+ which has the side affect of opening an ARP DoS/MiTM attack between
+ tasks using bridge networking on the same host network.
+ .
+ https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
+ .
+ This PR disables CAP_NET_RAW for the docker, exec, and java task
+ drivers. The previous behavior can be restored for docker using the
+ allow_caps docker plugin configuration option.
+ .
+ A future version of nomad will enable similar configurability for the
+ exec and java task drivers.
+ .
+ Note (Debian): The upstream patch was adapted because of code changes.
+Origin: upstream; https://github.com/hashicorp/nomad/commit/003d68fe6df652b172bc68beabd11a25fd7e1b58
+Author: Seth Hoenig <shoenig@hashicorp.com>
+Bug-Debian: https://bugs.debian.org/990581
+Last-Update: 2021-07-05
+
+--- a/drivers/docker/config.go
++++ b/drivers/docker/config.go
+@@ -35,17 +35,41 @@
+ 	// it is timed out.
+ 	dockerTimeout = 5 * time.Minute
+ 
+-	// dockerBasicCaps is comma-separated list of Linux capabilities that are
+-	// allowed by docker by default, as documented in
+-	// https://docs.docker.com/engine/reference/run/#block-io-bandwidth-blkio-constraint
+-	dockerBasicCaps = "CHOWN,DAC_OVERRIDE,FSETID,FOWNER,MKNOD,NET_RAW,SETGID," +
+-		"SETUID,SETFCAP,SETPCAP,NET_BIND_SERVICE,SYS_CHROOT,KILL,AUDIT_WRITE"
+-
+ 	// dockerAuthHelperPrefix is the prefix to attach to the credential helper
+ 	// and should be found in the $PATH. Example: ${prefix-}${helper-name}
+ 	dockerAuthHelperPrefix = "docker-credential-"
+ )
+ 
++// nomadDefaultCaps is the subset of dockerDefaultCaps that Nomad enables by
++// default and is used to compute the set of capabilities to add/drop given
++// docker driver configuration.
++func nomadDefaultCaps() []string {
++	return []string{
++		"AUDIT_WRITE",
++		"CHOWN",
++		"DAC_OVERRIDE",
++		"FOWNER",
++		"FSETID",
++		"KILL",
++		"MKNOD",
++		"NET_BIND_SERVICE",
++		"SETFCAP",
++		"SETGID",
++		"SETPCAP",
++		"SETUID",
++		"SYS_CHROOT",
++	}
++}
++
++// dockerDefaultCaps is a list of Linux capabilities enabled by docker by default
++// and is used to compute the set of capabilities to add/drop given docker driver
++// configuration, as well as Nomad built-in limitations.
++//
++// https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
++func dockerDefaultCaps() []string {
++	return append(nomadDefaultCaps(), "NET_RAW")
++}
++
+ func PluginLoader(opts map[string]string) (map[string]interface{}, error) {
+ 	conf := map[string]interface{}{}
+ 	if v, ok := opts["docker.endpoint"]; ok {
+@@ -243,7 +267,7 @@
+ 		"allow_privileged": hclspec.NewAttr("allow_privileged", "bool", false),
+ 		"allow_caps": hclspec.NewDefault(
+ 			hclspec.NewAttr("allow_caps", "list(string)", false),
+-			hclspec.NewLiteral(`["CHOWN","DAC_OVERRIDE","FSETID","FOWNER","MKNOD","NET_RAW","SETGID","SETUID","SETFCAP","SETPCAP","NET_BIND_SERVICE","SYS_CHROOT","KILL","AUDIT_WRITE"]`),
++			hclspec.NewLiteral(`["CHOWN","DAC_OVERRIDE","FSETID","FOWNER","MKNOD","SETGID","SETUID","SETFCAP","SETPCAP","NET_BIND_SERVICE","SYS_CHROOT","KILL","AUDIT_WRITE"]`),
+ 		),
+ 		"nvidia_runtime": hclspec.NewDefault(
+ 			hclspec.NewAttr("nvidia_runtime", "string", false),
+--- a/drivers/docker/driver.go
++++ b/drivers/docker/driver.go
+@@ -10,6 +10,7 @@
+ 	"os"
+ 	"path/filepath"
+ 	"runtime"
++	"sort"
+ 	"strconv"
+ 	"strings"
+ 	"sync"
+@@ -23,7 +24,9 @@
+ 	"github.com/hashicorp/nomad/client/taskenv"
+ 	"github.com/hashicorp/nomad/drivers/docker/docklog"
+ 	"github.com/hashicorp/nomad/drivers/shared/eventer"
++	"github.com/hashicorp/nomad/drivers/shared/executor"
+ 	"github.com/hashicorp/nomad/drivers/shared/resolvconf"
++	"github.com/hashicorp/nomad/helper"
+ 	nstructs "github.com/hashicorp/nomad/nomad/structs"
+ 	"github.com/hashicorp/nomad/plugins/base"
+ 	"github.com/hashicorp/nomad/plugins/drivers"
+@@ -892,30 +895,12 @@
+ 		hostCapsWhitelist[cap] = struct{}{}
+ 	}
+ 
+-	if _, ok := hostCapsWhitelist["all"]; !ok {
+-		effectiveCaps, err := tweakCapabilities(
+-			strings.Split(dockerBasicCaps, ","),
+-			driverConfig.CapAdd,
+-			driverConfig.CapDrop,
+-		)
+-		if err != nil {
+-			return c, err
+-		}
+-		var missingCaps []string
+-		for _, cap := range effectiveCaps {
+-			cap = strings.ToLower(cap)
+-			if _, ok := hostCapsWhitelist[cap]; !ok {
+-				missingCaps = append(missingCaps, cap)
+-			}
+-		}
+-		if len(missingCaps) > 0 {
+-			return c, fmt.Errorf("Docker driver doesn't have the following caps whitelisted on this Nomad agent: %s", missingCaps)
+-		}
++	// set add/drop capabilities
++	hostConfig.CapAdd, hostConfig.CapDrop, err = d.getCaps(driverConfig)
++	if err != nil {
++		return c, err
+ 	}
+ 
+-	hostConfig.CapAdd = driverConfig.CapAdd
+-	hostConfig.CapDrop = driverConfig.CapDrop
+-
+ 	// set SHM size
+ 	if driverConfig.ShmSize != 0 {
+ 		hostConfig.ShmSize = driverConfig.ShmSize
+@@ -1166,6 +1151,119 @@
+ 	}, nil
+ }
+ 
++// getCaps computes the capabilities to supply to the --add-cap and --drop-cap
++// options to the docker driver, which override the default capabilities enabled
++// by docker itself.
++func (d *Driver) getCaps(taskConfig *TaskConfig) ([]string, []string, error) {
++
++	// capabilities allowable by client docker plugin configuration
++	allowCaps := expandAllowCaps(d.config.AllowCaps)
++
++	// capabilities the task docker config is asking for based on the default
++	// capabilities allowable by nomad
++	desiredCaps, err := tweakCapabilities(nomadDefaultCaps(), taskConfig.CapAdd, taskConfig.CapDrop)
++	if err != nil {
++		return nil, nil, err
++	}
++
++	// capabilities the task is requesting that are NOT allowed by the docker plugin
++	if missing := missingCaps(allowCaps, desiredCaps); len(missing) > 0 {
++		return nil, nil, fmt.Errorf("Docker driver does not have the following caps allow-listed on this Nomad agent: %s", missing)
++	}
++
++	// capabilities that should be dropped relative to the docker default capabilities
++	dropCaps := capDrops(taskConfig.CapDrop, allowCaps)
++
++	return taskConfig.CapAdd, dropCaps, nil
++}
++
++// capDrops will compute the total dropped capabilities set
++//
++// {task cap_drop} U ({docker defaults} \ {driver allow caps})
++func capDrops(dropCaps []string, allowCaps []string) []string {
++	dropSet := make(map[string]struct{})
++
++	for _, c := range normalizeCaps(dropCaps) {
++		dropSet[c] = struct{}{}
++	}
++
++	// if dropCaps includes ALL, no need to iterate every capability
++	if _, exists := dropSet["ALL"]; exists {
++		return []string{"ALL"}
++	}
++
++	dockerDefaults := helper.SliceStringToSet(normalizeCaps(dockerDefaultCaps()))
++	allowedCaps := helper.SliceStringToSet(normalizeCaps(allowCaps))
++
++	// find the docker default caps not in allowed caps
++	for dCap := range dockerDefaults {
++		if _, exists := allowedCaps[dCap]; !exists {
++			dropSet[dCap] = struct{}{}
++		}
++	}
++
++	drops := make([]string, 0, len(dropSet))
++	for c := range dropSet {
++		drops = append(drops, c)
++	}
++	sort.Strings(drops)
++	return drops
++}
++
++// expandAllowCaps returns the normalized set of allowable capabilities set
++// for the docker plugin configuration.
++func expandAllowCaps(allowCaps []string) []string {
++	if len(allowCaps) == 0 {
++		return nil
++	}
++
++	set := make(map[string]struct{}, len(allowCaps))
++
++	for _, rawCap := range allowCaps {
++		capability := strings.ToUpper(rawCap)
++		if capability == "ALL" {
++			for _, defCap := range normalizeCaps(executor.SupportedCaps(true)) {
++				set[defCap] = struct{}{}
++			}
++		} else {
++			set[capability] = struct{}{}
++		}
++	}
++
++	result := make([]string, 0, len(set))
++	for capability := range set {
++		result = append(result, capability)
++	}
++	sort.Strings(result)
++	return result
++}
++
++// missingCaps returns the set of elements in desired that are not present in
++// allowed. The elements in desired are first upper-cased before comparison.
++// The elements in allowed are assumed to be upper-cased.
++func missingCaps(allowed, desired []string) []string {
++	_, missing := helper.SliceStringIsSubset(allowed, normalizeCaps(desired))
++	sort.Strings(missing)
++	return missing
++}
++
++// normalizeCaps returns a copy of caps with duplicate elements removed and all
++// elements upper-cased.
++func normalizeCaps(caps []string) []string {
++	set := make(map[string]struct{}, len(caps))
++	for _, c := range caps {
++		normal := strings.TrimPrefix(strings.ToUpper(c), "CAP_")
++		set[strings.ToUpper(normal)] = struct{}{}
++	}
++
++	result := make([]string, 0, len(set))
++	for c := range set {
++		result = append(result, c)
++	}
++	sort.Strings(result)
++	return result
++}
++
+ // detectIP of Docker container. Returns the first IP found as well as true if
+ // the IP should be advertised (bridge network IPs return false). Returns an
+ // empty string and false if no IP could be found.
+--- a/drivers/docker/driver_test.go
++++ b/drivers/docker/driver_test.go
+@@ -17,6 +17,7 @@
+ 	hclog "github.com/hashicorp/go-hclog"
+ 	"github.com/hashicorp/nomad/client/taskenv"
+ 	"github.com/hashicorp/nomad/client/testutil"
++	"github.com/hashicorp/nomad/drivers/shared/executor"
+ 	"github.com/hashicorp/nomad/helper/freeport"
+ 	"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils"
+ 	"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
+@@ -1240,44 +1241,44 @@
+ 		{
+ 			Name:    "default-whitelist-add-allowed",
+ 			CapAdd:  []string{"fowner", "mknod"},
+-			CapDrop: []string{"all"},
++			CapDrop: []string{"ALL"},
+ 		},
+ 		{
+ 			Name:       "default-whitelist-add-forbidden",
+ 			CapAdd:     []string{"net_admin"},
+-			StartError: "net_admin",
++			StartError: "NET_ADMIN",
+ 		},
+ 		{
+ 			Name:    "default-whitelist-drop-existing",
+-			CapDrop: []string{"fowner", "mknod"},
++			CapDrop: []string{"FOWNER", "MKNOD", "NET_RAW"},
+ 		},
+ 		{
+ 			Name:      "restrictive-whitelist-drop-all",
+-			CapDrop:   []string{"all"},
+-			Whitelist: "fowner,mknod",
++			CapDrop:   []string{"ALL"},
++			Allowlist: "FOWNER,MKNOD",
+ 		},
+ 		{
+ 			Name:      "restrictive-whitelist-add-allowed",
+ 			CapAdd:    []string{"fowner", "mknod"},
+-			CapDrop:   []string{"all"},
++			CapDrop:   []string{"ALL"},
+ 			Whitelist: "fowner,mknod",
+ 		},
+ 		{
+ 			Name:       "restrictive-whitelist-add-forbidden",
+ 			CapAdd:     []string{"net_admin", "mknod"},
+-			CapDrop:    []string{"all"},
++			CapDrop:    []string{"ALL"},
+ 			Whitelist:  "fowner,mknod",
+-			StartError: "net_admin",
++			StartError: "NET_ADMIN",
+ 		},
+ 		{
+ 			Name:      "permissive-whitelist",
+ 			CapAdd:    []string{"net_admin", "mknod"},
+-			Whitelist: "all",
++			Allowlist: "ALL",
+ 		},
+ 		{
+ 			Name:      "permissive-whitelist-add-all",
+ 			CapAdd:    []string{"all"},
+-			Whitelist: "all",
++			Allowlist: "ALL",
+ 		},
+ 	}
+ 
+@@ -2674,3 +2675,169 @@
+ 		require.Equal(t, int64(256*1024*1024), memoryReservation)
+ 	})
+ }
++
++func TestDockerCaps_normalizeCaps(t *testing.T) {
++	t.Run("empty", func(t *testing.T) {
++		result := normalizeCaps(nil)
++		require.Len(t, result, 0)
++	})
++
++	t.Run("mixed", func(t *testing.T) {
++		result := normalizeCaps([]string{
++			"DAC_OVERRIDE", "sys_chroot", "kill", "KILL",
++		})
++		require.Equal(t, []string{
++			"DAC_OVERRIDE", "KILL", "SYS_CHROOT",
++		}, result)
++	})
++}
++
++func TestDockerCaps_missingCaps(t *testing.T) {
++	allowed := []string{
++		"DAC_OVERRIDE", "SYS_CHROOT", "KILL", "CHOWN",
++	}
++
++	t.Run("none missing", func(t *testing.T) {
++		result := missingCaps(allowed, []string{
++			"SYS_CHROOT", "chown", "KILL",
++		})
++		require.Equal(t, []string(nil), result)
++	})
++
++	t.Run("some missing", func(t *testing.T) {
++		result := missingCaps(allowed, []string{
++			"chown", "audit_write", "SETPCAP", "dac_override",
++		})
++		require.Equal(t, []string{"AUDIT_WRITE", "SETPCAP"}, result)
++	})
++}
++
++func TestDockerCaps_expandAllowCaps(t *testing.T) {
++	t.Run("empty", func(t *testing.T) {
++		result := expandAllowCaps(nil)
++		require.Empty(t, result)
++	})
++
++	t.Run("manual", func(t *testing.T) {
++		result := expandAllowCaps([]string{
++			"DAC_OVERRIDE", "SYS_CHROOT", "KILL", "CHOWN",
++		})
++		require.Equal(t, []string{
++			"CHOWN", "DAC_OVERRIDE", "KILL", "SYS_CHROOT",
++		}, result)
++	})
++
++	t.Run("all", func(t *testing.T) {
++		result := expandAllowCaps([]string{"all"})
++		exp := normalizeCaps(executor.SupportedCaps(true))
++		sort.Strings(exp)
++		require.Equal(t, exp, result)
++	})
++}
++
++func TestDockerCaps_capDrops(t *testing.T) {
++	// docker default caps is always the same, task configured drop_caps and
++	// plugin config allow_caps may be altered
++
++	// This is the 90% use case, where NET_RAW is dropped, as Nomad's default
++	// capability allow-list is a subset of the docker default cap list.
++	t.Run("defaults", func(t *testing.T) {
++		result := capDrops(nil, nomadDefaultCaps())
++		require.Equal(t, []string{"NET_RAW"}, result)
++	})
++
++	// Users want to use ICMP (ping).
++	t.Run("enable net_raw", func(t *testing.T) {
++		result := capDrops(nil, append(nomadDefaultCaps(), "net_raw"))
++		require.Empty(t, result)
++	})
++
++	// The plugin is reduced in ability.
++	t.Run("enable minimal", func(t *testing.T) {
++		allow := []string{"setgid", "setuid", "chown", "kill"}
++		exp := []string{"AUDIT_WRITE", "DAC_OVERRIDE", "FOWNER", "FSETID", "MKNOD", "NET_BIND_SERVICE", "NET_RAW", "SETFCAP", "SETPCAP", "SYS_CHROOT"}
++		result := capDrops(nil, allow)
++		require.Equal(t, exp, result)
++	})
++
++	// The task drops abilities.
++	t.Run("task drops", func(t *testing.T) {
++		drops := []string{"audit_write", "fowner", "kill", "chown"}
++		exp := []string{"AUDIT_WRITE", "CHOWN", "FOWNER", "KILL", "NET_RAW"}
++		result := capDrops(drops, nomadDefaultCaps())
++		require.Equal(t, exp, result)
++	})
++
++	// Drop all mixed with others.
++	t.Run("task drops mix", func(t *testing.T) {
++		drops := []string{"audit_write", "all", "chown"}
++		exp := []string{"ALL"} // minimized
++		result := capDrops(drops, nomadDefaultCaps())
++		require.Equal(t, exp, result)
++	})
++}
++
++func TestDockerCaps_getCaps(t *testing.T) {
++	testutil.ExecCompatible(t) // tests require linux
++
++	t.Run("defaults", func(t *testing.T) {
++		d := Driver{config: &DriverConfig{
++			AllowCaps: nomadDefaultCaps(),
++		}}
++		add, drop, err := d.getCaps(&TaskConfig{
++			CapAdd: nil, CapDrop: nil,
++		})
++		require.NoError(t, err)
++		require.Empty(t, add)
++		require.Equal(t, []string{"NET_RAW"}, drop)
++	})
++
++	t.Run("enable net_raw", func(t *testing.T) {
++		d := Driver{config: &DriverConfig{
++			AllowCaps: append(nomadDefaultCaps(), "net_raw"),
++		}}
++		add, drop, err := d.getCaps(&TaskConfig{
++			CapAdd: nil, CapDrop: nil,
++		})
++		require.NoError(t, err)
++		require.Empty(t, add)
++		require.Empty(t, drop)
++	})
++
++	t.Run("block sys_time", func(t *testing.T) {
++		d := Driver{config: &DriverConfig{
++			AllowCaps: nomadDefaultCaps(),
++		}}
++		_, _, err := d.getCaps(&TaskConfig{
++			CapAdd:  []string{"SYS_TIME"},
++			CapDrop: nil,
++		})
++		require.EqualError(t, err, `Docker driver does not have the following caps allow-listed on this Nomad agent: [SYS_TIME]`)
++	})
++
++	t.Run("enable sys_time", func(t *testing.T) {
++		d := Driver{config: &DriverConfig{
++			AllowCaps: append(nomadDefaultCaps(), "sys_time"),
++		}}
++		add, drop, err := d.getCaps(&TaskConfig{
++			CapAdd:  []string{"SYS_TIME"},
++			CapDrop: nil,
++		})
++		require.NoError(t, err)
++		require.Equal(t, []string{"SYS_TIME"}, add)
++		require.Equal(t, []string{"NET_RAW"}, drop)
++	})
++
++	t.Run("task drops chown", func(t *testing.T) {
++		d := Driver{config: &DriverConfig{
++			AllowCaps: nomadDefaultCaps(),
++		}}
++		add, drop, err := d.getCaps(&TaskConfig{
++			CapAdd:  nil,
++			CapDrop: []string{"chown"},
++		})
++		require.NoError(t, err)
++		require.Empty(t, add)
++		require.Equal(t, []string{"CHOWN", "NET_RAW"}, drop)
++	})
++}
+--- a/drivers/shared/executor/executor.go
++++ b/drivers/shared/executor/executor.go
+@@ -23,6 +23,7 @@
+ 	cstructs "github.com/hashicorp/nomad/client/structs"
+ 	"github.com/hashicorp/nomad/plugins/drivers"
+ 	"github.com/kr/pty"
++	"github.com/syndtr/gocapability/capability"
+ 
+ 	shelpers "github.com/hashicorp/nomad/helper/stats"
+ )
+@@ -663,3 +664,23 @@
+ 	}
+ 	return nil
+ }
++
++// SupportedCaps returns a list of all supported capabilities in kernel.
++func SupportedCaps(allowNetRaw bool) []string {
++	var allCaps []string
++	last := capability.CAP_LAST_CAP
++	// workaround for RHEL6 which has no /proc/sys/kernel/cap_last_cap
++	if last == capability.Cap(63) {
++		last = capability.CAP_BLOCK_SUSPEND
++	}
++	for _, cap := range capability.List() {
++		if cap > last {
++			continue
++		}
++		if !allowNetRaw && cap == capability.CAP_NET_RAW {
++			continue
++		}
++		allCaps = append(allCaps, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())))
++	}
++	return allCaps
++}
+--- a/drivers/shared/executor/executor_linux.go
++++ b/drivers/shared/executor/executor_linux.go
+@@ -30,7 +30,6 @@
+ 	ldevices "github.com/opencontainers/runc/libcontainer/devices"
+ 	"github.com/opencontainers/runc/libcontainer/specconv"
+ 	lutils "github.com/opencontainers/runc/libcontainer/utils"
+-	"github.com/syndtr/gocapability/capability"
+ 	"golang.org/x/sys/unix"
+ )
+ 
+@@ -522,12 +521,12 @@
+ }
+ 
+ func configureCapabilities(cfg *lconfigs.Config, command *ExecCommand) error {
+-	// TODO: allow better control of these
++	// TODO(shoenig): allow better control of these
+ 	// use capabilities list as prior to adopting libcontainer in 0.9
+-	allCaps := supportedCaps()
+ 
+ 	// match capabilities used in Nomad 0.8
+ 	if command.User == "root" {
++		allCaps := SupportedCaps(true)
+ 		cfg.Capabilities = &lconfigs.Capabilities{
+ 			Bounding:    allCaps,
+ 			Permitted:   allCaps,
+@@ -536,6 +535,7 @@
+ 			Inheritable: nil,
+ 		}
+ 	} else {
++		allCaps := SupportedCaps(false)
+ 		cfg.Capabilities = &lconfigs.Capabilities{
+ 			Bounding: allCaps,
+ 		}
+@@ -544,23 +544,6 @@
+ 	return nil
+ }
+ 
+-// supportedCaps returns a list of all supported capabilities in kernel
+-func supportedCaps() []string {
+-	allCaps := []string{}
+-	last := capability.CAP_LAST_CAP
+-	// workaround for RHEL6 which has no /proc/sys/kernel/cap_last_cap
+-	if last == capability.Cap(63) {
+-		last = capability.CAP_BLOCK_SUSPEND
+-	}
+-	for _, cap := range capability.List() {
+-		if cap > last {
+-			continue
+-		}
+-		allCaps = append(allCaps, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())))
+-	}
+-	return allCaps
+-}
+-
+ // configureIsolation prepares the isolation primitives of the container.
+ // The process runs in a container configured with the following:
+ //
+--- a/drivers/shared/executor/executor_linux_test.go
++++ b/drivers/shared/executor/executor_linux_test.go
+@@ -403,7 +403,7 @@
+ CapInh: 0000000000000000
+ CapPrm: 0000000000000000
+ CapEff: 0000000000000000
+-CapBnd: 0000003fffffffff
++CapBnd: 0000003fffffdfff
+ CapAmb: 0000000000000000`,
+ 		},
+ 		{
diff -Nru nomad-0.12.10+dfsg1/debian/patches/series nomad-0.12.10+dfsg1/debian/patches/series
--- nomad-0.12.10+dfsg1/debian/patches/series	2021-05-09 10:14:36.000000000 +0300
+++ nomad-0.12.10+dfsg1/debian/patches/series	2021-07-05 23:47:53.000000000 +0300
@@ -6,3 +6,4 @@
 runc-rc93.patch
 
 t-skip-unreliable-tests.patch
+disable-cap-net-raw.patch

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
On Sat, 10 Jul 2021 at 23:13, Salvatore Bonaccorso <carnil@debian.org> wrote:
> Removed the moreinfo tag as the builds are now there on all
> architectures, but I'm replying here due to the following: I was
> checking the status for this, given it involved a CVE, and noticed
> that for s390x there was a build failure. Only after giving back two
> times nomad was build there as well, cf.:
>
> https://buildd.debian.org/status/logs.php?pkg=nomad&arch=s390x
>
> Is this a known issue?

It looks like it started with 0.12.10+dfsg1-2, and I don't see a FTBFS
bug filed yet.

Unblocked anyway, since it's not a regression in the new upload.

--- End Message ---

Reply to: