github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/efivarfs/fs.go (about) 1 // Copyright 2022 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package efivarfs allows interaction with efivarfs of the 6 // linux kernel. 7 package efivarfs 8 9 import ( 10 "os" 11 12 "golang.org/x/sys/unix" 13 ) 14 15 // FS_IMMUTABLE_FL is an inode flag to make a file immutable. 16 const FS_IMMUTABLE_FL = 0x10 17 18 // getInodeFlags returns the extended attributes of a file. 19 func getInodeFlags(f *os.File) (int, error) { 20 // If I knew how unix.Getxattr works I'd use that... 21 flags, err := unix.IoctlGetInt(int(f.Fd()), unix.FS_IOC_GETFLAGS) 22 if err != nil { 23 return 0, &os.PathError{Op: "ioctl(FS_IOC_GETFLAGS)", Path: f.Name(), Err: err} 24 } 25 return flags, nil 26 } 27 28 // setInodeFlags sets the extended attributes of a file. 29 func setInodeFlags(f *os.File, flags int) error { 30 // If I knew how unix.Setxattr works I'd use that... 31 if err := unix.IoctlSetPointerInt(int(f.Fd()), unix.FS_IOC_SETFLAGS, flags); err != nil { 32 return &os.PathError{Op: "ioctl(FS_IOC_SETFLAGS)", Path: f.Name(), Err: err} 33 } 34 return nil 35 } 36 37 // makeMutable will change a files xattrs so that 38 // the immutable flag is removed and return a restore 39 // function which can reset the flag for that filee. 40 func makeMutable(f *os.File) (restore func(), err error) { 41 flags, err := getInodeFlags(f) 42 if err != nil { 43 return nil, err 44 } 45 if flags&FS_IMMUTABLE_FL == 0 { 46 return func() {}, nil 47 } 48 49 if err := setInodeFlags(f, flags&^FS_IMMUTABLE_FL); err != nil { 50 return nil, err 51 } 52 return func() { 53 if err := setInodeFlags(f, flags); err != nil { 54 // If setting the immutable did 55 // not work it's alright to do nothing 56 // because after a reboot the flag is 57 // automatically reapplied 58 return 59 } 60 }, nil 61 }