-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprotect_linux.go
More file actions
38 lines (33 loc) · 1.15 KB
/
protect_linux.go
File metadata and controls
38 lines (33 loc) · 1.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//go:build linux
package writ
import (
"os"
"syscall"
"unsafe" //#nosec G103 -- ioctl for FS_APPEND_FL; unsafe.Pointer is the only available interface
)
// FS ioctl constants for 64-bit Linux (_IOR/'f'/1/sizeof(long) and _IOW/'f'/2/sizeof(long)).
const (
_fsIOCGetFlags = uintptr(0x80086601)
_fsIOCSetFlags = uintptr(0x40086602)
_fsAppendFL = int64(0x00000020)
)
// trySetAppendOnly attempts to set the FS_APPEND_FL attribute (chattr +a) on
// the file at path. Returns true if the flag was already set or successfully
// applied. Returns false on unsupported filesystems or insufficient privilege.
func trySetAppendOnly(path string) bool {
f, err := os.Open(path) //#nosec G304 -- construction-time path
if err != nil {
return false
}
defer func() { _ = f.Close() }()
var flags int64
if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), _fsIOCGetFlags, uintptr(unsafe.Pointer(&flags))); errno != 0 { //#nosec G103
return false
}
if flags&_fsAppendFL != 0 {
return true
}
flags |= _fsAppendFL
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), _fsIOCSetFlags, uintptr(unsafe.Pointer(&flags))) //#nosec G103
return errno == 0
}