Пример #1
0
static int wrapfs_open(struct inode *inode, struct file *file)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct path lower_path;

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_MESG("Enter");
#endif

	/* don't open unhashed/deleted files */
	if (d_unhashed(file->f_path.dentry)) {
		err = -ENOENT;
		goto out_err;
	}

	file->private_data = kzalloc(sizeof(struct wrapfs_file_info), GFP_KERNEL);
	if (!WRAPFS_F(file)) {
		err = -ENOMEM;
		goto out_err;
	}

	/* open lower object and link wrapfs's file struct to lower's */
	wrapfs_get_lower_path(file->f_path.dentry, &lower_path);
	lower_file = dentry_open(lower_path.dentry, lower_path.mnt,
				 file->f_flags, current_cred());
	if (IS_ERR(lower_file)) {
		err = PTR_ERR(lower_file);
		lower_file = wrapfs_lower_file(file);
		if (lower_file) {
			wrapfs_set_lower_file(file, NULL);
			fput(lower_file); /* fput calls dput for lower_dentry */
		}
	} else {
		wrapfs_set_lower_file(file, lower_file);
	}

	if (err)
		kfree(WRAPFS_F(file));
	else
		fsstack_copy_attr_all(inode, wrapfs_lower_inode(inode));
out_err:

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_RETURN("Exit", err);
#endif

	return err;
}
Пример #2
0
/* release all lower object references & free the file info structure */
static int wrapfs_file_release(struct inode *inode, struct file *file)
{
	struct file *lower_file;
#ifdef EXTRA_CREDIT
	int CHKSUM_SIZE =0;
	char *algo = kmalloc(sizeof(char)*10,GFP_KERNEL);
	int *algo_len = kmalloc(sizeof(int)*1,GFP_KERNEL);
	char *getchkbuf = kmalloc(sizeof(char)*32,GFP_KERNEL);
#else
	char *getchkbuf = kmalloc(sizeof(char)*CHKSUM_SIZE,GFP_KERNEL);
#endif
	char *has_integrity = kmalloc(sizeof(char)*1,GFP_KERNEL);
	int rc;

	lower_file = wrapfs_lower_file(file);
	if (lower_file) {

		if(lower_file->f_mode == O_RDONLY)
			goto out_release;

		else if(!S_ISDIR(lower_file->f_path.dentry->d_inode->i_mode)&& wrapfs_get_write_dirty(inode) == WRITE_DIRTY_BIT)
		{
#ifdef EXTRA_CREDIT
			CHKSUM_SIZE = get_default_chksum_size(lower_file->f_path.dentry,algo,algo_len);
#endif
			if(!has_integrity || !getchkbuf)
			{
				rc = -ENOMEM;
				goto out_release;
			}
			
			spin_lock(&inode->i_lock);
			wrapfs_set_write_dirty(inode,READ_DIRTY_BIT);
			spin_unlock(&inode->i_lock);

			if(vfs_getxattr(lower_file->f_path.dentry,XATTR_HAS_INTEGRITY,has_integrity,1)>0)
			{
				if(!memcmp(has_integrity,"1",1))
				{
					calculate_checksum(lower_file,getchkbuf,CHKSUM_SIZE);
					rc = vfs_setxattr(lower_file->f_path.dentry,XATTR_INTEGRITY_VAL,getchkbuf,CHKSUM_SIZE,XATTR_CREATE);
					if(rc == -EEXIST)
						rc = vfs_setxattr(lower_file->f_path.dentry,XATTR_INTEGRITY_VAL,getchkbuf,CHKSUM_SIZE,XATTR_REPLACE);
				}
			}
		}
out_release:
		wrapfs_set_lower_file(file, NULL);
		fput(lower_file);
	}

	kfree(WRAPFS_F(file));
	kfree(getchkbuf);
	kfree(has_integrity);
#ifdef EXTRA_CREDIT
	kfree(algo);
	kfree(algo_len);
#endif
	return 0;
}
Пример #3
0
static int __open_file(struct inode *inode, struct file *file,
			struct dentry *parent)
{
	struct dentry *lower_dentry;
	struct file *lower_file;
	struct vfsmount *lower_mnt;
	struct dentry *dentry  = file->f_path.dentry;
	int lower_flags;
	int i = 0, idx = 0;
	for (i = 0; i <= 1; i++) {
		lower_dentry = wrapfs_lower_dentry_idx(dentry, i);
		if (!lower_dentry  || !lower_dentry->d_inode)
			continue;
		lower_flags = file->f_flags;

		if (lower_dentry->d_inode && (i == 1)) {
			UDBG;
			if (lower_flags & O_TRUNC) {
				int size = 0;
				int err = -EROFS;
				UDBG;

				err = copyup_file(parent->d_inode, file,
						  i, 0, size);
				if (!err)
					break;
				return err;
			} else
				lower_flags &= ~(OPEN_WRITE_FLAGS);
		}
		dget(lower_dentry);
		lower_mnt = mntget(wrapfs_lower_mnt_idx(dentry, i));

		if (!lower_mnt)
			lower_mnt = mntget(wrapfs_lower_mnt_idx(parent, i));

		lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags,
					current_cred());

		if (IS_ERR(lower_file))
			return PTR_ERR(lower_file);

		wrapfs_set_lower_file(file, lower_file);
		branchget(inode->i_sb, i);
		idx = i;
		goto out;
	}
