github.com/opencontainers/umoci@v0.4.8-0.20240508124516-656e4836fb0d/pkg/fseval/fseval_rootless.go (about) 1 /* 2 * umoci: Umoci Modifies Open Containers' Images 3 * Copyright (C) 2016-2020 SUSE LLC 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package fseval 19 20 import ( 21 "io" 22 "os" 23 "path/filepath" 24 "time" 25 26 "github.com/opencontainers/umoci/pkg/unpriv" 27 "github.com/vbatts/go-mtree" 28 "golang.org/x/sys/unix" 29 ) 30 31 // Rootless is an FsEval implementation that uses "umoci/pkg/unpriv".* 32 // functions in order to provide the ability for unprivileged users (those 33 // without CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH) to evaluate parts of a 34 // filesystem that they own. Note that by necessity this requires modifying the 35 // filesystem (and thus will not work on read-only filesystems). 36 var Rootless FsEval = unprivFsEval(0) 37 38 // unprivFsEval is a hack to be able to make RootlessFsEval a const. 39 type unprivFsEval int 40 41 // Open is equivalent to unpriv.Open. 42 func (fs unprivFsEval) Open(path string) (*os.File, error) { 43 return unpriv.Open(path) 44 } 45 46 // Create is equivalent to unpriv.Create. 47 func (fs unprivFsEval) Create(path string) (*os.File, error) { 48 return unpriv.Create(path) 49 } 50 51 // Readdir is equivalent to unpriv.Readdir. 52 func (fs unprivFsEval) Readdir(path string) ([]os.FileInfo, error) { 53 return unpriv.Readdir(path) 54 } 55 56 // Lstat is equivalent to unpriv.Lstat. 57 func (fs unprivFsEval) Lstat(path string) (os.FileInfo, error) { 58 return unpriv.Lstat(path) 59 } 60 61 func (fs unprivFsEval) Lstatx(path string) (unix.Stat_t, error) { 62 return unpriv.Lstatx(path) 63 } 64 65 // Readlink is equivalent to unpriv.Readlink. 66 func (fs unprivFsEval) Readlink(path string) (string, error) { 67 return unpriv.Readlink(path) 68 } 69 70 // Symlink is equivalent to unpriv.Symlink. 71 func (fs unprivFsEval) Symlink(target, linkname string) error { 72 return unpriv.Symlink(target, linkname) 73 } 74 75 // Link is equivalent to unpriv.Link. 76 func (fs unprivFsEval) Link(target, linkname string) error { 77 return unpriv.Link(target, linkname) 78 } 79 80 // Chmod is equivalent to unpriv.Chmod. 81 func (fs unprivFsEval) Chmod(path string, mode os.FileMode) error { 82 return unpriv.Chmod(path, mode) 83 } 84 85 // Lutimes is equivalent to unpriv.Lutimes. 86 func (fs unprivFsEval) Lutimes(path string, atime, mtime time.Time) error { 87 return unpriv.Lutimes(path, atime, mtime) 88 } 89 90 // RemoveAll is equivalent to unpriv.RemoveAll. 91 func (fs unprivFsEval) RemoveAll(path string) error { 92 return unpriv.RemoveAll(path) 93 } 94 95 // Mknod is equivalent to unpriv.Mknod. 96 func (fs unprivFsEval) Mknod(path string, mode os.FileMode, dev uint64) error { 97 return unpriv.Mknod(path, mode, dev) 98 } 99 100 // MkdirAll is equivalent to unpriv.MkdirAll. 101 func (fs unprivFsEval) MkdirAll(path string, perm os.FileMode) error { 102 return unpriv.MkdirAll(path, perm) 103 } 104 105 // Llistxattr is equivalent to unpriv.Llistxattr 106 func (fs unprivFsEval) Llistxattr(path string) ([]string, error) { 107 return unpriv.Llistxattr(path) 108 } 109 110 // Lremovexattr is equivalent to unpriv.Lremovexattr 111 func (fs unprivFsEval) Lremovexattr(path, name string) error { 112 return unpriv.Lremovexattr(path, name) 113 } 114 115 // Lsetxattr is equivalent to unpriv.Lsetxattr 116 func (fs unprivFsEval) Lsetxattr(path, name string, value []byte, flags int) error { 117 return unpriv.Lsetxattr(path, name, value, flags) 118 } 119 120 // Lgetxattr is equivalent to unpriv.Lgetxattr 121 func (fs unprivFsEval) Lgetxattr(path string, name string) ([]byte, error) { 122 return unpriv.Lgetxattr(path, name) 123 } 124 125 // Lclearxattrs is equivalent to unpriv.Lclearxattrs 126 func (fs unprivFsEval) Lclearxattrs(path string, except map[string]struct{}) error { 127 return unpriv.Lclearxattrs(path, except) 128 } 129 130 // KeywordFunc returns a wrapper around the given mtree.KeywordFunc. 131 func (fs unprivFsEval) KeywordFunc(fn mtree.KeywordFunc) mtree.KeywordFunc { 132 return func(path string, info os.FileInfo, r io.Reader) ([]mtree.KeyVal, error) { 133 var kv []mtree.KeyVal 134 err := unpriv.Wrap(path, func(path string) error { 135 var err error 136 kv, err = fn(path, info, r) 137 return err 138 }) 139 return kv, err 140 } 141 } 142 143 // Walk is equivalent to filepath.Walk. 144 func (fs unprivFsEval) Walk(root string, fn filepath.WalkFunc) error { 145 return unpriv.Walk(root, fn) 146 }