github.com/coreos/mantle@v0.13.0/kola/tests/misc/files.go (about)

     1  // Copyright 2016 CoreOS, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package misc
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/coreos/mantle/kola/cluster"
    22  	"github.com/coreos/mantle/kola/register"
    23  )
    24  
    25  func init() {
    26  	register.Register(&register.Test{
    27  		Run:         Filesystem,
    28  		ClusterSize: 1,
    29  		Name:        "cl.filesystem",
    30  		Distros:     []string{"cl"},
    31  	})
    32  }
    33  
    34  func Filesystem(c cluster.TestCluster) {
    35  	c.Run("deadlinks", DeadLinks)
    36  	c.Run("suid", SUIDFiles)
    37  	c.Run("sgid", SGIDFiles)
    38  	c.Run("writablefiles", WritableFiles)
    39  	c.Run("writabledirs", WritableDirs)
    40  	c.Run("stickydirs", StickyDirs)
    41  	c.Run("blacklist", Blacklist)
    42  }
    43  
    44  func sugidFiles(c cluster.TestCluster, validfiles []string, mode string) {
    45  	m := c.Machines()[0]
    46  	badfiles := make([]string, 0, 0)
    47  
    48  	output := c.MustSSH(m, fmt.Sprintf("sudo find / -ignore_readdir_race -path /sys -prune -o -path /proc -prune -o -path /var/lib/rkt -prune -o -type f -perm -%v -print", mode))
    49  
    50  	if string(output) == "" {
    51  		return
    52  	}
    53  
    54  	files := strings.Split(string(output), "\n")
    55  	for _, file := range files {
    56  		var valid bool
    57  
    58  		for _, validfile := range validfiles {
    59  			if file == validfile {
    60  				valid = true
    61  			}
    62  		}
    63  		if valid != true {
    64  			badfiles = append(badfiles, file)
    65  		}
    66  	}
    67  
    68  	if len(badfiles) != 0 {
    69  		c.Fatalf("Unknown SUID or SGID files found: %v", badfiles)
    70  	}
    71  }
    72  
    73  func DeadLinks(c cluster.TestCluster) {
    74  	m := c.Machines()[0]
    75  
    76  	ignore := []string{
    77  		"/dev",
    78  		"/proc",
    79  		"/run/systemd",
    80  		"/run/udev/watch",
    81  		"/sys",
    82  		"/var/lib/docker",
    83  		"/var/lib/rkt",
    84  	}
    85  
    86  	output := c.MustSSH(m, fmt.Sprintf("sudo find / -ignore_readdir_race -path %s -prune -o -xtype l -print", strings.Join(ignore, " -prune -o -path ")))
    87  
    88  	if string(output) != "" {
    89  		c.Fatalf("Dead symbolic links found: %v", strings.Split(string(output), "\n"))
    90  	}
    91  }
    92  
    93  func SUIDFiles(c cluster.TestCluster) {
    94  	validfiles := []string{
    95  		"/usr/bin/chage",
    96  		"/usr/bin/chfn",
    97  		"/usr/bin/chsh",
    98  		"/usr/bin/expiry",
    99  		"/usr/bin/gpasswd",
   100  		"/usr/bin/ksu",
   101  		"/usr/bin/man",
   102  		"/usr/bin/mandb",
   103  		"/usr/bin/mount",
   104  		"/usr/bin/newgidmap",
   105  		"/usr/bin/newgrp",
   106  		"/usr/bin/newuidmap",
   107  		"/usr/bin/passwd",
   108  		"/usr/bin/pkexec",
   109  		"/usr/bin/umount",
   110  		"/usr/bin/su",
   111  		"/usr/bin/sudo",
   112  		"/usr/lib/polkit-1/polkit-agent-helper-1",
   113  		"/usr/lib64/polkit-1/polkit-agent-helper-1",
   114  		"/usr/libexec/dbus-daemon-launch-helper",
   115  		"/usr/sbin/mount.nfs",
   116  		"/usr/sbin/unix_chkpwd",
   117  	}
   118  
   119  	sugidFiles(c, validfiles, "4000")
   120  }
   121  
   122  func SGIDFiles(c cluster.TestCluster) {
   123  	validfiles := []string{}
   124  
   125  	sugidFiles(c, validfiles, "2000")
   126  }
   127  
   128  func WritableFiles(c cluster.TestCluster) {
   129  	m := c.Machines()[0]
   130  
   131  	output := c.MustSSH(m, "sudo find / -ignore_readdir_race -path /sys -prune -o -path /proc -prune -o -path /var/lib/rkt -prune -o -type f -perm -0002 -print")
   132  
   133  	if string(output) != "" {
   134  		c.Fatalf("Unknown writable files found: %s", output)
   135  	}
   136  }
   137  
   138  func WritableDirs(c cluster.TestCluster) {
   139  	m := c.Machines()[0]
   140  
   141  	output := c.MustSSH(m, "sudo find / -ignore_readdir_race -path /sys -prune -o -path /proc -prune -o -path /var/lib/rkt -prune -o -type d -perm -0002 -a ! -perm -1000 -print")
   142  
   143  	if string(output) != "" {
   144  		c.Fatalf("Unknown writable directories found: %s", output)
   145  	}
   146  }
   147  
   148  // The default permissions for the root of a tmpfs are 1777
   149  // https://github.com/coreos/bugs/issues/1812
   150  func StickyDirs(c cluster.TestCluster) {
   151  	m := c.Machines()[0]
   152  
   153  	ignore := []string{
   154  		// don't descend into these
   155  		"/proc",
   156  		"/sys",
   157  		"/var/lib/docker",
   158  		"/var/lib/rkt",
   159  
   160  		// should be sticky, and may have sticky children
   161  		"/dev/mqueue",
   162  		"/dev/shm",
   163  		"/media",
   164  		"/tmp",
   165  		"/var/tmp",
   166  	}
   167  
   168  	output := c.MustSSH(m, fmt.Sprintf("sudo find / -ignore_readdir_race -path %s -prune -o -type d -perm /1000 -print", strings.Join(ignore, " -prune -o -path ")))
   169  
   170  	if string(output) != "" {
   171  		c.Fatalf("Unknown sticky directories found: %s", output)
   172  	}
   173  }
   174  
   175  func Blacklist(c cluster.TestCluster) {
   176  	m := c.Machines()[0]
   177  
   178  	skip := []string{
   179  		// Directories not to descend into
   180  		"/proc",
   181  		"/sys",
   182  		"/var/lib/docker",
   183  		"/var/lib/rkt",
   184  	}
   185  
   186  	blacklist := []string{
   187  		// Things excluded from the image that might slip in
   188  		"/usr/bin/perl",
   189  		"/usr/bin/python",
   190  		"/usr/share/man",
   191  
   192  		// net-tools "make install" copies binaries from
   193  		// /usr/bin/{} to /usr/bin/{}.old before overwriting them.
   194  		// This sometimes produced an extraneous set of {}.old
   195  		// binaries due to make parallelism.
   196  		// https://github.com/coreos/coreos-overlay/pull/2734
   197  		"/usr/bin/*.old",
   198  
   199  		// Control characters in filenames
   200  		"*[\x01-\x1f]*",
   201  		// Space
   202  		"* *",
   203  		// DEL
   204  		"*\x7f*",
   205  	}
   206  
   207  	output := c.MustSSH(m, fmt.Sprintf("sudo find / -ignore_readdir_race -path %s -prune -o -path '%s' -print", strings.Join(skip, " -prune -o -path "), strings.Join(blacklist, "' -print -o -path '")))
   208  
   209  	if string(output) != "" {
   210  		c.Fatalf("Blacklisted files or directories found:\n%s", output)
   211  	}
   212  }