Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff91fad2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6:
  eCryptfs: Larger buffer for encrypted symlink targets
  eCryptfs: Lock lower directory inode mutex during lookup
  eCryptfs: Remove ecryptfs_unlink_sigs warnings
  eCryptfs: Fix data corruption when using ecryptfs_passthrough
  eCryptfs: Print FNEK sig properly in /proc/mounts
  eCryptfs: NULL pointer dereference in ecryptfs_send_miscdev()
  eCryptfs: Copy lower inode attrs before dentry instantiation
parents 198aa045 3a6b42ca
Loading
Loading
Loading
Loading
+2 −19
Original line number Diff line number Diff line
@@ -483,15 +483,7 @@ int ecryptfs_encrypt_page(struct page *page)
	ecryptfs_inode = page->mapping->host;
	crypt_stat =
		&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
	if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
		rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, page,
						       0, PAGE_CACHE_SIZE);
		if (rc)
			printk(KERN_ERR "%s: Error attempting to copy "
			       "page at index [%ld]\n", __func__,
			       page->index);
		goto out;
	}
	BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));
	enc_extent_page = alloc_page(GFP_USER);
	if (!enc_extent_page) {
		rc = -ENOMEM;
@@ -620,16 +612,7 @@ int ecryptfs_decrypt_page(struct page *page)
	ecryptfs_inode = page->mapping->host;
	crypt_stat =
		&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
	if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
		rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
						      PAGE_CACHE_SIZE,
						      ecryptfs_inode);
		if (rc)
			printk(KERN_ERR "%s: Error attempting to copy "
			       "page at index [%ld]\n", __func__,
			       page->index);
		goto out;
	}
	BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));
	enc_extent_page = alloc_page(GFP_USER);
	if (!enc_extent_page) {
		rc = -ENOMEM;
+1 −0
Original line number Diff line number Diff line
@@ -269,6 +269,7 @@ struct ecryptfs_crypt_stat {
#define ECRYPTFS_ENCRYPT_FILENAMES    0x00000800
#define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000
#define ECRYPTFS_ENCFN_USE_FEK        0x00002000
#define ECRYPTFS_UNLINK_SIGS	      0x00004000
	u32 flags;
	unsigned int file_version;
	size_t iv_bytes;
+29 −8
Original line number Diff line number Diff line
@@ -379,9 +379,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
		goto out_d_drop;
	}
	lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent);
	mutex_lock(&lower_dir_dentry->d_inode->i_mutex);
	lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name,
				      lower_dir_dentry,
				      ecryptfs_dentry->d_name.len);
	mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
	if (IS_ERR(lower_dentry)) {
		rc = PTR_ERR(lower_dentry);
		printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
@@ -406,9 +408,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
		       "filename; rc = [%d]\n", __func__, rc);
		goto out_d_drop;
	}
	mutex_lock(&lower_dir_dentry->d_inode->i_mutex);
	lower_dentry = lookup_one_len(encrypted_and_encoded_name,
				      lower_dir_dentry,
				      encrypted_and_encoded_name_size - 1);
	mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
	if (IS_ERR(lower_dentry)) {
		rc = PTR_ERR(lower_dentry);
		printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
@@ -636,8 +640,9 @@ 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_crypt_stat *crypt_stat;
	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
	char *plaintext_name;
	size_t plaintext_name_size;
	mm_segment_t old_fs;
@@ -648,12 +653,21 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
		rc = -EINVAL;
		goto out;
	}
	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
	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(bufsiz, GFP_KERNEL);
	lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
	if (lower_buf == NULL) {
		printk(KERN_ERR "%s: Out of memory whilst attempting to "
		       "kmalloc [%d] bytes\n", __func__, bufsiz);
		       "kmalloc [%d] bytes\n", __func__, lower_bufsiz);
		rc = -ENOMEM;
		goto out;
	}
@@ -661,7 +675,7 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
	set_fs(get_ds());
	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						   (char __user *)lower_buf,
						   bufsiz);
						   lower_bufsiz);
	set_fs(old_fs);
	if (rc >= 0) {
		rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
@@ -674,7 +688,9 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
				rc);
			goto out_free_lower_buf;
		}
		rc = copy_to_user(buf, plaintext_name, plaintext_name_size);
		/* Check for bufsiz <= 0 done in sys_readlinkat() */
		rc = copy_to_user(buf, plaintext_name,
				  min((unsigned) bufsiz, plaintext_name_size));
		if (rc)
			rc = -EFAULT;
		else
@@ -814,6 +830,13 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
		size_t num_zeros = (PAGE_CACHE_SIZE
				    - (new_length & ~PAGE_CACHE_MASK));

		if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
			rc = vmtruncate(inode, new_length);
			if (rc)
				goto out_free;
			rc = vmtruncate(lower_dentry->d_inode, new_length);
			goto out_free;
		}
		if (num_zeros) {
			char *zeros_virt;

@@ -915,8 +938,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
			}
			rc = 0;
			crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
			mutex_unlock(&crypt_stat->cs_mutex);
			goto out;
		}
	}
	mutex_unlock(&crypt_stat->cs_mutex);
