Skip to content

Commit fc02980

Browse files
committed
golang: Remove TSync functions, and set unconditionally
Go's extensive use of threading makes installing Seccomp filters without TSync set have strong potential for unexpected behavior. Setting TSync unconditionally ensures expected behavior. This commit bumps the minimum supported library version to v2.2.0 to ensure support for TSync. Signed-off-by: Matthew Heon <[email protected]>
1 parent 9814e55 commit fc02980

3 files changed

Lines changed: 18 additions & 104 deletions

File tree

seccomp.go

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (e VersionError) Error() string {
4343
if e.minimum != "" {
4444
format += e.minimum + ": "
4545
} else {
46-
format += "2.1.0: "
46+
format += "2.2.0: "
4747
}
4848
format += "detected %d.%d.%d"
4949
return fmt.Sprintf(format, verMajor, verMinor, verMicro)
@@ -76,8 +76,8 @@ type ScmpSyscall int32
7676

7777
const (
7878
// Valid architectures recognized by libseccomp
79-
// ARM64 and all MIPS architectures are unsupported by versions of the
80-
// library before v2.2 and will return errors if used
79+
// PowerPC and S390(x) architectures are unavailable below library version
80+
// v2.3.0 and will returns errors if used with incompatible libraries
8181

8282
// ArchInvalid is a placeholder to ensure uninitialized ScmpArch
8383
// variables are invalid
@@ -494,6 +494,13 @@ func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
494494
filter.valid = true
495495
runtime.SetFinalizer(filter, filterFinalizer)
496496

497+
// Enable TSync so all goroutines will receive the same rules
498+
// If the kernel does not support TSYNC, allow us to continue without error
499+
if err := filter.setFilterAttr(filterAttrTsync, 0x1); err != nil && err != syscall.ENOTSUP {
500+
filter.Release()
501+
return nil, fmt.Errorf("could not create filter - error setting tsync bit: %v", err)
502+
}
503+
497504
return filter, nil
498505
}
499506

@@ -550,7 +557,7 @@ func (f *ScmpFilter) Release() {
550557
// The source filter src will be released as part of the process, and will no
551558
// longer be usable or valid after this call.
552559
// To be merged, filters must NOT share any architectures, and all their
553-
// attributes (Default Action, Bad Arch Action, No New Privs and TSync bools)
560+
// attributes (Default Action, Bad Arch Action, and No New Privs bools)
554561
// must match.
555562
// The filter src will be merged into the filter this is called on.
556563
// The architectures of the src filter not present in the destination, and all
@@ -723,30 +730,6 @@ func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) {
723730
return true, nil
724731
}
725732

726-
// GetTsyncBit returns whether Thread Synchronization will be enabled on the
727-
// filter being loaded, or an error if an issue was encountered retrieving the
728-
// value.
729-
// Thread Sync ensures that all members of the thread group of the calling
730-
// process will share the same Seccomp filter set.
731-
// Tsync is a fairly recent addition to the Linux kernel and older kernels
732-
// lack support. If the running kernel does not support Tsync and it is
733-
// requested in a filter, Libseccomp will not enable TSync support and will
734-
// proceed as normal.
735-
// This function is unavailable before v2.2 of libseccomp and will return an
736-
// error.
737-
func (f *ScmpFilter) GetTsyncBit() (bool, error) {
738-
tSync, err := f.getFilterAttr(filterAttrTsync)
739-
if err != nil {
740-
return false, err
741-
}
742-
743-
if tSync == 0 {
744-
return false, nil
745-
}
746-
747-
return true, nil
748-
}
749-
750733
// SetBadArchAction sets the default action taken on a syscall for an
751734
// architecture not in the filter, or an error if an issue was encountered
752735
// setting the value.
@@ -773,27 +756,6 @@ func (f *ScmpFilter) SetNoNewPrivsBit(state bool) error {
773756
return f.setFilterAttr(filterAttrNNP, toSet)
774757
}
775758

776-
// SetTsync sets whether Thread Synchronization will be enabled on the filter
777-
// being loaded. Returns an error if setting Tsync failed, or the filter is
778-
// invalid.
779-
// Thread Sync ensures that all members of the thread group of the calling
780-
// process will share the same Seccomp filter set.
781-
// Tsync is a fairly recent addition to the Linux kernel and older kernels
782-
// lack support. If the running kernel does not support Tsync and it is
783-
// requested in a filter, Libseccomp will not enable TSync support and will
784-
// proceed as normal.
785-
// This function is unavailable before v2.2 of libseccomp and will return an
786-
// error.
787-
func (f *ScmpFilter) SetTsync(enable bool) error {
788-
var toSet C.uint32_t = 0x0
789-
790-
if enable {
791-
toSet = 0x1
792-
}
793-
794-
return f.setFilterAttr(filterAttrTsync, toSet)
795-
}
796-
797759
// SetSyscallPriority sets a syscall's priority.
798760
// This provides a hint to the filter generator in libseccomp about the
799761
// importance of this syscall. High-priority syscalls are placed

seccomp_internal.go

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,15 @@ import (
2020
#include <seccomp.h>
2121
2222
#if SCMP_VER_MAJOR < 2
23-
#error Minimum supported version of Libseccomp is v2.1.0
24-
#elif SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 1
25-
#error Minimum supported version of Libseccomp is v2.1.0
23+
#error Minimum supported version of Libseccomp is v2.2.0
24+
#elif SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 2
25+
#error Minimum supported version of Libseccomp is v2.2.0
2626
#endif
2727
2828
#define ARCH_BAD ~0
2929
3030
const uint32_t C_ARCH_BAD = ARCH_BAD;
3131
32-
#ifndef SCMP_ARCH_AARCH64
33-
#define SCMP_ARCH_AARCH64 ARCH_BAD
34-
#endif
35-
36-
#ifndef SCMP_ARCH_MIPS
37-
#define SCMP_ARCH_MIPS ARCH_BAD
38-
#endif
39-
40-
#ifndef SCMP_ARCH_MIPS64
41-
#define SCMP_ARCH_MIPS64 ARCH_BAD
42-
#endif
43-
44-
#ifndef SCMP_ARCH_MIPS64N32
45-
#define SCMP_ARCH_MIPS64N32 ARCH_BAD
46-
#endif
47-
48-
#ifndef SCMP_ARCH_MIPSEL
49-
#define SCMP_ARCH_MIPSEL ARCH_BAD
50-
#endif
51-
52-
#ifndef SCMP_ARCH_MIPSEL64
53-
#define SCMP_ARCH_MIPSEL64 ARCH_BAD
54-
#endif
55-
56-
#ifndef SCMP_ARCH_MIPSEL64N32
57-
#define SCMP_ARCH_MIPSEL64N32 ARCH_BAD
58-
#endif
59-
6032
#ifndef SCMP_ARCH_PPC
6133
#define SCMP_ARCH_PPC ARCH_BAD
6234
#endif
@@ -101,12 +73,6 @@ const uint32_t C_ACT_ERRNO = SCMP_ACT_ERRNO(0);
10173
const uint32_t C_ACT_TRACE = SCMP_ACT_TRACE(0);
10274
const uint32_t C_ACT_ALLOW = SCMP_ACT_ALLOW;
10375
104-
// If TSync is not supported, make sure it doesn't map to a supported filter attribute
105-
// Don't worry about major version < 2, the minimum version checks should catch that case
106-
#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 2
107-
#define SCMP_FLTATR_CTL_TSYNC _SCMP_CMP_MIN
108-
#endif
109-
11076
const uint32_t C_ATTRIBUTE_DEFAULT = (uint32_t)SCMP_FLTATR_ACT_DEFAULT;
11177
const uint32_t C_ATTRIBUTE_BADARCH = (uint32_t)SCMP_FLTATR_ACT_BADARCH;
11278
const uint32_t C_ATTRIBUTE_NNP = (uint32_t)SCMP_FLTATR_CTL_NNP;
@@ -219,9 +185,9 @@ func checkVersionAbove(major, minor, micro uint) bool {
219185
(verMajor == major && verMinor == minor && verMicro >= micro)
220186
}
221187

222-
// Ensure that the library is supported, i.e. >= 2.1.0.
188+
// Ensure that the library is supported, i.e. >= 2.2.0.
223189
func ensureSupportedVersion() error {
224-
if !checkVersionAbove(2, 1, 0) {
190+
if !checkVersionAbove(2, 2, 0) {
225191
return VersionError{}
226192
}
227193
return nil
@@ -243,13 +209,6 @@ func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) {
243209
return 0x0, errBadFilter
244210
}
245211

246-
if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
247-
return 0x0, VersionError{
248-
message: "thread synchronization attribute is not supported",
249-
minimum: "2.2.0",
250-
}
251-
}
252-
253212
var attribute C.uint32_t
254213

255214
retCode := C.seccomp_attr_get(f.filterCtx, attr.toNative(), &attribute)
@@ -269,13 +228,6 @@ func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error
269228
return errBadFilter
270229
}
271230

272-
if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
273-
return VersionError{
274-
message: "thread synchronization attribute is not supported",
275-
minimum: "2.2.0",
276-
}
277-
}
278-
279231
retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value)
280232
if retCode != 0 {
281233
return syscall.Errno(-1 * retCode)

seccomp_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ var versionErrorTests = []versionErrorTest{
4242
"",
4343
},
4444
"Libseccomp version too low: " +
45-
"deadbeef: minimum supported is 2.1.0: " +
45+
"deadbeef: minimum supported is 2.2.0: " +
4646
"detected " + versionStr,
4747
},
4848
{
4949
VersionError{
5050
"",
5151
"",
5252
},
53-
"Libseccomp version too low: minimum supported is 2.1.0: " +
53+
"Libseccomp version too low: minimum supported is 2.2.0: " +
5454
"detected " + versionStr,
5555
},
5656
}

0 commit comments

Comments
 (0)