Skip to content

Commit adf54cd

Browse files
committed
Add support for --security-opt mask and unmask
Fixes: #5881 Signed-off-by: Daniel J Walsh <[email protected]>
1 parent 996c49d commit adf54cd

File tree

8 files changed

+63
-3
lines changed

8 files changed

+63
-3
lines changed

define/build.go

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ type CommonBuildOptions struct {
6262
// LabelOpts is a slice of the fields of an SELinux context, given in "field:pair" format, or "disable".
6363
// Recognized field names are "role", "type", and "level".
6464
LabelOpts []string
65+
// Paths to mask
66+
Masks []string
6567
// MemorySwap limits the amount of memory and swap together.
6668
MemorySwap int64
6769
// NoHostname tells the builder not to create /etc/hostname content when running
@@ -109,6 +111,8 @@ type CommonBuildOptions struct {
109111
SSHSources []string
110112
// OCIHooksDir is the location of OCI hooks for the build containers
111113
OCIHooksDir []string
114+
// Paths to unmask
115+
Unmasks []string
112116
}
113117

114118
// BuildOptions can be used to alter how an image is built.

docs/buildah-build.1.md

+6
Original file line numberDiff line numberDiff line change
@@ -935,11 +935,17 @@ Security Options
935935
"label=type:TYPE" : Set the label type for the container
936936
"label=level:LEVEL" : Set the label level for the container
937937
"label=disable" : Turn off label confinement for the container
938+
939+
"mask=_/path/1:/path/2_": The paths to mask separated by a colon. A masked path cannot be accessed inside the container.
940+
938941
"no-new-privileges" : Disable container processes from gaining additional privileges
939942

940943
"seccomp=unconfined" : Turn off seccomp confinement for the container
941944
"seccomp=profile.json : JSON configuration for a seccomp filter
942945

946+
"unmask=_ALL_ or _/path/1:/path/2_, or shell expanded paths (/proc/*): Paths to unmask separated by a colon. If set to **ALL**, it unmasks all the paths that are masked or made read-only by default.
947+
The default masked paths are **/proc/acpi, /proc/kcore, /proc/keys, /proc/latency_stats, /proc/sched_debug, /proc/scsi, /proc/timer_list, /proc/timer_stats, /sys/firmware, and /sys/fs/selinux**, **/sys/devices/virtual/powercap**. The default paths that are read-only are **/proc/asound**, **/proc/bus**, **/proc/fs**, **/proc/irq**, **/proc/sys**, **/proc/sysrq-trigger**, **/sys/fs/cgroup**.
948+
943949
**--shm-size**=""
944950

945951
Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
-18 Bytes
Binary file not shown.

pkg/parse/parse.go

+12
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,18 @@ func parseSecurityOpts(securityOpts []string, commonOpts *define.CommonBuildOpti
249249
commonOpts.ApparmorProfile = con[1]
250250
case "seccomp":
251251
commonOpts.SeccompProfilePath = con[1]
252+
case "mask":
253+
commonOpts.Masks = append(commonOpts.Masks, strings.Split(con[1], ":")...)
254+
case "unmask":
255+
unmasks := strings.Split(con[1], ":")
256+
for _, unmask := range unmasks {
257+
matches, _ := filepath.Glob(unmask)
258+
if len(matches) > 0 {
259+
commonOpts.Unmasks = append(commonOpts.Unmasks, matches...)
260+
continue
261+
}
262+
commonOpts.Unmasks = append(commonOpts.Unmasks, unmask)
263+
}
252264
default:
253265
return fmt.Errorf("invalid --security-opt 2: %q", opt)
254266
}

run_linux.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
328328
}
329329
}
330330

331-
setupMaskedPaths(g)
331+
setupMaskedPaths(g, b.CommonBuildOpts)
332332
setupReadOnlyPaths(g)
333333

334334
setupTerminal(g, options.Terminal, options.TerminalSize)
@@ -1199,8 +1199,14 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string,
11991199
return mounts, nil
12001200
}
12011201

1202-
func setupMaskedPaths(g *generate.Generator) {
1203-
for _, mp := range config.DefaultMaskedPaths {
1202+
func setupMaskedPaths(g *generate.Generator, opts *define.CommonBuildOptions) {
1203+
if slices.Contains(opts.Unmasks, "all") {
1204+
return
1205+
}
1206+
for _, mp := range append(config.DefaultMaskedPaths, opts.Masks...) {
1207+
if slices.Contains(opts.Unmasks, mp) {
1208+
continue
1209+
}
12041210
g.AddLinuxMaskedPaths(mp)
12051211
}
12061212
}

tests/bud.bats

+13
Original file line numberDiff line numberDiff line change
@@ -7125,3 +7125,16 @@ EOF
71257125
echo RUN --mount=type=tmpfs,target=tmpfssubdir test '`stat -f -c %i .`' '!=' '`stat -f -c %i tmpfssubdir`' >> ${TEST_SCRATCH_DIR}/Containerfile
71267126
run_buildah build --security-opt label=disable ${TEST_SCRATCH_DIR}
71277127
}
7128+
7129+
@test "build-security-opt-mask" {
7130+
base=busybox
7131+
_prefetch $base
7132+
run_buildah build bud/masks
7133+
expect_output --substring "masked" "Everything should be masked"
7134+
run_buildah build --security-opt unmask=all bud/masks
7135+
expect_output --substring "unmasked" "Everything should be masked"
7136+
run_buildah build --security-opt unmask=/proc/* bud/masks
7137+
expect_output --substring "unmasked" "Everything should be masked"
7138+
run_buildah build --security-opt unmask=/proc/acpi bud/masks
7139+
expect_output --substring "unmasked" "Everything should be masked"
7140+
}

tests/bud/masks/Containerfile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM alpine
2+
COPY --chmod=700 test.sh /
3+
RUN /test.sh
4+

tests/bud/masks/test.sh

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# !/bin/sh
2+
3+
function output {
4+
for mask in /proc/acpi /proc/kcore /proc/keys /proc/latency_stats /proc/sched_debug /proc/scsi /proc/timer_list /proc/timer_stats /sys/dev/block /sys/devices/virtual/powercap /sys/firmware /sys/fs/selinux; do
5+
test -e $mask || continue
6+
test -f $mask && cat $mask 2> /dev/null
7+
test -d $mask && ls $mask
8+
done
9+
}
10+
output=$(output | wc -c )
11+
if [ $output == 0 ]; then
12+
echo "masked"
13+
else
14+
echo "unmasked"
15+
fi

0 commit comments

Comments
 (0)