From 1b277cb1ff5c299d3431e40d01af16e02c5f0115 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Thu, 7 Feb 2019 23:05:42 +0100 Subject: [PATCH] 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. --- src/borg/archiver.py | 8 ++++++-- src/borg/fuse.py | 13 ++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/borg/archiver.py b/src/borg/archiver.py index 4e350ed7c8..41e34a8331 100644 --- a/src/borg/archiver.py +++ b/src/borg/archiver.py @@ -2760,14 +2760,18 @@ def define_archive_filters_group(subparser, *, sort_by=True, first_last=True): 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 diff --git a/src/borg/fuse.py b/src/borg/fuse.py index f670a152ca..a6999514ab 100644 --- a/src/borg/fuse.py +++ b/src/borg/fuse.py @@ -308,9 +308,20 @@ def pop_option(options, key, present, not_present, wanted_type, int_base=0): 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)