aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--internal/configfile/feature_flags.go11
-rw-r--r--mount.go26
3 files changed, 30 insertions, 9 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 792b879..fb55979 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -48,7 +48,7 @@ jobs:
# Build & upload static binary
- run: ./build-without-openssl.bash
- - uses: actions/upload-artifact@v6
+ - uses: actions/upload-artifact@v7
with:
name: gocryptfs ${{ github.sha }} static ${{ runner.arch }} binary, Go ${{ matrix.go }}
path: gocryptfs
diff --git a/internal/configfile/feature_flags.go b/internal/configfile/feature_flags.go
index d6627a5..d5bd6d4 100644
--- a/internal/configfile/feature_flags.go
+++ b/internal/configfile/feature_flags.go
@@ -1,5 +1,9 @@
package configfile
+import (
+ "slices"
+)
+
type flagIota int
const (
@@ -64,10 +68,5 @@ func isFeatureFlagKnown(flag string) bool {
// IsFeatureFlagSet returns true if the feature flag "flagWant" is enabled.
func (cf *ConfFile) IsFeatureFlagSet(flagWant flagIota) bool {
flagString := knownFlags[flagWant]
- for _, flag := range cf.FeatureFlags {
- if flag == flagString {
- return true
- }
- }
- return false
+ return slices.Contains(cf.FeatureFlags, flagString)
}
diff --git a/mount.go b/mount.go
index f7378aa..2508409 100644
--- a/mount.go
+++ b/mount.go
@@ -449,9 +449,18 @@ func initGoFuse(rootNode fs.InodeEmbedder, args *argContainer) *fuse.Server {
if runtime.GOOS == "darwin" {
opts["volname"] = strings.Replace(path.Base(args.mountpoint), ",", "_", -1)
}
+ underlyingFilesystemRo, err := isReadOnlyFilesystem(args.cipherdir)
+ if err != nil {
+ tlog.Debug.Printf("Error checking if cipherdir is on a read-only filesystem: %s", err)
+ } else if underlyingFilesystemRo && args.rw {
+ tlog.Fatal.Printf("Writeable mount explicitly requested but cipherdir %s is on a read-only filesystem, refusing.", args.cipherdir)
+ os.Exit(exitcodes.Usage)
+ } else if underlyingFilesystemRo && !args.ro {
+ tlog.Info.Printf("Cipherdir %s is on a read-only filesystem, mounting as read-only.", args.cipherdir)
+ }
// The kernel enforces read-only operation, we just have to pass "ro".
- // Reverse mounts are always read-only.
- if args.ro || args.reverse {
+ // Reverse mounts and mounts with cipherdirs on read-only filesystems are always read-only.
+ if args.ro || args.reverse || underlyingFilesystemRo {
opts["ro"] = ""
} else if args.rw {
opts["rw"] = ""
@@ -562,3 +571,16 @@ func unmount(srv *fuse.Server, mountpoint string) {
}
}
}
+
+const (
+ ST_RDONLY = 0x1
+)
+
+func isReadOnlyFilesystem(path string) (bool, error) {
+ var stat syscall.Statfs_t
+ if err := syscall.Statfs(path, &stat); err != nil {
+ return false, err
+ }
+
+ return (stat.Flags & ST_RDONLY) != 0, nil
+}