xorl %eax, %eax

GRKERNSEC_FIFO Named Pipe Restrictions

leave a comment »

As its name implies this is designed to do the following:

config GRKERNSEC_FIFO
	bool "FIFO restrictions"
	help
	  If you say Y here, users will not be able to write to FIFOs they don't
	  own in world-writable +t directories (i.e. /tmp), unless the owner of
	  the FIFO is the same owner of the directory it's held in.  If the sysctl
	  option is enabled, a sysctl option with name "fifo_restrictions" is
	  created.

It’s a simple code that is implemented in a single file which is the grsecurity/grsec_fifo.c and it is shown below.

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/grinternal.h>

int
gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
	       const struct dentry *dir, const int flag, const int acc_mode)
{
#ifdef CONFIG_GRKERNSEC_FIFO
	const struct cred *cred = current_cred();

	if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
	    !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
	    (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
	    (cred->fsuid != dentry->d_inode->i_uid)) {
		if (!generic_permission(dentry->d_inode, acc_mode, NULL))
			gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
		return -EACCES;
	}
#endif
	return 0;
}

This function always returns ‘-EACCES’ (Access Denied). The first one will be true if all of the following conditions are met:
– ‘grsec_enable_fifo’ is non-zero
– It’s dealing with a FIFO (aka a named pipe)
– It doesn’t have ‘O_EXCL’ flag set
– Directory has sticky bit ‘S_ISVTX’
– Both source and destination have the same UIDs
– User’s file UID isn’t different than the FIFO’s one
Assuming that the above conditions were met, it will enter a second ‘if’ clause that just calls generic_permission(). This is a routine of fs/namei.c that checks for access writes on POSIX-like filesystems. If the request returns with no error, meaning that the user has the access mode to manipulate that FIFO, it will log the event using gr_log_fs_int2(). Otherwise, it will simply return ‘-EACCES’ (Access Denied) error code.
Back to the Linux kernel’s code, we can find this function being used at do_last() which is a function also located at fs/namei.c.

static struct file *do_last(struct nameidata *nd, struct path *path,
                            int open_flag, int acc_mode,
                            int mode, const char *pathname)
{
        struct dentry *dir = nd->path.dentry;
        struct file *filp;
        int error = -EISDIR;

    ...
        /*
         * It already exists.
         */
    ...
	if (gr_handle_fifo(path->dentry, nd->path.mnt, dir, flag, acc_mode)) {
		error = -EACCES;
		goto exit_mutex_unlock;
	}

        mutex_unlock(&dir->d_inode->i_mutex);
        audit_inode(pathname, path->dentry);
    ...
exit:
        if (!IS_ERR(nd->intent.open.file))
                release_open_intent(nd);
        path_put(&nd->path);
        return ERR_PTR(error);
}

Written by xorl

November 24, 2010 at 09:29

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