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]

Add to Google Powered by Linux

[Older Kernel Discussion]     [Yosemite National Park Forum]     [Large Format Photos]     [Gimp]     [Yosemite Photos]     [Stuff]