aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Lackner2019-01-04 04:53:55 +0100
committerrfjakob2019-01-04 09:34:12 +0100
commitcdb57ca7e0b99ee8e5a844d5177d03d5857fab27 (patch)
treeeaf32b836357ccde09cc215bcc99597522c8716e
parentacf7e52022fcf67a9db58bda59efc2e932e8892d (diff)
fsck: Do not show files/directories without access permissions as corrupt.
When running as a regular user, error EACCES does not necessarily mean that the file/directory/xattr is corrupt, but just that we do not have sufficient access permissions. Add a hint that running as root can be used to check everything. Fixes: https://github.com/rfjakob/gocryptfs/issues/309
-rw-r--r--fsck.go43
1 files changed, 35 insertions, 8 deletions
diff --git a/fsck.go b/fsck.go
index 31033de..27612c8 100644
--- a/fsck.go
+++ b/fsck.go
@@ -22,18 +22,30 @@ type fsckObj struct {
fs *fusefrontend.FS
// List of corrupt files
corruptList []string
+ // List of skipped files
+ skippedList []string
// Protects corruptList
- corruptListLock sync.Mutex
+ listLock sync.Mutex
// stop a running watchMitigatedCorruptions thread
watchDone chan struct{}
// Inode numbers of hard-linked files (Nlink > 1) that we have already checked
seenInodes map[uint64]struct{}
}
+func runsAsRoot() bool {
+ return syscall.Geteuid() == 0
+}
+
func (ck *fsckObj) markCorrupt(path string) {
- ck.corruptListLock.Lock()
+ ck.listLock.Lock()
ck.corruptList = append(ck.corruptList, path)
- ck.corruptListLock.Unlock()
+ ck.listLock.Unlock()
+}
+
+func (ck *fsckObj) markSkipped(path string) {
+ ck.listLock.Lock()
+ ck.skippedList = append(ck.skippedList, path)
+ ck.listLock.Unlock()
}
// Watch for mitigated corruptions that occur during OpenDir()
@@ -59,8 +71,12 @@ func (ck *fsckObj) dir(path string) {
ck.watchDone <- struct{}{}
// Also catch non-mitigated corruptions
if !status.Ok() {
- ck.markCorrupt(path)
fmt.Printf("fsck: error opening dir %q: %v\n", path, status)
+ if status == fuse.EACCES && !runsAsRoot() {
+ ck.markSkipped(path)
+ } else {
+ ck.markCorrupt(path)
+ }
return
}
// Sort alphabetically
@@ -128,8 +144,12 @@ func (ck *fsckObj) file(path string) {
ck.xattrs(path)
f, status := ck.fs.Open(path, syscall.O_RDONLY, nil)
if !status.Ok() {
- ck.markCorrupt(path)
fmt.Printf("fsck: error opening file %q: %v\n", path, status)
+ if status == fuse.EACCES && !runsAsRoot() {
+ ck.markSkipped(path)
+ } else {
+ ck.markCorrupt(path)
+ }
return
}
defer f.Release()
@@ -194,7 +214,11 @@ func (ck *fsckObj) xattrs(path string) {
_, status := ck.fs.GetXAttr(path, a, nil)
if !status.Ok() {
fmt.Printf("fsck: error reading xattr %q from %q: %v\n", a, path, status)
- ck.markCorrupt(path)
+ if status == fuse.EACCES && !runsAsRoot() {
+ ck.markSkipped(path)
+ } else {
+ ck.markCorrupt(path)
+ }
}
}
}
@@ -215,11 +239,14 @@ func fsck(args *argContainer) {
}
ck.dir("")
wipeKeys()
- if len(ck.corruptList) == 0 {
+ if len(ck.corruptList) == 0 && len(ck.skippedList) == 0 {
tlog.Info.Printf("fsck summary: no problems found\n")
return
}
- fmt.Printf("fsck summary: %d corrupt files\n", len(ck.corruptList))
+ if len(ck.skippedList) > 0 {
+ tlog.Warn.Printf("fsck: re-run this program as root to check all files!\n")
+ }
+ fmt.Printf("fsck summary: %d corrupt files, %d files skipped\n", len(ck.corruptList), len(ck.skippedList))
os.Exit(exitcodes.FsckErrors)
}