github.com/rigado/snapd@v2.42.5-go-mod+incompatible/selinux/label_linux.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 package selinux 20 21 import ( 22 "os" 23 "os/exec" 24 "regexp" 25 26 "github.com/snapcore/snapd/osutil" 27 ) 28 29 var ( 30 // actual matchpathcon -V output: 31 // /home/guest/snap has context unconfined_u:object_r:user_home_t:s0, should be unconfined_u:object_r:snappy_home_t:s0 32 matchIncorrectLabel = regexp.MustCompile("^.* has context .* should be .*\n$") 33 ) 34 35 // VerifyPathContext checks whether a given path is labeled according to its default 36 // SELinux context 37 func VerifyPathContext(aPath string) (bool, error) { 38 if _, err := os.Stat(aPath); err != nil { 39 // path that cannot be accessed cannot be verified 40 return false, err 41 } 42 // matchpathcon -V verifies whether the context of a path matches the 43 // default 44 cmd := exec.Command("matchpathcon", "-V", aPath) 45 cmd.Env = append(os.Environ(), "LC_ALL=C") 46 out, err := cmd.Output() 47 if err == nil { 48 // the path was verified 49 return true, nil 50 } 51 exit, _ := osutil.ExitCode(err) 52 // exits with 1 when the verification failed or other error occurred, 53 // when verification failed a message like this will be printed to 54 // stdout: 55 // <the-path> has context <some-context>, should be <some-other-context> 56 // match the message so that we can distinguish a failed verification 57 // case from other errors 58 if exit == 1 && matchIncorrectLabel.Match(out) { 59 return false, nil 60 } 61 return false, err 62 } 63 64 // RestoreContext restores the default SELinux context of given path 65 func RestoreContext(aPath string, mode RestoreMode) error { 66 if _, err := os.Stat(aPath); err != nil { 67 // path that cannot be accessed cannot be restored 68 return err 69 } 70 71 args := make([]string, 0, 2) 72 if mode.Recursive { 73 // -R: recursive 74 args = append(args, "-R") 75 } 76 args = append(args, aPath) 77 78 return exec.Command("restorecon", args...).Run() 79 } 80 81 // SnapMountContext finds out the right context for mounting snaps 82 func SnapMountContext() string { 83 // TODO: consider reading this from an external configuration file, such 84 // as per app contexts, from 85 // /etc/selinux/targeted/contexts/snapd_contexts like go-selinux and 86 // podman do for container volumes. 87 return "system_u:object_r:snappy_snap_t:s0" 88 }