浏览代码

Merge pull request #4355 from ThomasWaldmann/fuse-default-options-1.0

security fix: configure FUSE with "default_permissions", fixes #3903
TW 6 年之前
父节点
当前提交
cc29608917
共有 2 个文件被更改,包括 21 次插入3 次删除
  1. 5 2
      borg/archiver.py
  2. 16 1
      borg/fuse.py

+ 5 - 2
borg/archiver.py

@@ -1613,12 +1613,15 @@ class Archiver:
         memory usage can be up to ~8 MiB times this number. The default is the number
         memory usage can be up to ~8 MiB times this number. The default is the number
         of CPU cores.
         of CPU cores.
 
 
-        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:
         - allow_damaged_files: by default damaged files (where missing chunks were
         - allow_damaged_files: by default damaged files (where missing chunks were
           replaced with runs of zeros by borg check --repair) are not readable and
           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.
           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".
 
 
         When the daemonized process receives a signal or crashes, it does not unmount.
         When the daemonized process receives a signal or crashes, it does not unmount.
         Unmounting in these cases could cause an active rsync or similar process
         Unmounting in these cases could cause an active rsync or similar process

+ 16 - 1
borg/fuse.py

@@ -84,7 +84,12 @@ class FuseOperations(llfuse.Operations):
 
 
     def mount(self, mountpoint, mount_options, foreground=False):
     def mount(self, mountpoint, mount_options, foreground=False):
         """Mount filesystem on *mountpoint* with *mount_options*."""
         """Mount filesystem on *mountpoint* with *mount_options*."""
-        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:
         if mount_options:
             options.extend(mount_options.split(','))
             options.extend(mount_options.split(','))
         try:
         try:
@@ -92,6 +97,16 @@ class FuseOperations(llfuse.Operations):
             self.allow_damaged_files = True
             self.allow_damaged_files = True
         except ValueError:
         except ValueError:
             pass
             pass
+        try:
+            options.remove('ignore_permissions')
+            # if above does not raise ValueError (meaning: ignore_permissions is present),
+            # we remove default_permissions again.
+            # 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:
+            options.remove('default_permissions')
+        except ValueError:
+            pass
         llfuse.init(self, mountpoint, options)
         llfuse.init(self, mountpoint, options)
         if not foreground:
         if not foreground:
             old_id, new_id = daemonize()
             old_id, new_id = daemonize()