Re: Security Anti Symlink Attack Patch for 2.1.71

t0mmy (t0mmy@main.mobis.com)
Sun, 7 Dec 1997 08:08:50 -0600 (GMT+6)


I'm not sure if we are talking about the same patch, But I know Solar
Designer created a patch for buffer overflows, it creates an
anti-executable stack. It also has a hard/sym link patch. I have been
using it since 2.0.30 which i guess is what it originally came out for,
when I upgraded to 2.0.32 i did this:

cat patch |sed -e 's/2.0.30/2.0.32/' >>patch2
then just ran the patch. You can find that patch at
ftp://ftp.mobis.com/pub/linux/anti-stack-patch. something or other.

**********************************************************************
* Michael Freeman - UNIX/Network Engineer - Mobile Internet Services *
* www.mobis.com/~mfreeman - mfreeman@mobis.com >8) *
**********************************************************************
* "/earth is 98% full ... please delete anyone you can." *
**********************************************************************

On Sat, 6 Dec 1997, Christoph Lameter wrote:

> It is very common for tools to use temporary files in /tmp. Sadly anyone
> can create a symlink in /tmp and thus potentially redirect the creation of
> said temporary files.
>
> The following patch was originaly for 2.0.32 by solar@false.com. I ported
> it to 2.1.71 and separated it from another patch that came with it.
>
> The patch is also available from
> ftp://ftp.fuller.edu/Linux/symlink-attack-patch-2.1.71
>
> diff -urN linux-2.1.71/Documentation/Configure.help linux/Documentation/Configure.help
> --- linux-2.1.71/Documentation/Configure.help Thu Dec 4 19:19:34 1997
> +++ linux/Documentation/Configure.help Sat Dec 6 16:27:06 1997
> @@ -4364,6 +4364,27 @@
> other operating systems will pick up the idea of context-dependent
> translations. If unsure, say Y.
>
> +Symlink security fix (EXPERIMENTAL)
> +CONFIG_SYMLINK_FIX
> + A very common class of security hole on UNIX-like systems involves
> + a malicious user creating a symbolic link in /tmp pointing at
> + another user's file. When the victim then writes to that file they
> + inadvertently write to the wrong file. Enabling this option fixes
> + this class of hole by preventing a process from following a link
> + which is in a +t directory unless they own the link. However, this
> + fix does not affect links owned by root, since these could only be
> + created by someone having root access already. To prevent someone
> + from using a hard link instead, this fix does not allow non-root
> + users to create hard links in a +t directory to files they don't
> + own. Note that this fix might break things. Only say Y if security
> + is more important.
> +
> +Log symlink exploit attempts
> +CONFIG_SYMLINK_LOG
> + This option enables logging of symlink (and hard link) exploit
> + attempts. No more than one attempt per minute is logged, so this is
> + safe. Say Y.
> +
> Minix fs support
> CONFIG_MINIX_FS
> Minix is a simple operating system used in many classes about
> diff -urN linux-2.1.71/arch/alpha/defconfig linux/arch/alpha/defconfig
> --- linux-2.1.71/arch/alpha/defconfig Fri Sep 19 21:46:38 1997
> +++ linux/arch/alpha/defconfig Sat Dec 6 16:25:05 1997
> @@ -196,6 +196,8 @@
> # Filesystems
> #
> # CONFIG_QUOTA is not set
> +# CONFIG_SYMLINK_FIX is not set
> +CONFIG_SYMLINK_LOG=y
> # CONFIG_MINIX_FS is not set
> CONFIG_EXT2_FS=y
> # CONFIG_FAT_FS is not set
> diff -urN linux-2.1.71/arch/i386/defconfig linux/arch/i386/defconfig
> --- linux-2.1.71/arch/i386/defconfig Thu Dec 4 19:19:35 1997
> +++ linux/arch/i386/defconfig Sat Dec 6 16:33:48 1997
> @@ -211,6 +211,8 @@
> # Filesystems
> #
> # CONFIG_QUOTA is not set
> +# CONFIG_SYMLINK_FIX is not set
> +CONFIG_SYMLINK_LOG=y
> # CONFIG_MINIX_FS is not set
> CONFIG_EXT2_FS=y
> CONFIG_ISO9660_FS=y
> diff -urN linux-2.1.71/arch/m68k/defconfig linux/arch/m68k/defconfig
> --- linux-2.1.71/arch/m68k/defconfig Thu Jul 31 13:09:16 1997
> +++ linux/arch/m68k/defconfig Sat Dec 6 16:25:05 1997
> @@ -152,6 +152,8 @@
> # Filesystems
> #
> # CONFIG_QUOTA is not set
> +# CONFIG_SYMLINK_FIX is not set
> +CONFIG_SYMLINK_LOG=y
> CONFIG_MINIX_FS=y
> CONFIG_EXT2_FS=y
> CONFIG_FAT_FS=y
> diff -urN linux-2.1.71/arch/mips/defconfig linux/arch/mips/defconfig
> --- linux-2.1.71/arch/mips/defconfig Sat Aug 16 09:51:07 1997
> +++ linux/arch/mips/defconfig Sat Dec 6 16:34:41 1997
> @@ -155,6 +155,8 @@
> # Filesystems
> #
> # CONFIG_QUOTA is not set
> +# CONFIG_SYMLINK_FIX is not set
> +CONFIG_SYMLINK_LOG=y
> # CONFIG_MINIX_FS is not set
> CONFIG_EXT2_FS=y
> # CONFIG_FAT_FS is not set
> diff -urN linux-2.1.71/arch/sparc/defconfig linux/arch/sparc/defconfig
> --- linux-2.1.71/arch/sparc/defconfig Sat Aug 16 09:51:08 1997
> +++ linux/arch/sparc/defconfig Sat Dec 6 16:34:18 1997
> @@ -182,6 +182,8 @@
> # Filesystems
> #
> CONFIG_QUOTA=y
> +# CONFIG_SYMLINK_FIX is not set
> +CONFIG_SYMLINK_LOG=y
> CONFIG_MINIX_FS=m
> CONFIG_EXT2_FS=y
> CONFIG_FAT_FS=m
> diff -urN linux-2.1.71/fs/Config.in linux/fs/Config.in
> --- linux-2.1.71/fs/Config.in Wed Dec 3 07:40:18 1997
> +++ linux/fs/Config.in Sat Dec 6 16:31:58 1997
> @@ -6,6 +6,13 @@
>
> bool 'Quota support' CONFIG_QUOTA
>
> +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
> + bool 'Symlink security fix (EXPERIMENTAL)' CONFIG_SYMLINK_FIX
> + if [ "$CONFIG_SYMLINK_FIX" = "y" ]; then
> + bool ' Log symlink exploit attempts' CONFIG_SYMLINK_LOG
> + fi
> +fi
> +
> tristate 'Minix fs support' CONFIG_MINIX_FS
> tristate 'Second extended fs support' CONFIG_EXT2_FS
>
> diff -urN linux-2.1.71/fs/namei.c linux/fs/namei.c
> --- linux-2.1.71/fs/namei.c Mon Dec 1 20:05:00 1997
> +++ linux/fs/namei.c Sat Dec 6 17:37:46 1997
> @@ -22,6 +22,7 @@
> #include <linux/proc_fs.h>
> #include <linux/smp.h>
> #include <linux/smp_lock.h>
> +#include <linux/config.h>
>
> #include <asm/uaccess.h>
> #include <asm/unaligned.h>
> @@ -73,6 +74,11 @@
> * and in the old Linux semantics.
> */
>
> +/* [6-Dec-97 Christoph Lameter] port symlink attack patch from solar@false.com
> + * Do not follow non-root non-user symlinks in +t dirs. Do not allow hardlinks to
> + * files owned by other users in +t dirs.
> + */
> +
> static char * quicklist = NULL;
> static int quickcount = 0;
> struct semaphore quicklock = MUTEX;
> @@ -300,17 +306,34 @@
>
> if (inode && inode->i_op && inode->i_op->follow_link) {
> if (current->link_count < 5) {
> - struct dentry * result;
> +#ifdef CONFIG_SYMLINK_FIX
> +/*
> + * Don't follow links that we don't own in +t directories, unless the link
> + * is owned by root.
> + */
> + if (S_ISLNK(inode->i_mode) && (base->d_inode->i_mode & S_ISVTX) &&
> + inode->i_uid && current->fsuid != inode->i_uid) {
> +#ifdef CONFIG_SYMLINK_LOG
> + security_alert("symlink");
> +#endif
> + dput(dentry);
> + dentry = ERR_PTR(-EPERM);
> + } else
> +#endif
> + {
> + struct dentry * result;
>
> - current->link_count++;
> - /* This eats the base */
> - result = inode->i_op->follow_link(inode, base);
> - current->link_count--;
> + current->link_count++;
> + /* This eats the base */
> + result = inode->i_op->follow_link(inode, base);
> + current->link_count--;
> + dput(dentry);
> + return result;
> + }
> + } else {
> dput(dentry);
> - return result;
> + dentry = ERR_PTR(-ELOOP);
> }
> - dput(dentry);
> - dentry = ERR_PTR(-ELOOP);
> }
> dput(base);
> return dentry;
> @@ -1029,6 +1052,20 @@
> error = -EEXIST;
> if (new_dentry->d_inode)
> goto exit_lock;
> +
> +#ifdef CONFIG_SYMLINK_FIX
> +/*
> + * Don't allow non-root users to create hard links to files they don't own
> + * in a +t directory.
> + */
> + error = -EPERM;
> + if ((dir->d_inode->i_mode & S_ISVTX) && current->fsuid != old_dentry->d_inode->i_uid && !fsuser()) {
> +#ifdef CONFIG_SYMLINK_LOG
> + security_alert("hard link");
> +#endif
> + goto exit_lock;
> + }
> +#endif
>
> error = -EROFS;
> if (IS_RDONLY(dir->d_inode))
> diff -urN linux-2.1.71/include/linux/kernel.h linux/include/linux/kernel.h
> --- linux-2.1.71/include/linux/kernel.h Sun Nov 30 18:29:02 1997
> +++ linux/include/linux/kernel.h Sat Dec 6 16:25:06 1997
> @@ -80,6 +80,27 @@
> (((addr) >> 16) & 0xff), \
> (((addr) >> 24) & 0xff)
>
> +#define security_alert(msg) { \
> + static unsigned long warning_time = 0, no_flood_yet = 0; \
> +\
> +/* Make sure at least one minute passed since the last warning logged */ \
> + if (!warning_time || jiffies - warning_time > 60 * HZ) { \
> + warning_time = jiffies; no_flood_yet = 1; \
> + printk( \
> + KERN_ALERT \
> + "Possible " msg " exploit attempt:\n" \
> + KERN_ALERT \
> + "Process %s (pid %d, uid %d, euid %d).\n", \
> + current->comm, current->pid, \
> + current->uid, current->euid); \
> + } else if (no_flood_yet) { \
> + warning_time = jiffies; no_flood_yet = 0; \
> + printk( \
> + KERN_ALERT \
> + "More possible " msg " exploit attempts follow.\n"); \
> + } \
> +}
> +
> #endif /* __KERNEL__ */
>
> #define SI_LOAD_SHIFT 16
> diff -urN linux-2.1.71/init/patches/stack_noexec-symlink-security-fix.pinfo linux/init/patches/stack_noexec-symlink-security-fix.pinfo
> --- linux-2.1.71/init/patches/stack_noexec-symlink-security-fix.pinfo Wed Dec 31 16:00:00 1969
> +++ linux/init/patches/stack_noexec-symlink-security-fix.pinfo Sat Dec 6 16:25:06 1997
> @@ -0,0 +1 @@
> +Non-executable stack and tmp-symlink security fix (Solar Designer <solar@false.com>)
>
>
>