+9 −5
Original line number Diff line number Diff line
@@ -190,14 +190,14 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
		init_special_inode(inode, lower_inode->i_mode,
				   lower_inode->i_rdev);
	dentry->d_op = &ecryptfs_dops;
	if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD)
		d_add(dentry, inode);
	else
		d_instantiate(dentry, inode);
	fsstack_copy_attr_all(inode, lower_inode, NULL);
	/* This size will be overwritten for real files w/ headers and
	 * other metadata */
	fsstack_copy_inode_size(inode, lower_inode);
	if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD)
		d_add(dentry, inode);
	else
		d_instantiate(dentry, inode);
out:
	return rc;
}
@@ -208,7 +208,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig,
       ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata,
       ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig,
       ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes,
       ecryptfs_opt_err };
       ecryptfs_opt_unlink_sigs, ecryptfs_opt_err };

static const match_table_t tokens = {
	{ecryptfs_opt_sig, "sig=%s"},
@@ -222,6 +222,7 @@ static const match_table_t tokens = {
	{ecryptfs_opt_fnek_sig, "ecryptfs_fnek_sig=%s"},
	{ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"},
	{ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"},
	{ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"},
	{ecryptfs_opt_err, NULL}
};

@@ -402,6 +403,9 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
				fn_cipher_key_bytes;
			fn_cipher_key_bytes_set = 1;
			break;
		case ecryptfs_opt_unlink_sigs:
			mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS;
			break;
		case ecryptfs_opt_err:
		default:
			printk(KERN_WARNING
+0 −82
Original line number Diff line number Diff line
@@ -133,45 +133,6 @@ out:
	return rc;
}

static int
ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
			     struct ecryptfs_msg_ctx **msg_ctx);

/**
 * ecryptfs_send_raw_message
 * @msg_type: Message type
 * @daemon: Daemon struct for recipient of message
 *
 * A raw message is one that does not include an ecryptfs_message
 * struct. It simply has a type.
 *
 * Must be called with ecryptfs_daemon_hash_mux held.
 *
 * Returns zero on success; non-zero otherwise
 */
static int ecryptfs_send_raw_message(u8 msg_type,
				     struct ecryptfs_daemon *daemon)
{
	struct ecryptfs_msg_ctx *msg_ctx;
	int rc;

	rc = ecryptfs_send_message_locked(NULL, 0, msg_type, &msg_ctx);
	if (rc) {
		printk(KERN_ERR "%s: Error whilst attempting to send "
		       "message to ecryptfsd; rc = [%d]\n", __func__, rc);
		goto out;
	}
	/* Raw messages are logically context-free (e.g., no
	 * reply is expected), so we set the state of the
	 * ecryptfs_msg_ctx object to indicate that it should
	 * be freed as soon as the message is sent. */
	mutex_lock(&msg_ctx->mux);
	msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY;
	mutex_unlock(&msg_ctx->mux);
out:
	return rc;
}

/**
 * ecryptfs_spawn_daemon - Create and initialize a new daemon struct
 * @daemon: Pointer to set to newly allocated daemon struct
@@ -211,49 +172,6 @@ out:
	return rc;
}

/**
 * ecryptfs_process_helo
 * @euid: The user ID owner of the message
 * @user_ns: The namespace in which @euid applies
 * @pid: The process ID for the userspace program that sent the
 *       message
 *
 * Adds the euid and pid values to the daemon euid hash.  If an euid
 * already has a daemon pid registered, the daemon will be
 * unregistered before the new daemon is put into the hash list.
 * Returns zero after adding a new daemon to the hash list;
 * non-zero otherwise.
 */
int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns,
			  struct pid *pid)
{
	struct ecryptfs_daemon *new_daemon;
	struct ecryptfs_daemon *old_daemon;
	int rc;

	mutex_lock(&ecryptfs_daemon_hash_mux);
	rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid, user_ns);
	if (rc != 0) {
		printk(KERN_WARNING "Received request from user [%d] "
		       "to register daemon [0x%p]; unregistering daemon "
		       "[0x%p]\n", euid, pid, old_daemon->pid);
		rc = ecryptfs_send_raw_message(ECRYPTFS_MSG_QUIT, old_daemon);
		if (rc)
			printk(KERN_WARNING "Failed to send QUIT "
			       "message to daemon [0x%p]; rc = [%d]\n",
			       old_daemon->pid, rc);
		hlist_del(&old_daemon->euid_chain);
		kfree(old_daemon);
	}
	rc = ecryptfs_spawn_daemon(&new_daemon, euid, user_ns, pid);
	if (rc)
		printk(KERN_ERR "%s: The gods are displeased with this attempt "
		       "to create a new daemon object for euid [%d]; pid "
		       "[0x%p]; rc = [%d]\n", __func__, euid, pid, rc);
	mutex_unlock(&ecryptfs_daemon_hash_mux);
	return rc;
}

/**
 * ecryptfs_exorcise_daemon - Destroy the daemon struct
 *
Loading