2022-07-06 17:14:06 +08:00
//go:build linux
2018-05-12 01:08:18 +08:00
// +build linux
package chroot
import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
2021-09-28 05:25:06 +08:00
"strconv"
2018-05-12 01:08:18 +08:00
"strings"
"testing"
2018-09-18 03:20:16 +08:00
"github.com/containers/buildah/tests/testreport/types"
"github.com/containers/buildah/util"
2023-10-05 05:07:30 +08:00
"github.com/containers/storage/pkg/mount"
2018-05-12 01:08:18 +08:00
"github.com/containers/storage/pkg/reexec"
2019-02-23 10:08:09 +08:00
specs "github.com/opencontainers/runtime-spec/specs-go"
2018-05-12 01:08:18 +08:00
"github.com/opencontainers/runtime-tools/generate"
2023-10-05 05:07:30 +08:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2024-01-31 23:03:20 +08:00
"golang.org/x/exp/slices"
2023-10-05 05:07:30 +08:00
"golang.org/x/sys/unix"
2018-05-12 01:08:18 +08:00
)
const (
reportCommand = "testreport"
)
func TestMain ( m * testing . M ) {
if reexec . Init ( ) {
return
}
os . Exit ( m . Run ( ) )
}
func testMinimal ( t * testing . T , modify func ( g * generate . Generator , rootDir , bundleDir string ) , verify func ( t * testing . T , report * types . TestReport ) ) {
2023-10-05 05:07:30 +08:00
t . Helper ( )
2018-05-12 01:08:18 +08:00
g , err := generate . New ( "linux" )
if err != nil {
t . Fatalf ( "generate.New(%q): %v" , "linux" , err )
}
2021-10-27 05:16:44 +08:00
if err = setupSeccomp ( g . Config , "" ) ; err != nil {
t . Fatalf ( "setupSeccomp(%q): %v" , "" , err )
}
2018-05-12 01:08:18 +08:00
2022-08-20 15:02:40 +08:00
// t.TempDir returns /tmp/TestName/001.
// /tmp/TestName/001 has permission 0777, but /tmp/TestName is 0700
tempDir := t . TempDir ( )
if err = os . Chmod ( filepath . Dir ( tempDir ) , 0711 ) ; err != nil {
2018-05-12 01:08:18 +08:00
t . Fatalf ( "error loosening permissions on %q: %v" , tempDir , err )
}
rootDir := filepath . Join ( tempDir , "root" )
if err := os . Mkdir ( rootDir , 0711 ) ; err != nil {
t . Fatalf ( "os.Mkdir(%q): %v" , rootDir , err )
}
2021-10-27 03:16:06 +08:00
rootTmpDir := filepath . Join ( rootDir , "tmp" )
if err := os . Mkdir ( rootTmpDir , 01777 ) ; err != nil {
t . Fatalf ( "os.Mkdir(%q): %v" , rootTmpDir , err )
}
2018-05-12 01:08:18 +08:00
specPath := filepath . Join ( ".." , "tests" , reportCommand , reportCommand )
specBinarySource , err := os . Open ( specPath )
if err != nil {
t . Fatalf ( "open(%q): %v" , specPath , err )
}
defer specBinarySource . Close ( )
specBinary , err := os . OpenFile ( filepath . Join ( rootDir , reportCommand ) , os . O_WRONLY | os . O_CREATE | os . O_EXCL , 0711 )
if err != nil {
t . Fatalf ( "open(%q): %v" , filepath . Join ( rootDir , reportCommand ) , err )
}
2019-05-29 21:38:15 +08:00
if _ , err := io . Copy ( specBinary , specBinarySource ) ; err != nil {
t . Fatalf ( "io.Copy error: %v" , err )
}
2018-05-12 01:08:18 +08:00
specBinary . Close ( )
g . SetRootPath ( rootDir )
g . SetProcessArgs ( [ ] string { "/" + reportCommand } )
bundleDir := filepath . Join ( tempDir , "bundle" )
if err := os . Mkdir ( bundleDir , 0700 ) ; err != nil {
t . Fatalf ( "os.Mkdir(%q): %v" , bundleDir , err )
}
if modify != nil {
modify ( & g , rootDir , bundleDir )
}
2019-02-23 10:08:09 +08:00
uid , gid , err := util . GetHostRootIDs ( g . Config )
2018-05-12 01:08:18 +08:00
if err != nil {
t . Fatalf ( "GetHostRootIDs: %v" , err )
}
if err := os . Chown ( rootDir , int ( uid ) , int ( gid ) ) ; err != nil {
t . Fatalf ( "os.Chown(%q): %v" , rootDir , err )
}
output := new ( bytes . Buffer )
2019-05-16 06:40:15 +08:00
if err := RunUsingChroot ( g . Config , bundleDir , "/" , new ( bytes . Buffer ) , output , output ) ; err != nil {
2018-05-12 01:08:18 +08:00
t . Fatalf ( "run: %v: %s" , err , output . String ( ) )
}
var report types . TestReport
2022-07-06 17:14:06 +08:00
if err := json . Unmarshal ( output . Bytes ( ) , & report ) ; err != nil {
2018-05-12 01:08:18 +08:00
t . Fatalf ( "decode: %v" , err )
}
if verify != nil {
verify ( t , & report )
}
}
2019-06-18 19:29:58 +08:00
func TestNoop ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
testMinimal ( t , nil , nil )
}
2019-06-18 19:29:58 +08:00
func TestMinimalSkeleton ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
} ,
func ( t * testing . T , report * types . TestReport ) {
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
func TestProcessTerminal ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
for _ , terminal := range [ ] bool { false , true } {
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . SetProcessTerminal ( terminal )
} ,
func ( t * testing . T , report * types . TestReport ) {
if report . Spec . Process . Terminal != terminal {
t . Fatalf ( "expected terminal = %v, got %v" , terminal , report . Spec . Process . Terminal )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
}
func TestProcessConsoleSize ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
for _ , size := range [ ] [ 2 ] uint { { 80 , 25 } , { 132 , 50 } } {
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . SetProcessTerminal ( true )
g . SetProcessConsoleSize ( size [ 0 ] , size [ 1 ] )
} ,
func ( t * testing . T , report * types . TestReport ) {
if report . Spec . Process . ConsoleSize . Width != size [ 0 ] {
t . Fatalf ( "expected console width = %v, got %v" , size [ 0 ] , report . Spec . Process . ConsoleSize . Width )
}
if report . Spec . Process . ConsoleSize . Height != size [ 1 ] {
t . Fatalf ( "expected console height = %v, got %v" , size [ 1 ] , report . Spec . Process . ConsoleSize . Height )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
}
func TestProcessUser ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
for _ , id := range [ ] uint32 { 0 , 1000 } {
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . SetProcessUID ( id )
g . SetProcessGID ( id + 1 )
g . AddProcessAdditionalGid ( id + 2 )
} ,
func ( t * testing . T , report * types . TestReport ) {
if report . Spec . Process . User . UID != id {
t . Fatalf ( "expected UID %v, got %v" , id , report . Spec . Process . User . UID )
}
if report . Spec . Process . User . GID != id + 1 {
t . Fatalf ( "expected GID %v, got %v" , id + 1 , report . Spec . Process . User . GID )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
}
func TestProcessEnv ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
2023-10-05 05:07:30 +08:00
e := fmt . Sprintf ( "PARENT_TEST_PID=%d" , unix . Getpid ( ) )
2018-05-12 01:08:18 +08:00
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . ClearProcessEnv ( )
2023-10-05 05:07:30 +08:00
g . AddProcessEnv ( "PARENT_TEST_PID" , strconv . Itoa ( unix . Getpid ( ) ) )
2018-05-12 01:08:18 +08:00
} ,
func ( t * testing . T , report * types . TestReport ) {
for _ , ev := range report . Spec . Process . Env {
if ev == e {
return
}
}
t . Fatalf ( "expected environment variable %q" , e )
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
func TestProcessCwd ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
if err := os . Mkdir ( filepath . Join ( rootDir , "/no-such-directory" ) , 0700 ) ; err != nil {
t . Fatalf ( "mkdir(%q): %v" , filepath . Join ( rootDir , "/no-such-directory" ) , err )
}
g . SetProcessCwd ( "/no-such-directory" )
} ,
func ( t * testing . T , report * types . TestReport ) {
if report . Spec . Process . Cwd != "/no-such-directory" {
t . Fatalf ( "expected %q, got %q" , "/no-such-directory" , report . Spec . Process . Cwd )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
func TestProcessCapabilities ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . ClearProcessCapabilities ( )
} ,
func ( t * testing . T , report * types . TestReport ) {
if len ( report . Spec . Process . Capabilities . Permitted ) != 0 {
t . Fatalf ( "expected no permitted capabilities, got %#v" , report . Spec . Process . Capabilities . Permitted )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . ClearProcessCapabilities ( )
2019-05-29 21:38:15 +08:00
if err := g . AddProcessCapabilityEffective ( "CAP_IPC_LOCK" ) ; err != nil {
t . Fatalf ( "%v" , err )
}
if err := g . AddProcessCapabilityPermitted ( "CAP_IPC_LOCK" ) ; err != nil {
t . Fatalf ( "%v" , err )
}
if err := g . AddProcessCapabilityInheritable ( "CAP_IPC_LOCK" ) ; err != nil {
t . Fatalf ( "%v" , err )
}
if err := g . AddProcessCapabilityBounding ( "CAP_IPC_LOCK" ) ; err != nil {
t . Fatalf ( "%v" , err )
}
if err := g . AddProcessCapabilityAmbient ( "CAP_IPC_LOCK" ) ; err != nil {
t . Fatalf ( "%v" , err )
}
2018-05-12 01:08:18 +08:00
} ,
func ( t * testing . T , report * types . TestReport ) {
if len ( report . Spec . Process . Capabilities . Permitted ) != 1 {
t . Fatalf ( "expected one permitted capability, got %#v" , report . Spec . Process . Capabilities . Permitted )
}
if report . Spec . Process . Capabilities . Permitted [ 0 ] != "CAP_IPC_LOCK" {
t . Fatalf ( "expected one capability CAP_IPC_LOCK, got %#v" , report . Spec . Process . Capabilities . Permitted )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
func TestProcessRlimits ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
2023-10-05 05:07:30 +08:00
for _ , limit := range [ ] uint64 { 100 * 1024 * 1024 * 1024 , 200 * 1024 * 1024 * 1024 , unix . RLIM_INFINITY } {
2018-05-12 01:08:18 +08:00
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . ClearProcessRlimits ( )
2023-10-05 05:07:30 +08:00
if limit != unix . RLIM_INFINITY {
g . AddProcessRlimits ( "rlimit_as" , limit , limit )
2018-05-12 01:08:18 +08:00
}
} ,
func ( t * testing . T , report * types . TestReport ) {
var rlim * specs . POSIXRlimit
for i := range report . Spec . Process . Rlimits {
if strings . ToUpper ( report . Spec . Process . Rlimits [ i ] . Type ) == "RLIMIT_AS" {
rlim = & report . Spec . Process . Rlimits [ i ]
}
}
2023-10-05 05:07:30 +08:00
if limit == unix . RLIM_INFINITY && ! ( rlim == nil || ( rlim . Soft == unix . RLIM_INFINITY && rlim . Hard == unix . RLIM_INFINITY ) ) {
2018-05-12 01:08:18 +08:00
t . Fatalf ( "wasn't supposed to set limit on number of open files: %#v" , rlim )
}
2023-10-05 05:07:30 +08:00
if limit != unix . RLIM_INFINITY && rlim == nil {
2018-05-12 01:08:18 +08:00
t . Fatalf ( "was supposed to set limit on number of open files" )
}
if rlim != nil {
2023-10-05 05:07:30 +08:00
if rlim . Soft != limit {
2018-05-12 01:08:18 +08:00
t . Fatalf ( "soft limit was set to %d, not %d" , rlim . Soft , limit )
}
2023-10-05 05:07:30 +08:00
if rlim . Hard != limit {
2018-05-12 01:08:18 +08:00
t . Fatalf ( "hard limit was set to %d, not %d" , rlim . Hard , limit )
}
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
}
func TestProcessNoNewPrivileges ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
2023-10-05 05:07:30 +08:00
if ! seccompAvailable {
t . Skip ( "not built with seccomp support" )
}
2018-05-12 01:08:18 +08:00
for _ , nope := range [ ] bool { false , true } {
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . SetProcessNoNewPrivileges ( nope )
} ,
func ( t * testing . T , report * types . TestReport ) {
if report . Spec . Process . NoNewPrivileges != nope {
2023-10-05 05:07:30 +08:00
t . Fatalf ( "expected no-new-privs to be %v, got %v" , nope , report . Spec . Process . NoNewPrivileges )
2018-05-12 01:08:18 +08:00
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
}
func TestProcessOOMScoreAdj ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
for _ , adj := range [ ] int { 0 , 1 , 2 , 3 } {
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . SetProcessOOMScoreAdj ( adj )
} ,
func ( t * testing . T , report * types . TestReport ) {
adjusted := 0
if report . Spec . Process . OOMScoreAdj != nil {
adjusted = * report . Spec . Process . OOMScoreAdj
}
if adjusted != adj {
t . Fatalf ( "expected oom-score-adj to be %v, got %v" , adj , adjusted )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
}
func TestHostname ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
2023-10-05 05:07:30 +08:00
hostname := fmt . Sprintf ( "host%d" , unix . Getpid ( ) )
2018-05-12 01:08:18 +08:00
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . SetHostname ( hostname )
} ,
func ( t * testing . T , report * types . TestReport ) {
if report . Spec . Hostname != hostname {
t . Fatalf ( "expected %q, got %q" , hostname , report . Spec . Hostname )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
func TestMounts ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
2023-10-05 05:07:30 +08:00
t . Run ( "tmpfs" , func ( t * testing . T ) {
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . AddMount ( specs . Mount {
Source : "tmpfs" ,
Destination : "/was-not-there-before" ,
Type : "tmpfs" ,
Options : [ ] string { "ro" , "size=0" } ,
} )
} ,
func ( t * testing . T , report * types . TestReport ) {
found := false
for _ , mount := range report . Spec . Mounts {
if mount . Destination == "/was-not-there-before" && mount . Type == "tmpfs" {
found = true
}
2018-05-12 01:08:18 +08:00
}
2023-10-05 05:07:30 +08:00
if ! found {
t . Errorf ( "added mount for /was-not-there-before not found in %#v" , report . Spec . Mounts )
}
} ,
)
} )
// apparently we can do anything except turn read-only into read-write
binds := [ ] struct {
name string
tmpfsOptions string
destination string
fsType string
options [ ] string
require [ ] string
reject [ ] string
} {
{
name : "nodev" ,
destination : "/nodev" ,
options : [ ] string { "nodev" } ,
reject : [ ] string { "dev" } ,
2021-10-27 03:16:06 +08:00
} ,
2023-10-05 05:07:30 +08:00
{
name : "noexec" ,
destination : "/noexec" ,
options : [ ] string { "noexec" } ,
reject : [ ] string { "exec" } ,
} ,
{
name : "nosuid" ,
destination : "/nosuid" ,
options : [ ] string { "nosuid" } ,
reject : [ ] string { "suid" } } ,
{
name : "nodev,noexec" ,
destination : "/nodev,noexec" ,
options : [ ] string { "nodev" , "noexec" } ,
reject : [ ] string { "dev" , "exec" } ,
} ,
{
name : "nodev,noexec,nosuid" ,
destination : "/nodev,noexec,nosuid" ,
options : [ ] string { "nodev" , "noexec" , "nosuid" } ,
reject : [ ] string { "dev" , "exec" , "suid" } ,
} ,
{
name : "nodev,noexec,nosuid,ro" ,
destination : "/nodev,noexec,nosuid,ro" ,
options : [ ] string { "nodev" , "noexec" , "nosuid" , "ro" } ,
reject : [ ] string { "dev" , "exec" , "suid" , "rw" } ,
} ,
{
name : "nodev,noexec,nosuid,rw" ,
destination : "/nodev,noexec,nosuid,rw" ,
options : [ ] string { "nodev" , "noexec" , "nosuid" , "rw" } ,
reject : [ ] string { "dev" , "exec" , "suid" , "ro" } ,
} ,
{
name : "dev,exec,suid,rw" ,
tmpfsOptions : "nodev,noexec,nosuid" ,
destination : "/dev,exec,suid,rw" ,
options : [ ] string { "dev" , "exec" , "suid" , "rw" } ,
require : [ ] string { "rw" } ,
reject : [ ] string { "nodev" , "noexec" , "nosuid" , "ro" } ,
} ,
{
name : "nodev,noexec,nosuid,ro,flip" ,
tmpfsOptions : "dev,exec,suid,rw" ,
destination : "/nodev,noexec,nosuid,ro" ,
options : [ ] string { "nodev" , "noexec" , "nosuid" , "ro" } ,
reject : [ ] string { "dev" , "exec" , "suid" , "rw" } ,
} ,
}
for _ , bind := range binds {
t . Run ( bind . name , func ( t * testing . T ) {
// mount a tmpfs over the temp dir, which may be on a nodev/noexec/nosuid filesystem
tmpfsMount := t . TempDir ( )
t . Cleanup ( func ( ) { _ = unix . Unmount ( tmpfsMount , unix . MNT_FORCE | unix . MNT_DETACH ) } )
tmpfsOptions := "rw,size=1m"
if bind . tmpfsOptions != "" {
tmpfsOptions += ( "," + bind . tmpfsOptions )
}
tmpfsFlags , tmpfsOptions := mount . ParseOptions ( tmpfsOptions )
require . NoErrorf ( t , unix . Mount ( "none" , tmpfsMount , "tmpfs" , uintptr ( tmpfsFlags ) , tmpfsOptions ) , "error mounting a tmpfs with flags=%#x,options=%q at %s" , tmpfsFlags , tmpfsOptions , tmpfsMount )
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
fsType := bind . fsType
if fsType == "" {
fsType = "bind"
}
g . AddMount ( specs . Mount {
Source : tmpfsMount ,
Destination : bind . destination ,
Type : fsType ,
Options : bind . options ,
} )
} ,
func ( t * testing . T , report * types . TestReport ) {
2023-12-31 01:42:31 +08:00
foundBindDestinationMount := false
2023-10-05 05:07:30 +08:00
for _ , mount := range report . Spec . Mounts {
if mount . Destination == bind . destination {
allRequired := true
requiredFlags := bind . require
if len ( requiredFlags ) == 0 {
requiredFlags = bind . options
}
for _ , required := range requiredFlags {
2024-01-31 23:03:20 +08:00
if ! slices . Contains ( mount . Options , required ) {
2023-10-05 05:07:30 +08:00
allRequired = false
}
}
anyRejected := false
for _ , rejected := range bind . reject {
2024-01-31 23:03:20 +08:00
if slices . Contains ( mount . Options , rejected ) {
2023-10-05 05:07:30 +08:00
anyRejected = true
}
}
2023-12-31 01:42:31 +08:00
if allRequired && ! anyRejected {
foundBindDestinationMount = true
}
2023-10-05 05:07:30 +08:00
}
}
2023-12-31 01:42:31 +08:00
if ! foundBindDestinationMount {
2023-10-05 05:07:30 +08:00
t . Errorf ( "added mount for %s not found with the right flags (%v) in %+v" , bind . destination , bind . options , report . Spec . Mounts )
}
} ,
)
// okay, just make sure we didn't change anything about the tmpfs mount point outside of the chroot
var fs unix . Statfs_t
require . NoErrorf ( t , unix . Statfs ( tmpfsMount , & fs ) , "fstat" )
assert . Equalf ( t , tmpfsFlags & unix . MS_NODEV == unix . MS_NODEV , fs . Flags & unix . ST_NODEV == unix . ST_NODEV , "nodev flag" )
assert . Equalf ( t , tmpfsFlags & unix . MS_NOEXEC == unix . MS_NOEXEC , fs . Flags & unix . ST_NOEXEC == unix . ST_NOEXEC , "noexec flag" )
assert . Equalf ( t , tmpfsFlags & unix . MS_NOSUID == unix . MS_NOSUID , fs . Flags & unix . ST_NOSUID == unix . ST_NOSUID , "nosuid flag" )
assert . Equalf ( t , tmpfsFlags & unix . MS_RDONLY == unix . MS_RDONLY , fs . Flags & unix . ST_RDONLY == unix . ST_RDONLY , "readonly flag" )
} )
}
2018-05-12 01:08:18 +08:00
}
func TestLinuxIDMapping ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . ClearLinuxUIDMappings ( )
g . ClearLinuxGIDMappings ( )
2023-10-05 05:07:30 +08:00
g . AddLinuxUIDMapping ( uint32 ( unix . Getuid ( ) ) , 0 , 1 )
g . AddLinuxGIDMapping ( uint32 ( unix . Getgid ( ) ) , 0 , 1 )
2018-05-12 01:08:18 +08:00
} ,
func ( t * testing . T , report * types . TestReport ) {
if len ( report . Spec . Linux . UIDMappings ) != 1 {
t . Fatalf ( "expected 1 uid mapping, got %q" , len ( report . Spec . Linux . UIDMappings ) )
}
2023-10-05 05:07:30 +08:00
if report . Spec . Linux . UIDMappings [ 0 ] . HostID != uint32 ( unix . Getuid ( ) ) {
t . Fatalf ( "expected host uid mapping to be %d, got %d" , unix . Getuid ( ) , report . Spec . Linux . UIDMappings [ 0 ] . HostID )
2018-05-12 01:08:18 +08:00
}
if report . Spec . Linux . UIDMappings [ 0 ] . ContainerID != 0 {
t . Fatalf ( "expected container uid mapping to be 0, got %d" , report . Spec . Linux . UIDMappings [ 0 ] . ContainerID )
}
if report . Spec . Linux . UIDMappings [ 0 ] . Size != 1 {
t . Fatalf ( "expected container uid map size to be 1, got %d" , report . Spec . Linux . UIDMappings [ 0 ] . Size )
}
2023-10-05 05:07:30 +08:00
if report . Spec . Linux . GIDMappings [ 0 ] . HostID != uint32 ( unix . Getgid ( ) ) {
t . Fatalf ( "expected host uid mapping to be %d, got %d" , unix . Getgid ( ) , report . Spec . Linux . GIDMappings [ 0 ] . HostID )
2018-05-12 01:08:18 +08:00
}
if report . Spec . Linux . GIDMappings [ 0 ] . ContainerID != 0 {
t . Fatalf ( "expected container gid mapping to be 0, got %d" , report . Spec . Linux . GIDMappings [ 0 ] . ContainerID )
}
if report . Spec . Linux . GIDMappings [ 0 ] . Size != 1 {
t . Fatalf ( "expected container gid map size to be 1, got %d" , report . Spec . Linux . GIDMappings [ 0 ] . Size )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}
func TestLinuxIDMappingShift ( t * testing . T ) {
2023-10-05 05:07:30 +08:00
if unix . Getuid ( ) != 0 {
2018-05-12 01:08:18 +08:00
t . Skip ( "tests need to be run as root" )
}
testMinimal ( t ,
func ( g * generate . Generator , rootDir , bundleDir string ) {
g . ClearLinuxUIDMappings ( )
g . ClearLinuxGIDMappings ( )
2023-10-05 05:07:30 +08:00
g . AddLinuxUIDMapping ( uint32 ( unix . Getuid ( ) ) + 1 , 0 , 1 )
g . AddLinuxGIDMapping ( uint32 ( unix . Getgid ( ) ) + 1 , 0 , 1 )
2018-05-12 01:08:18 +08:00
} ,
func ( t * testing . T , report * types . TestReport ) {
if len ( report . Spec . Linux . UIDMappings ) != 1 {
t . Fatalf ( "expected 1 uid mapping, got %q" , len ( report . Spec . Linux . UIDMappings ) )
}
2023-10-05 05:07:30 +08:00
if report . Spec . Linux . UIDMappings [ 0 ] . HostID != uint32 ( unix . Getuid ( ) + 1 ) {
t . Fatalf ( "expected host uid mapping to be %d, got %d" , unix . Getuid ( ) + 1 , report . Spec . Linux . UIDMappings [ 0 ] . HostID )
2018-05-12 01:08:18 +08:00
}
if report . Spec . Linux . UIDMappings [ 0 ] . ContainerID != 0 {
t . Fatalf ( "expected container uid mapping to be 0, got %d" , report . Spec . Linux . UIDMappings [ 0 ] . ContainerID )
}
if report . Spec . Linux . UIDMappings [ 0 ] . Size != 1 {
t . Fatalf ( "expected container uid map size to be 1, got %d" , report . Spec . Linux . UIDMappings [ 0 ] . Size )
}
2023-10-05 05:07:30 +08:00
if report . Spec . Linux . GIDMappings [ 0 ] . HostID != uint32 ( unix . Getgid ( ) + 1 ) {
t . Fatalf ( "expected host uid mapping to be %d, got %d" , unix . Getgid ( ) + 1 , report . Spec . Linux . GIDMappings [ 0 ] . HostID )
2018-05-12 01:08:18 +08:00
}
if report . Spec . Linux . GIDMappings [ 0 ] . ContainerID != 0 {
t . Fatalf ( "expected container gid mapping to be 0, got %d" , report . Spec . Linux . GIDMappings [ 0 ] . ContainerID )
}
if report . Spec . Linux . GIDMappings [ 0 ] . Size != 1 {
t . Fatalf ( "expected container gid map size to be 1, got %d" , report . Spec . Linux . GIDMappings [ 0 ] . Size )
}
2021-10-27 03:16:06 +08:00
} ,
)
2018-05-12 01:08:18 +08:00
}