Browse Source

security fix: configure FUSE with "default_permissions", fixes #3903

"default_permissions" is now enforced by borg by default to let the
kernel check uid/gid/mode based permissions.

"ignore_permissions" can be given to not enforce "default_permissions".

note: man mount.fuse explicitly tells about the security issue:

    default_permissions
	By  default FUSE doesn't check file access permissions, ...
	This option enables permission checking, restricting access
	based on file mode.
	This option is usually useful together with the allow_other
	mount option.

We consider this a pitfall waiting for someone to fall into and this is
why we chose to change the default behaviour for borg.
Thomas Waldmann 6 years ago
parent
commit
1b277cb1ff
2 changed files with 18 additions and 3 deletions
  1. 6 2
      src/borg/archiver.py
  2. 12 1
      src/borg/fuse.py

+ 6 - 2
src/borg/archiver.py

@@ -2760,14 +2760,18 @@ class Archiver:
         To allow a regular user to use fstab entries, add the ``user`` option:
         ``/path/to/repo /mnt/point fuse.borgfs defaults,noauto,user 0 0``
 
-        For mount options, see the fuse(8) manual page. Additional mount options
-        supported by borg:
+        For FUSE configuration and mount options, see the mount.fuse(8) manual page.
+
+        Additional mount options supported by borg:
 
         - versions: when used with a repository mount, this gives a merged, versioned
           view of the files in the archives. EXPERIMENTAL, layout may change in future.
         - allow_damaged_files: by default damaged files (where missing chunks were
           replaced with runs of zeros by borg check ``--repair``) are not readable and
           return EIO (I/O error). Set this option to read such files.
+        - ignore_permissions: for security reasons the "default_permissions" mount
+          option is internally enforced by borg. "ignore_permissions" can be given to
+          not enforce "default_permissions".
 
         The BORG_MOUNT_DATA_CACHE_ENTRIES environment variable is meant for advanced users
         to tweak the performance. It sets the number of cached data chunks; additional

+ 12 - 1
src/borg/fuse.py

@@ -308,9 +308,20 @@ class FuseOperations(llfuse.Operations):
             else:
                 return not_present
 
-        options = ['fsname=borgfs', 'ro']
+        # default_permissions enables permission checking by the kernel. Without
+        # this, any umask (or uid/gid) would not have an effect and this could
+        # cause security issues if used with allow_other mount option.
+        # When not using allow_other or allow_root, access is limited to the
+        # mounting user anyway.
+        options = ['fsname=borgfs', 'ro', 'default_permissions']
         if mount_options:
             options.extend(mount_options.split(','))
+        ignore_permissions = pop_option(options, 'ignore_permissions', True, False, bool)
+        if ignore_permissions:
+            # in case users have a use-case that requires NOT giving "default_permissions",
+            # this is enabled by the custom "ignore_permissions" mount option which just
+            # removes "default_permissions" again:
+            pop_option(options, 'default_permissions', True, False, bool)
         self.allow_damaged_files = pop_option(options, 'allow_damaged_files', True, False, bool)
         self.versions = pop_option(options, 'versions', True, False, bool)
         self.uid_forced = pop_option(options, 'uid', None, None, int)