out:
	if (!wrapfs_lower_inode_idx(inode, idx))
		fsstack_copy_attr_all(inode,
			wrapfs_lower_inode_idx(inode, idx));
	return 0;
}
Пример #4
0
/* release all lower object references & free the file info structure */
static int wrapfs_file_release(struct inode *inode, struct file *file)
{
	struct file *lower_file;

	lower_file = wrapfs_lower_file(file);
	if (lower_file) {
		wrapfs_set_lower_file(file, NULL);
		fput(lower_file);
	}

	kfree(WRAPFS_F(file));
	return 0;
}
Пример #5
0
/* release all lower object references & free the file info structure */
static int wrapfs_file_release(struct inode *inode, struct file *file)
{
	struct file *lower_file;

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_MESG("Enter");
#endif

	lower_file = wrapfs_lower_file(file);
	if (lower_file) {
		wrapfs_set_lower_file(file, NULL);
		fput(lower_file);
	}

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_MESG("Exit");
#endif 

	kfree(WRAPFS_F(file));
	return 0;
}
Пример #6
0
static int wrapfs_open(struct inode *inode, struct file *file)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct path lower_path;
#ifdef EXTRA_CREDIT
	int CHKSUM_SIZE =0;
	char *algo = kmalloc(sizeof(char)*10,GFP_KERNEL);
	int *algo_len = kmalloc(sizeof(char)*1,GFP_KERNEL);
	char *chkbuf = kmalloc(sizeof(char)*32,GFP_KERNEL);
	char *getchkbuf = kmalloc(sizeof(char)*32,GFP_KERNEL);
#else	
	char *chkbuf = kmalloc(sizeof(char)*CHKSUM_SIZE,GFP_KERNEL);
	char *getchkbuf = kmalloc(sizeof(char)*CHKSUM_SIZE,GFP_KERNEL);
#endif
	char *has_integrity = kmalloc(sizeof(char)*1,GFP_KERNEL);
	int rc = 0;

	if(!chkbuf || !has_integrity || !getchkbuf)
	{
		err = -ENOMEM;
		goto out_err;
	}
	/* don't open unhashed/deleted files */
	if (d_unhashed(file->f_path.dentry)) {
		err = -ENOENT;
		goto out_err;
	}

	file->private_data =
		kzalloc(sizeof(struct wrapfs_file_info), GFP_KERNEL);
	if (!WRAPFS_F(file)) {
		err = -ENOMEM;
		goto out_err;
	}

	/* open lower object and link wrapfs's file struct to lower's */
	wrapfs_get_lower_path(file->f_path.dentry, &lower_path);
	lower_file = dentry_open(lower_path.dentry, lower_path.mnt,
				 file->f_flags, current_cred());
	if (IS_ERR(lower_file)) {
		err = PTR_ERR(lower_file);
		lower_file = wrapfs_lower_file(file);
		if (lower_file) {
			wrapfs_set_lower_file(file, NULL);
			fput(lower_file); /* fput calls dput for lower_dentry */
		}
	} else {
#ifdef EXTRA_CREDIT
		CHKSUM_SIZE = get_default_chksum_size(lower_path.dentry,algo,algo_len);
#endif
		rc = vfs_getxattr(lower_path.dentry,XATTR_HAS_INTEGRITY,has_integrity,1);
		if(rc > 0 && !S_ISDIR(lower_path.dentry->d_inode->i_mode))
		{
			wrapfs_set_lower_file(file,lower_file);

			if(lower_file->f_mode == O_TRUNC)
				wrapfs_set_write_dirty(inode,WRITE_DIRTY_BIT);
			
			if(!memcmp(has_integrity,"1",1) && wrapfs_get_write_dirty(inode)!=WRITE_DIRTY_BIT && rc ==1)
			{	
				if(vfs_getxattr(lower_path.dentry,XATTR_INTEGRITY_VAL,chkbuf,CHKSUM_SIZE)>0)
				{
					//mutex_lock(&lower_path.dentry->d_inode->i_mutex);
					calculate_checksum(lower_file,getchkbuf,CHKSUM_SIZE);
					if(memcmp(chkbuf,getchkbuf,CHKSUM_SIZE))
					{
						printk("Integrity mismatch\n");
						err = -EPERM;
						wrapfs_set_lower_file(file,NULL);
						fput(lower_file);
					}
					//mutex_unlock(&lower_path.dentry->d_inode->i_mutex);							
				}
			}
			else if(!memcmp(has_integrity,"0",1) && rc ==1)
			{
				if(vfs_getxattr(lower_path.dentry,XATTR_INTEGRITY_VAL,chkbuf,CHKSUM_SIZE)>0)
				{
					err = -EIO;
					wrapfs_set_lower_file(file,NULL);
					fput(lower_file);
				}
				else
					wrapfs_set_lower_file(file,lower_file);
			}
			else
			{
				printk("File corrupted.Unexpected value for has_integrity attribute\n");
				err = -EPERM;
				wrapfs_set_lower_file(file,NULL);
				fput(lower_file);
			}
		}
		else if(vfs_getxattr(lower_path.dentry,XATTR_HAS_INTEGRITY,has_integrity,1)<=0 && vfs_getxattr(lower_path.dentry,XATTR_INTEGRITY_VAL,chkbuf,CHKSUM_SIZE)>0)
		{
			err = -EIO;
			wrapfs_set_lower_file(file,NULL);
			fput(lower_file);
		}			
		else
		{
			wrapfs_set_lower_file(file, lower_file);
		}
	}

	if (err)
		kfree(WRAPFS_F(file));
	else
		fsstack_copy_attr_all(inode, wrapfs_lower_inode(inode));
out_err:
	kfree(chkbuf);
	kfree(getchkbuf);
	kfree(has_integrity);
#ifdef EXTRA_CREDIT
	kfree(algo);
	kfree(algo_len);
#endif
	return err;
}