Commit ff91fad2 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6

* '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
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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
......
......@@ -133,45 +133,6 @@ int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid,
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 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid,
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
*
......
......@@ -193,7 +193,6 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
int rc = 0;
mutex_lock(&msg_ctx->mux);
if (data) {
msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size),
GFP_KERNEL);
if (!msg_ctx->msg) {
......@@ -203,16 +202,11 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
(sizeof(*msg_ctx->msg) + data_size));
goto out_unlock;
}
} else
msg_ctx->msg = NULL;
msg_ctx->msg->index = msg_ctx->index;
msg_ctx->msg->data_len = data_size;
msg_ctx->type = msg_type;
if (data) {
memcpy(msg_ctx->msg->data, data, data_size);
msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size);
} else
msg_ctx->msg_size = 0;
mutex_lock(&daemon->mux);
list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue);
daemon->num_queued_msg_ctx++;
......
......@@ -449,6 +449,7 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
struct ecryptfs_crypt_stat *crypt_stat;
crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
return ecryptfs_write_inode_size_to_xattr(ecryptfs_inode);
else
......@@ -490,6 +491,16 @@ static int ecryptfs_write_end(struct file *file,
ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
"(page w/ index = [0x%.16x], to = [%d])\n", index, to);
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, page, 0,
to);
if (!rc) {
rc = copied;
fsstack_copy_inode_size(ecryptfs_inode,
ecryptfs_inode_to_lower(ecryptfs_inode));
}
goto out;
}
/* Fills in zeros if 'to' goes beyond inode size */
rc = fill_zeros_to_end_of_page(page, to);
if (rc) {
......
......@@ -117,13 +117,15 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
size_t size)
{
struct page *ecryptfs_page;
struct ecryptfs_crypt_stat *crypt_stat;
struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode;
char *ecryptfs_page_virt;
loff_t ecryptfs_file_size =
i_size_read(ecryptfs_file->f_dentry->d_inode);
loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode);
loff_t data_offset = 0;
loff_t pos;
int rc = 0;
crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
/*
* if we are writing beyond current size, then start pos
* at the current size - we'll fill in zeros from there.
......@@ -184,7 +186,13 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
flush_dcache_page(ecryptfs_page);
SetPageUptodate(ecryptfs_page);
unlock_page(ecryptfs_page);
if (crypt_stat->flags & ECRYPTFS_ENCRYPTED)
rc = ecryptfs_encrypt_page(ecryptfs_page);
else
rc = ecryptfs_write_lower_page_segment(ecryptfs_inode,
ecryptfs_page,
start_offset_in_page,
data_offset);
page_cache_release(ecryptfs_page);
if (rc) {
printk(KERN_ERR "%s: Error encrypting "
......@@ -194,9 +202,10 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
pos += num_bytes;
}
if ((offset + size) > ecryptfs_file_size) {
i_size_write(ecryptfs_file->f_dentry->d_inode, (offset + size));
i_size_write(ecryptfs_inode, (offset + size));
if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
rc = ecryptfs_write_inode_size_to_metadata(
ecryptfs_file->f_dentry->d_inode);
ecryptfs_inode);
if (rc) {
printk(KERN_ERR "Problem with "
"ecryptfs_write_inode_size_to_metadata; "
......@@ -204,6 +213,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
goto out;
}
}
}
out:
return rc;
}
......
......@@ -170,6 +170,9 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
list_for_each_entry(walker,
&mount_crypt_stat->global_auth_tok_list,
mount_crypt_stat_list) {
if (walker->flags & ECRYPTFS_AUTH_TOK_FNEK)
seq_printf(m, ",ecryptfs_fnek_sig=%s", walker->sig);
else
seq_printf(m, ",ecryptfs_sig=%s", walker->sig);
}
mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
......@@ -186,6 +189,8 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
seq_printf(m, ",ecryptfs_xattr_metadata");
if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
seq_printf(m, ",ecryptfs_encrypted_view");
if (mount_crypt_stat->flags & ECRYPTFS_UNLINK_SIGS)
seq_printf(m, ",ecryptfs_unlink_sigs");
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment