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  }