xorl %eax, %eax

GRKERNSEC_AUDIT_MOUNT (Un)Mount Logging

leave a comment »

This option of grsecurity could be useful in systems that have no reason of mounting/un-mounting devices on a regular basis. Such behavior on those systems could imply a possible attack. Here is the configuration option’s description for that feature:

config GRKERNSEC_AUDIT_MOUNT
	bool "(Un)Mount logging"
	help
	  If you say Y here, all mounts and unmounts will be logged.  If the
	  sysctl option is enabled, a sysctl option with name "audit_mount" is
	  created.

As the description says, the sysctl option for that feature is ‘audit_mount’.

#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
	{
		.procname	= "audit_mount",
		.data		= &grsec_enable_mount,
		.maxlen		= sizeof(int),
		.mode		= 0600,
		.proc_handler	= &proc_dointvec,
	},
#endif

That initializes ‘grsec_enable_mount’ which is used at grsecurity/grsec_mount.c in the routines below.

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mount.h>
#include <linux/grsecurity.h>
#include <linux/grinternal.h>

void
gr_log_remount(const char *devname, const int retval)
{
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
	if (grsec_enable_mount && (retval >= 0))
		gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
#endif
	return;
}

void
gr_log_unmount(const char *devname, const int retval)
{
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
	if (grsec_enable_mount && (retval >= 0))
		gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
#endif
	return;
}

void
gr_log_mount(const char *from, const char *to, const int retval)
{
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
	if (grsec_enable_mount && (retval >= 0))
		gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
#endif
	return;
}

All three of them are simple logging routines that will log the events if the protection is enabled and the return value passed to them as their last argument isn’t negative which means that it was a successful operation. If we now move to fs/namespace.c of Linux kernel’s code we’ll see this:

static int do_umount(struct vfsmount *mnt, int flags)
{
        struct super_block *sb = mnt->mnt_sb;
        int retval;
        LIST_HEAD(umount_list);
    ...
        if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
                /*
                 * Special case for "unmounting" root ...
                 * we just try to remount it readonly.
                 */
                down_write(&sb->s_umount);
                if (!(sb->s_flags & MS_RDONLY))
                        retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
                up_write(&sb->s_umount);

                gr_log_remount(mnt->mnt_devname, retval)
 
                return retval;
        }
    ...
        br_write_unlock(vfsmount_lock);
        up_write(&namespace_sem);
        release_mounts(&umount_list);

        gr_log_unmount(mnt->mnt_devname, retval);

        return retval;
}

That will log any attempt to re-mount the root filesystem as read-only and also, gr_log_unmount() is called at the end of this routine and it will log the incident depending on its success or failure. Finally, do_mount() is also patched to log failed mount attempts.

/*
 * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
 * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
 *
 * data is a (void *) that can point to any structure up to
 * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
 * information (or be NULL).
 *
 * Pre-0.97 versions of mount() didn't have a flags word.

 * When the flags word was introduced its top half was required
 * to have the magic value 0xC0ED, and this remained so until 2.4.0-test9.
 * Therefore, if this magic number is present, it carries no information
 * and must be discarded.
 */
long do_mount(char *dev_name, char *dir_name, char *type_page,
                  unsigned long flags, void *data_page)
{
        struct path path;
        int retval = 0;
        int mnt_flags = 0;
    ...
dput_out:
        path_put(&path);

        gr_log_mount(dev_name, dir_name, retval);

        return retval;
}

Written by xorl

November 18, 2010 at 08:16

Posted in grsecurity, linux, security

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s