|
|
|
Re: [PATCH] fs: hardlink creation restrictions | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
|
|
* Kees Cook <keescook@xxxxxxxxxxxx> wrote:
> This is the other half of link restrictions, now that symlink
> restriction has landed in -mm.
Nice features!
> On systems that have user-writable directories on the same
> partition as system files, a long-standing class of security
> issues is the hardlink-based time-of-check-time-of-use race,
> most commonly seen in world-writable directories like /tmp.
> The common method of exploitation of this flaw is to cross
> privilege boundaries when following a given hardlink (i.e. a
> root process follows a hardlink created by another user).
> Additionally, an issue exists where users can "pin" a
> potentially vulnerable setuid/setgid file so that an
> administrator will not actually upgrade a system fully.
>
> The solution is to permit hardlinks to only be created when
> the user is already the existing file's owner, or if they
> already have read/write access to the existing file.
>
> Many Linux users are surprised when they learn they can link
> to files they have no access to, so this change appears to
> follow the doctrine of "least surprise". Additionally, this
> change does not violate POSIX, which states "the
> implementation may require that the calling process has
> permission to access the existing file"[1].
>
> This change is known to break some implementations of the "at"
> daemon, though the version used by Fedora and Ubuntu has been
> fixed[2] for a while. Otherwise, the change has been
> undisruptive while in use in Ubuntu for the last 1.5 years.
>
> This patch is based on the patch in Openwall and grsecurity.
> I have added a sysctl to enable the protected behavior,
> documentation, and an audit notification.
>
> [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html
> [2] http://anonscm.debian.org/gitweb/?p=collab-maint/at.git;a=commitdiff;h=f4114656c3a6c6f6070e315ffdf940a49eda3279
>
> Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx>
> ---
> Documentation/sysctl/fs.txt | 21 ++++++++++++
> fs/Kconfig | 46 ++++++++++++++++++++-------
> fs/namei.c | 72 ++++++++++++++++++++++++++++++++++++++++++-
> include/linux/fs.h | 1 +
> kernel/sysctl.c | 11 ++++++-
> 5 files changed, 137 insertions(+), 14 deletions(-)
>
> diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
> index 4b47cd5..08458be 100644
> --- a/Documentation/sysctl/fs.txt
> +++ b/Documentation/sysctl/fs.txt
> @@ -32,6 +32,7 @@ Currently, these files are in /proc/sys/fs:
> - nr_open
> - overflowuid
> - overflowgid
> +- protected_nonaccess_hardlinks
> - protected_sticky_symlinks
> - suid_dumpable
> - super-max
> @@ -158,6 +159,26 @@ The default is 65534.
>
> ==============================================================
>
> +protected_nonaccess_hardlinks:
> +
> +A long-standing class of security issues is the hardlink-based
> +time-of-check-time-of-use race, most commonly seen in world-writable
> +directories like /tmp. The common method of exploitation of this flaw
> +is to cross privilege boundaries when following a given hardlink (i.e. a
> +root process follows a hardlink created by another user). Additionally,
> +on systems without separated partitions, this stops unauthorized users
> +from "pinning" vulnerable setuid/setgid files against being upgraded by
> +the administrator.
> +
> +When set to "0", hardlink creation behavior is unrestricted.
> +
> +When set to "1" hardlinks cannot be created by users if they do not
> +already own the source file, or do not have read/write access to it.
> +
> +This protection is based on the restrictions in Openwall and grsecurity.
> +
> +==============================================================
> +
> protected_sticky_symlinks:
>
> A long-standing class of security issues is the symlink-based
> diff --git a/fs/Kconfig b/fs/Kconfig
> index ca279b7..66f9334 100644
> --- a/fs/Kconfig
> +++ b/fs/Kconfig
> @@ -271,27 +271,29 @@ endif # NETWORK_FILESYSTEMS
> source "fs/nls/Kconfig"
> source "fs/dlm/Kconfig"
>
> -config PROTECTED_STICKY_SYMLINKS
> - bool "Evaluate vulnerable symlink conditions"
> - default y
> +config PROTECTED_LINKS
> + bool "Evaluate vulnerable link conditions"
> + default n
> help
> - A long-standing class of security issues is the symlink-based
> + A long-standing class of security issues is the link-based
> time-of-check-time-of-use race, most commonly seen in
> world-writable directories like /tmp. The common method of
> exploitation of this flaw is to cross privilege boundaries
> - when following a given symlink (i.e. a root process follows
> - a malicious symlink belonging to another user).
> + when following a given link (i.e. a root process follows
> + a malicious symlink belonging to another user, or a hardlink
> + created to a root-owned file).
>
> - Enabling this adds the logic to examine these dangerous symlink
> - conditions. Whether or not the dangerous symlink situations are
> - allowed is controlled by PROTECTED_STICKY_SYMLINKS_ENABLED.
> + Enabling this adds the logic to examine these dangerous link
> + conditions. Whether or not the dangerous link situations are
> + allowed is controlled by PROTECTED_NONACCESS_HARDLINKS_ENABLED and
> + PROTECTED_STICKY_SYMLINKS_ENABLED.
>
> config PROTECTED_STICKY_SYMLINKS_ENABLED
> - depends on PROTECTED_STICKY_SYMLINKS
> + depends on PROTECTED_LINKS
> bool "Disallow symlink following in sticky world-writable dirs"
> default y
> help
> - Solve ToCToU symlink race vulnerablities by permitting symlinks
> + Solve ToCToU symlink race vulnerabilities by permitting symlinks
> to be followed only when outside a sticky world-writable directory,
> or when the uid of the symlink and follower match, or when the
> directory and symlink owners match.
> @@ -300,9 +302,29 @@ config PROTECTED_STICKY_SYMLINKS_ENABLED
> via /proc/sys/kernel/protected_sticky_symlinks.
>
> config PROTECTED_STICKY_SYMLINKS_ENABLED_SYSCTL
> - depends on PROTECTED_STICKY_SYMLINKS
> + depends on PROTECTED_LINKS
> int
> default "1" if PROTECTED_STICKY_SYMLINKS_ENABLED
> default "0"
>
> +config PROTECTED_NONACCESS_HARDLINKS_ENABLED
> + depends on PROTECTED_LINKS
> + bool "Disallow hardlink creation to non-accessible files"
> + default y
> + help
> + Solve ToCToU hardlink race vulnerabilities by permitting hardlinks
> + to be created only when to a regular file that is owned by the user,
> + or is readable and writable by the user. Also blocks users from
> + "pinning" vulnerable setuid/setgid programs from being upgraded by
> + the administrator.
> +
> + When PROC_SYSCTL is enabled, this setting can also be controlled
> + via /proc/sys/kernel/protected_nonaccess_hardlinks.
I'd add a:
See Documentation/sysctl/fs.txt for details.
line as well.
> +config PROTECTED_NONACCESS_HARDLINKS_ENABLED_SYSCTL
> + depends on PROTECTED_LINKS
> + int
> + default "1" if PROTECTED_NONACCESS_HARDLINKS_ENABLED
> + default "0"
Naming nit: how about dropping the _NONACCESS/_nonaccess names
complete and turn it into protected_hardlinks? The longer
variant is not any better descriptive, and needlessly longer.
The PROTECTED_SYMLINKS/PROTECTED_HARDLINKS naming is thus also
nicely symmetric.
> +#ifdef CONFIG_AUDIT
> + if (error) {
> + struct audit_buffer *ab;
> +
> + ab = audit_log_start(current->audit_context,
> + GFP_KERNEL, AUDIT_AVC);
> + audit_log_format(ab, "op=linkat action=denied");
> + audit_log_format(ab, " pid=%d comm=", current->pid);
> + audit_log_untrustedstring(ab, current->comm);
> + audit_log_d_path(ab, " path=", old_path);
> + audit_log_format(ab, " dev=");
> + audit_log_untrustedstring(ab, inode->i_sb->s_id);
> + audit_log_format(ab, " ino=%lu", inode->i_ino);
> + audit_log_end(ab);
> + }
> +#endif
Small detail: don't these audit methods map to nothing on
!CONFIG_AUDIT, allowing the #ifdef to be dropped? (if not then
it should really be so.)
Otherwise:
Acked-by: Ingo Molnar <mingo@xxxxxxx>
Thanks,
Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Other Archives] [Linux Kernel Newbies] [Linux Driver Development] [Fedora Kernel] [Linux Kernel Testers] [Linux SH] [Linux Omap] [Linux Kbuild] [Linux Tape] [Linux Input] [Linux Kernel Janitors] [Linux Kernel Packagers] [Linux Doc] [Linux Man Pages] [Linux API] [Linux Memory Management] [Linux Modules] [Linux Standards] [Kernel Announce] [Netdev] [Git] [Linux PCI] Linux CAN Development [Linux I2C] [Linux RDMA] [Linux NUMA] [Netfilter] [Netfilter Devel] [SELinux] [Bugtraq] [FIO] [Linux Perf Users] [Linux Serial] [Linux PPP] [Linux ISDN] [Linux Next] [Kernel Stable Commits] [Linux Tip Commits] [Kernel MM Commits] [Linux Security Module] [Filesystem Development] [Ext3 Filesystem] [Linux bcache] [Ext4 Filesystem] [Linux BTRFS] [Linux CEPH Filesystem] [Linux XFS] [XFS] [Linux NFS] [Linux CIFS] [Ecryptfs] [Linux NILFS] [Linux Cachefs] [Reiser FS] [Initramfs] [Linux FB Devel] [Linux OpenGL] [DRI Devel] [Fastboot] [Linux RT Users] [Linux RT Stable] [eCos] [Corosync] [Linux Clusters] [LVS Devel] [Hot Plug] [Linux Virtualization] [KVM] [KVM PPC] [KVM ia64] [Linux Containers] [Linux Hexagon] [Linux Cgroups] [Util Linux] [Wireless] [Linux Bluetooth] [Bluez Devel] [Ethernet Bridging] [Embedded Linux] [Barebox] [Linux MMC] [Linux IIO] [Sparse] [Smatch] [Linux Arch] [x86 Platform Driver] [Linux ACPI] [Linux IBM ACPI] [LM Sensors] [CPU Freq] [Linux Power Management] [Linmodems] [Linux DCCP] [Linux SCTP] [ALSA Devel] [Linux USB] [Linux PA RISC] [Linux Samsung SOC] [MIPS Linux] [IBM S/390 Linux] [ARM Linux] [ARM Kernel] [ARM MSM] [Tegra Devel] [Sparc Linux] [Linux Security] [Linux Sound] [Linux Media] [Video 4 Linux] [Linux IRDA Users] [Linux for the blind] [Linux RAID] [Linux ATA RAID] [Device Mapper] [Linux SCSI] [SCSI Target Devel] [Linux SCSI Target Infrastructure] [Linux IDE] [Linux SMP] [Linux AXP] [Linux Alpha] [Linux M68K] [Linux ia64] [Linux 8086] [Linux x86_64] [Linux Config] [Linux Apps] [Linux MSDOS] [Linux X.25] [Linux Crypto] [DM Crypt] [Linux Trace Users] [Linux Btrace] [Linux Watchdog] [Utrace Devel] [Linux C Programming] [Linux Assembly] [Dash] [DWARVES] [Hail Devel] [Linux Kernel Debugger] [Linux gcc] [Gcc Help] [X.Org] [Wine]
![]() |
![]() |
[Older Kernel Discussion] [Yosemite National Park Forum] [Large Format Photos] [Gimp] [Yosemite Photos] [Stuff]