Пример #1
0
/*
 * The inode of symbolic link is different to data stream.
 * The data stream become link name. Unless the LONG_SYMLINK
 * flag is set.
 */
static void *
befs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	struct super_block *sb = dentry->d_sb;
	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
	befs_data_stream *data = &befs_ino->i_data.ds;
	befs_off_t len = data->size;
	char *link;

	if (len == 0) {
		befs_error(sb, "Long symlink with illegal length");
		link = ERR_PTR(-EIO);
	} else {
		befs_debug(sb, "Follow long symlink");

		link = kmalloc(len, GFP_NOFS);
		if (!link) {
			link = ERR_PTR(-ENOMEM);
		} else if (befs_read_lsymlink(sb, data, link, len) != len) {
			kfree(link);
			befs_error(sb, "Failed to read entire long symlink");
			link = ERR_PTR(-EIO);
		} else {
			link[len - 1] = '\0';
		}
	}
	nd_set_link(nd, link);
	return NULL;
}
static void *
CVE_2011_2928_linux2_6_23_befs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
	char *link;

	if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
		struct super_block *sb = dentry->d_sb;
		befs_data_stream *data = &befs_ino->i_data.ds;
		befs_off_t len = data->size;

		befs_debug(sb, "Follow long symlink");

		link = kmalloc(len, GFP_NOFS);
		if (!link) {
			link = ERR_PTR(-ENOMEM);
		} else if (befs_read_lsymlink(sb, data, link, len) != len) {
			kfree(link);
			befs_error(sb, "Failed to read entire long symlink");
			link = ERR_PTR(-EIO);
		}
	} else {
		link = befs_ino->i_data.symlink;
	}

	nd_set_link(nd, link);
	return NULL;
}
Пример #3
0
/*
 * The inode of symbolic link is different to data stream.
 * The data stream become link name. Unless the LONG_SYMLINK
 * flag is set.
 */
static int befs_symlink_readpage(struct file *unused, struct page *page)
{
	struct inode *inode = page->mapping->host;
	struct super_block *sb = inode->i_sb;
	struct befs_inode_info *befs_ino = BEFS_I(inode);
	befs_data_stream *data = &befs_ino->i_data.ds;
	befs_off_t len = data->size;
	char *link = page_address(page);

	if (len == 0 || len > PAGE_SIZE) {
		befs_error(sb, "Long symlink with illegal length");
		goto fail;
	}
	befs_debug(sb, "Follow long symlink");

	if (befs_read_lsymlink(sb, data, link, len) != len) {
		befs_error(sb, "Failed to read entire long symlink");
		goto fail;
	}
	link[len - 1] = '\0';
	SetPageUptodate(page);
	unlock_page(page);
	return 0;
fail:
	SetPageError(page);
	unlock_page(page);
	return -EIO;
}
Пример #4
0
static int
befs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{
	struct super_block *sb = dentry->d_sb;
	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
	char *link;
	int res;

	if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
		befs_data_stream *data = &befs_ino->i_data.ds;
		befs_off_t linklen = data->size;

		befs_debug(sb, "Read long symlink");

		link = kmalloc(linklen, GFP_NOFS);
		if (link == NULL)
			return -ENOMEM;

		if (befs_read_lsymlink(sb, data, link, linklen) != linklen) {
			kfree(link);
			befs_error(sb, "Failed to read entire long symlink");
			return -EIO;
		}

		res = vfs_readlink(dentry, buffer, buflen, link);

		kfree(link);
	} else {
		link = befs_ino->i_data.symlink;
		res = vfs_readlink(dentry, buffer, buflen, link);
	}

	return res;
}