Пример #1
0
/* Inspired by generic filldir in fs/readdir.c */
static int
ecryptfs_filldir(void *dirent, const char *lower_name, int lower_namelen,
		 loff_t offset, u64 ino, unsigned int d_type)
{
	struct ecryptfs_getdents_callback *buf =
	    (struct ecryptfs_getdents_callback *)dirent;
	size_t name_size;
	char *name;
	int rc;

	buf->filldir_called++;
	rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
						  buf->dentry, lower_name,
						  lower_namelen);
	if (rc) {
		printk(KERN_ERR "%s: Error attempting to decode and decrypt "
		       "filename [%s]; rc = [%d]\n", __func__, lower_name,
		       rc);
		goto out;
	}
	rc = buf->filldir(buf->dirent, name, name_size, offset, ino, d_type);
	kfree(name);
	if (rc >= 0)
		buf->entries_written++;
out:
	return rc;
}
Пример #2
0
static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
				   size_t *bufsiz)
{
	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
	char *lower_buf;
	size_t lower_bufsiz = PATH_MAX;
	mm_segment_t old_fs;
	int rc;

	lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
	if (!lower_buf) {
		rc = -ENOMEM;
		goto out;
	}
	old_fs = get_fs();
	set_fs(get_ds());
	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						   (char __user *)lower_buf,
						   lower_bufsiz);
	set_fs(old_fs);
	if (rc < 0)
		goto out;
	lower_bufsiz = rc;
	rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
						  lower_buf, lower_bufsiz);
out:
	kfree(lower_buf);
	return rc;
}
Пример #3
0
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
{
	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
	char *lower_buf;
	char *buf;
	mm_segment_t old_fs;
	int rc;

	lower_buf = kmalloc(PATH_MAX, GFP_KERNEL);
	if (!lower_buf)
		return ERR_PTR(-ENOMEM);
	old_fs = get_fs();
	set_fs(get_ds());
	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						   (char __user *)lower_buf,
						   PATH_MAX);
	set_fs(old_fs);
	if (rc < 0)
		goto out;
	rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
						  lower_buf, rc);
out:
	kfree(lower_buf);
	return rc ? ERR_PTR(rc) : buf;
}
Пример #4
0
static int
ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{
	char *lower_buf;
	struct dentry *lower_dentry;
	struct ecryptfs_crypt_stat *crypt_stat;
	char *plaintext_name;
	size_t plaintext_name_size;
	mm_segment_t old_fs;
	int rc;

	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	if (!lower_dentry->d_inode->i_op->readlink) {
		rc = -EINVAL;
		goto out;
	}
	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
	/* Released in this function */
	lower_buf = kmalloc(bufsiz, GFP_KERNEL);
	if (lower_buf == NULL) {
		printk(KERN_ERR "%s: Out of memory whilst attempting to "
		       "kmalloc [%d] bytes\n", __func__, bufsiz);
		rc = -ENOMEM;
		goto out;
	}
	old_fs = get_fs();
	set_fs(get_ds());
	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						   (char __user *)lower_buf,
						   bufsiz);
	set_fs(old_fs);
	if (rc >= 0) {
		rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
							  &plaintext_name_size,
							  dentry, lower_buf,
							  rc);
		if (rc) {
			printk(KERN_ERR "%s: Error attempting to decode and "
			       "decrypt filename; rc = [%d]\n", __func__,
				rc);
			goto out_free_lower_buf;
		}
		rc = copy_to_user(buf, plaintext_name, plaintext_name_size);
		if (rc)
			rc = -EFAULT;
		else
			rc = plaintext_name_size;
		kfree(plaintext_name);
		fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
	}
out_free_lower_buf:
	kfree(lower_buf);
out:
	return rc;
}
Пример #5
0
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
{
	DEFINE_DELAYED_CALL(done);
	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
	const char *link;
	char *buf;
	int rc;

	link = vfs_get_link(lower_dentry, &done);
	if (IS_ERR(link))
		return ERR_CAST(link);

	rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
						  link, strlen(link));
	do_delayed_call(&done);
	if (rc)
		return ERR_PTR(rc);

	return buf;
}
Пример #6
0
static int
ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{
	char *lower_buf;
	size_t lower_bufsiz;
	struct dentry *lower_dentry;
	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
	char *plaintext_name;
	size_t plaintext_name_size;
	mm_segment_t old_fs;
	int rc;

	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	if (!lower_dentry->d_inode->i_op->readlink) {
		rc = -EINVAL;
		goto out;
	}
	mount_crypt_stat = &ecryptfs_superblock_to_private(
						dentry->d_sb)->mount_crypt_stat;
	/*
	 * If the lower filename is encrypted, it will result in a significantly
	 * longer name.  If needed, truncate the name after decode and decrypt.
	 */
	if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
		lower_bufsiz = PATH_MAX;
	else
		lower_bufsiz = bufsiz;
	/* Released in this function */
	lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
	if (lower_buf == NULL) {
		printk(KERN_ERR "%s: Out of memory whilst attempting to "
		       "kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
		rc = -ENOMEM;
		goto out;
	}
	old_fs = get_fs();
	set_fs(get_ds());
	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						   (char __user *)lower_buf,
						   lower_bufsiz);
	set_fs(old_fs);
	if (rc >= 0) {
		rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
							  &plaintext_name_size,
							  dentry, lower_buf,
							  rc);
		if (rc) {
			printk(KERN_ERR "%s: Error attempting to decode and "
			       "decrypt filename; rc = [%d]\n", __func__,
				rc);
			goto out_free_lower_buf;
		}
		/* Check for bufsiz <= 0 done in sys_readlinkat() */
		rc = copy_to_user(buf, plaintext_name,
				  min((size_t) bufsiz, plaintext_name_size));
		if (rc)
			rc = -EFAULT;
		else
			rc = plaintext_name_size;
		kfree(plaintext_name);
		fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
	}
out_free_lower_buf:
	kfree(lower_buf);
out:
	return rc;
}