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: Turn lower lookup error messages into debug messages eCryptfs: Copy lower directory inode times and size on link ecryptfs: fix use with tmpfs by removing d_drop from ecryptfs_destroy_inode ecryptfs: fix error code for missing xattrs in lower fs eCryptfs: Decrypt symlink target for stat size eCryptfs: Strip metadata in xattr flag in encrypted view eCryptfs: Clear buffer before reading in metadata xattr eCryptfs: Rename ecryptfs_crypt_stat.num_header_bytes_at_front eCryptfs: Fix metadata in xattr feature regression
This commit is contained in:
@@ -382,8 +382,8 @@ out:
|
|||||||
static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
|
static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
|
||||||
struct ecryptfs_crypt_stat *crypt_stat)
|
struct ecryptfs_crypt_stat *crypt_stat)
|
||||||
{
|
{
|
||||||
(*offset) = (crypt_stat->num_header_bytes_at_front
|
(*offset) = ecryptfs_lower_header_size(crypt_stat)
|
||||||
+ (crypt_stat->extent_size * extent_num));
|
+ (crypt_stat->extent_size * extent_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -835,13 +835,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
|
|||||||
set_extent_mask_and_shift(crypt_stat);
|
set_extent_mask_and_shift(crypt_stat);
|
||||||
crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
|
crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
|
||||||
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
||||||
crypt_stat->num_header_bytes_at_front = 0;
|
crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
|
||||||
else {
|
else {
|
||||||
if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
|
if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
|
||||||
crypt_stat->num_header_bytes_at_front =
|
crypt_stat->metadata_size =
|
||||||
ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
|
ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
|
||||||
else
|
else
|
||||||
crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE;
|
crypt_stat->metadata_size = PAGE_CACHE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1108,8 +1108,8 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written)
|
|||||||
(*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
|
(*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void ecryptfs_write_crypt_stat_flags(char *page_virt,
|
||||||
write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
|
struct ecryptfs_crypt_stat *crypt_stat,
|
||||||
size_t *written)
|
size_t *written)
|
||||||
{
|
{
|
||||||
u32 flags = 0;
|
u32 flags = 0;
|
||||||
@@ -1238,8 +1238,7 @@ ecryptfs_write_header_metadata(char *virt,
|
|||||||
|
|
||||||
header_extent_size = (u32)crypt_stat->extent_size;
|
header_extent_size = (u32)crypt_stat->extent_size;
|
||||||
num_header_extents_at_front =
|
num_header_extents_at_front =
|
||||||
(u16)(crypt_stat->num_header_bytes_at_front
|
(u16)(crypt_stat->metadata_size / crypt_stat->extent_size);
|
||||||
/ crypt_stat->extent_size);
|
|
||||||
put_unaligned_be32(header_extent_size, virt);
|
put_unaligned_be32(header_extent_size, virt);
|
||||||
virt += 4;
|
virt += 4;
|
||||||
put_unaligned_be16(num_header_extents_at_front, virt);
|
put_unaligned_be16(num_header_extents_at_front, virt);
|
||||||
@@ -1292,7 +1291,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
|
|||||||
offset = ECRYPTFS_FILE_SIZE_BYTES;
|
offset = ECRYPTFS_FILE_SIZE_BYTES;
|
||||||
write_ecryptfs_marker((page_virt + offset), &written);
|
write_ecryptfs_marker((page_virt + offset), &written);
|
||||||
offset += written;
|
offset += written;
|
||||||
write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
|
ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat,
|
||||||
|
&written);
|
||||||
offset += written;
|
offset += written;
|
||||||
ecryptfs_write_header_metadata((page_virt + offset), crypt_stat,
|
ecryptfs_write_header_metadata((page_virt + offset), crypt_stat,
|
||||||
&written);
|
&written);
|
||||||
@@ -1382,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
|
|||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
virt_len = crypt_stat->num_header_bytes_at_front;
|
virt_len = crypt_stat->metadata_size;
|
||||||
order = get_order(virt_len);
|
order = get_order(virt_len);
|
||||||
/* Released in this function */
|
/* Released in this function */
|
||||||
virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
|
virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
|
||||||
@@ -1428,16 +1428,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
|
|||||||
header_extent_size = get_unaligned_be32(virt);
|
header_extent_size = get_unaligned_be32(virt);
|
||||||
virt += sizeof(__be32);
|
virt += sizeof(__be32);
|
||||||
num_header_extents_at_front = get_unaligned_be16(virt);
|
num_header_extents_at_front = get_unaligned_be16(virt);
|
||||||
crypt_stat->num_header_bytes_at_front =
|
crypt_stat->metadata_size = (((size_t)num_header_extents_at_front
|
||||||
(((size_t)num_header_extents_at_front
|
|
||||||
* (size_t)header_extent_size));
|
* (size_t)header_extent_size));
|
||||||
(*bytes_read) = (sizeof(__be32) + sizeof(__be16));
|
(*bytes_read) = (sizeof(__be32) + sizeof(__be16));
|
||||||
if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
|
if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
|
||||||
&& (crypt_stat->num_header_bytes_at_front
|
&& (crypt_stat->metadata_size
|
||||||
< ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
|
< ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
printk(KERN_WARNING "Invalid header size: [%zd]\n",
|
printk(KERN_WARNING "Invalid header size: [%zd]\n",
|
||||||
crypt_stat->num_header_bytes_at_front);
|
crypt_stat->metadata_size);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1452,8 +1451,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
|
|||||||
*/
|
*/
|
||||||
static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
|
static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
|
||||||
{
|
{
|
||||||
crypt_stat->num_header_bytes_at_front =
|
crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
|
||||||
ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1607,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
|
|||||||
ecryptfs_dentry,
|
ecryptfs_dentry,
|
||||||
ECRYPTFS_VALIDATE_HEADER_SIZE);
|
ECRYPTFS_VALIDATE_HEADER_SIZE);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
memset(page_virt, 0, PAGE_CACHE_SIZE);
|
||||||
rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
|
rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_DEBUG "Valid eCryptfs headers not found in "
|
printk(KERN_DEBUG "Valid eCryptfs headers not found in "
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ struct ecryptfs_crypt_stat {
|
|||||||
u32 flags;
|
u32 flags;
|
||||||
unsigned int file_version;
|
unsigned int file_version;
|
||||||
size_t iv_bytes;
|
size_t iv_bytes;
|
||||||
size_t num_header_bytes_at_front;
|
size_t metadata_size;
|
||||||
size_t extent_size; /* Data extent size; default is 4096 */
|
size_t extent_size; /* Data extent size; default is 4096 */
|
||||||
size_t key_size;
|
size_t key_size;
|
||||||
size_t extent_shift;
|
size_t extent_shift;
|
||||||
@@ -464,6 +464,14 @@ struct ecryptfs_daemon {
|
|||||||
|
|
||||||
extern struct mutex ecryptfs_daemon_hash_mux;
|
extern struct mutex ecryptfs_daemon_hash_mux;
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
|
||||||
|
{
|
||||||
|
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
||||||
|
return 0;
|
||||||
|
return crypt_stat->metadata_size;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct ecryptfs_file_info *
|
static inline struct ecryptfs_file_info *
|
||||||
ecryptfs_file_to_private(struct file *file)
|
ecryptfs_file_to_private(struct file *file)
|
||||||
{
|
{
|
||||||
@@ -651,6 +659,9 @@ int ecryptfs_decrypt_page(struct page *page);
|
|||||||
int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
|
int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
|
||||||
int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
|
int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
|
||||||
int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
|
int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
|
||||||
|
void ecryptfs_write_crypt_stat_flags(char *page_virt,
|
||||||
|
struct ecryptfs_crypt_stat *crypt_stat,
|
||||||
|
size_t *written);
|
||||||
int ecryptfs_read_and_validate_header_region(char *data,
|
int ecryptfs_read_and_validate_header_region(char *data,
|
||||||
struct inode *ecryptfs_inode);
|
struct inode *ecryptfs_inode);
|
||||||
int ecryptfs_read_and_validate_xattr_region(char *page_virt,
|
int ecryptfs_read_and_validate_xattr_region(char *page_virt,
|
||||||
|
|||||||
@@ -324,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
|
|||||||
rc = ecryptfs_read_and_validate_header_region(page_virt,
|
rc = ecryptfs_read_and_validate_header_region(page_virt,
|
||||||
ecryptfs_dentry->d_inode);
|
ecryptfs_dentry->d_inode);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
memset(page_virt, 0, PAGE_CACHE_SIZE);
|
||||||
rc = ecryptfs_read_and_validate_xattr_region(page_virt,
|
rc = ecryptfs_read_and_validate_xattr_region(page_virt,
|
||||||
ecryptfs_dentry);
|
ecryptfs_dentry);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@@ -336,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
|
|||||||
ecryptfs_dentry->d_sb)->mount_crypt_stat;
|
ecryptfs_dentry->d_sb)->mount_crypt_stat;
|
||||||
if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
|
if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
|
||||||
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
||||||
file_size = (crypt_stat->num_header_bytes_at_front
|
file_size = (crypt_stat->metadata_size
|
||||||
+ i_size_read(lower_dentry->d_inode));
|
+ i_size_read(lower_dentry->d_inode));
|
||||||
else
|
else
|
||||||
file_size = i_size_read(lower_dentry->d_inode);
|
file_size = i_size_read(lower_dentry->d_inode);
|
||||||
@@ -388,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
|
|||||||
mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
|
mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
|
||||||
if (IS_ERR(lower_dentry)) {
|
if (IS_ERR(lower_dentry)) {
|
||||||
rc = PTR_ERR(lower_dentry);
|
rc = PTR_ERR(lower_dentry);
|
||||||
printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
|
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
|
||||||
"lower_dentry = [%s]\n", __func__, rc,
|
"[%d] on lower_dentry = [%s]\n", __func__, rc,
|
||||||
ecryptfs_dentry->d_name.name);
|
encrypted_and_encoded_name);
|
||||||
goto out_d_drop;
|
goto out_d_drop;
|
||||||
}
|
}
|
||||||
if (lower_dentry->d_inode)
|
if (lower_dentry->d_inode)
|
||||||
@@ -417,8 +418,8 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
|
|||||||
mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
|
mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
|
||||||
if (IS_ERR(lower_dentry)) {
|
if (IS_ERR(lower_dentry)) {
|
||||||
rc = PTR_ERR(lower_dentry);
|
rc = PTR_ERR(lower_dentry);
|
||||||
printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
|
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
|
||||||
"lower_dentry = [%s]\n", __func__, rc,
|
"[%d] on lower_dentry = [%s]\n", __func__, rc,
|
||||||
encrypted_and_encoded_name);
|
encrypted_and_encoded_name);
|
||||||
goto out_d_drop;
|
goto out_d_drop;
|
||||||
}
|
}
|
||||||
@@ -456,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
|
|||||||
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
|
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_lock;
|
goto out_lock;
|
||||||
fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
|
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
|
||||||
fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
|
fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
|
||||||
old_dentry->d_inode->i_nlink =
|
old_dentry->d_inode->i_nlink =
|
||||||
ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
|
ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
|
||||||
i_size_write(new_dentry->d_inode, file_size_save);
|
i_size_write(new_dentry->d_inode, file_size_save);
|
||||||
@@ -648,38 +649,17 @@ out_lock:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
|
||||||
ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
|
size_t *bufsiz)
|
||||||
{
|
{
|
||||||
|
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||||
char *lower_buf;
|
char *lower_buf;
|
||||||
size_t lower_bufsiz;
|
size_t lower_bufsiz = PATH_MAX;
|
||||||
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;
|
mm_segment_t old_fs;
|
||||||
int rc;
|
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);
|
lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
|
||||||
if (lower_buf == NULL) {
|
if (!lower_buf) {
|
||||||
printk(KERN_ERR "%s: Out of memory whilst attempting to "
|
|
||||||
"kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
|
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -689,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
|
|||||||
(char __user *)lower_buf,
|
(char __user *)lower_buf,
|
||||||
lower_bufsiz);
|
lower_bufsiz);
|
||||||
set_fs(old_fs);
|
set_fs(old_fs);
|
||||||
if (rc >= 0) {
|
if (rc < 0)
|
||||||
rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
|
goto out;
|
||||||
&plaintext_name_size,
|
lower_bufsiz = rc;
|
||||||
dentry, lower_buf,
|
rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
|
||||||
rc);
|
lower_buf, lower_bufsiz);
|
||||||
if (rc) {
|
out:
|
||||||
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);
|
kfree(lower_buf);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
|
||||||
|
{
|
||||||
|
char *kbuf;
|
||||||
|
size_t kbufsiz, copied;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
copied = min_t(size_t, bufsiz, kbufsiz);
|
||||||
|
rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
|
||||||
|
kfree(kbuf);
|
||||||
|
fsstack_copy_attr_atime(dentry->d_inode,
|
||||||
|
ecryptfs_dentry_to_lower(dentry)->d_inode);
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -769,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
|
|||||||
{
|
{
|
||||||
loff_t lower_size;
|
loff_t lower_size;
|
||||||
|
|
||||||
lower_size = crypt_stat->num_header_bytes_at_front;
|
lower_size = ecryptfs_lower_header_size(crypt_stat);
|
||||||
if (upper_size != 0) {
|
if (upper_size != 0) {
|
||||||
loff_t num_extents;
|
loff_t num_extents;
|
||||||
|
|
||||||
@@ -1016,6 +998,28 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
|
struct kstat *stat)
|
||||||
|
{
|
||||||
|
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
mount_crypt_stat = &ecryptfs_superblock_to_private(
|
||||||
|
dentry->d_sb)->mount_crypt_stat;
|
||||||
|
generic_fillattr(dentry->d_inode, stat);
|
||||||
|
if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
|
||||||
|
char *target;
|
||||||
|
size_t targetsiz;
|
||||||
|
|
||||||
|
rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz);
|
||||||
|
if (!rc) {
|
||||||
|
kfree(target);
|
||||||
|
stat->size = targetsiz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
struct kstat *stat)
|
struct kstat *stat)
|
||||||
{
|
{
|
||||||
@@ -1040,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
|||||||
|
|
||||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||||
if (!lower_dentry->d_inode->i_op->setxattr) {
|
if (!lower_dentry->d_inode->i_op->setxattr) {
|
||||||
rc = -ENOSYS;
|
rc = -EOPNOTSUPP;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
||||||
@@ -1058,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (!lower_dentry->d_inode->i_op->getxattr) {
|
if (!lower_dentry->d_inode->i_op->getxattr) {
|
||||||
rc = -ENOSYS;
|
rc = -EOPNOTSUPP;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
||||||
@@ -1085,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
|
|||||||
|
|
||||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||||
if (!lower_dentry->d_inode->i_op->listxattr) {
|
if (!lower_dentry->d_inode->i_op->listxattr) {
|
||||||
rc = -ENOSYS;
|
rc = -EOPNOTSUPP;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
||||||
@@ -1102,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
|
|||||||
|
|
||||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||||
if (!lower_dentry->d_inode->i_op->removexattr) {
|
if (!lower_dentry->d_inode->i_op->removexattr) {
|
||||||
rc = -ENOSYS;
|
rc = -EOPNOTSUPP;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
mutex_lock(&lower_dentry->d_inode->i_mutex);
|
||||||
@@ -1133,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = {
|
|||||||
.put_link = ecryptfs_put_link,
|
.put_link = ecryptfs_put_link,
|
||||||
.permission = ecryptfs_permission,
|
.permission = ecryptfs_permission,
|
||||||
.setattr = ecryptfs_setattr,
|
.setattr = ecryptfs_setattr,
|
||||||
|
.getattr = ecryptfs_getattr_link,
|
||||||
.setxattr = ecryptfs_setxattr,
|
.setxattr = ecryptfs_setxattr,
|
||||||
.getxattr = ecryptfs_getxattr,
|
.getxattr = ecryptfs_getxattr,
|
||||||
.listxattr = ecryptfs_listxattr,
|
.listxattr = ecryptfs_listxattr,
|
||||||
|
|||||||
@@ -83,6 +83,19 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void strip_xattr_flag(char *page_virt,
|
||||||
|
struct ecryptfs_crypt_stat *crypt_stat)
|
||||||
|
{
|
||||||
|
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
|
||||||
|
size_t written;
|
||||||
|
|
||||||
|
crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR;
|
||||||
|
ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat,
|
||||||
|
&written);
|
||||||
|
crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Header Extent:
|
* Header Extent:
|
||||||
* Octets 0-7: Unencrypted file size (big-endian)
|
* Octets 0-7: Unencrypted file size (big-endian)
|
||||||
@@ -98,19 +111,6 @@ out:
|
|||||||
* (big-endian)
|
* (big-endian)
|
||||||
* Octet 26: Begin RFC 2440 authentication token packet set
|
* Octet 26: Begin RFC 2440 authentication token packet set
|
||||||
*/
|
*/
|
||||||
static void set_header_info(char *page_virt,
|
|
||||||
struct ecryptfs_crypt_stat *crypt_stat)
|
|
||||||
{
|
|
||||||
size_t written;
|
|
||||||
size_t save_num_header_bytes_at_front =
|
|
||||||
crypt_stat->num_header_bytes_at_front;
|
|
||||||
|
|
||||||
crypt_stat->num_header_bytes_at_front =
|
|
||||||
ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
|
|
||||||
ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
|
|
||||||
crypt_stat->num_header_bytes_at_front =
|
|
||||||
save_num_header_bytes_at_front;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ecryptfs_copy_up_encrypted_with_header
|
* ecryptfs_copy_up_encrypted_with_header
|
||||||
@@ -136,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
|
|||||||
* num_extents_per_page)
|
* num_extents_per_page)
|
||||||
+ extent_num_in_page);
|
+ extent_num_in_page);
|
||||||
size_t num_header_extents_at_front =
|
size_t num_header_extents_at_front =
|
||||||
(crypt_stat->num_header_bytes_at_front
|
(crypt_stat->metadata_size / crypt_stat->extent_size);
|
||||||
/ crypt_stat->extent_size);
|
|
||||||
|
|
||||||
if (view_extent_num < num_header_extents_at_front) {
|
if (view_extent_num < num_header_extents_at_front) {
|
||||||
/* This is a header extent */
|
/* This is a header extent */
|
||||||
@@ -147,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
|
|||||||
memset(page_virt, 0, PAGE_CACHE_SIZE);
|
memset(page_virt, 0, PAGE_CACHE_SIZE);
|
||||||
/* TODO: Support more than one header extent */
|
/* TODO: Support more than one header extent */
|
||||||
if (view_extent_num == 0) {
|
if (view_extent_num == 0) {
|
||||||
|
size_t written;
|
||||||
|
|
||||||
rc = ecryptfs_read_xattr_region(
|
rc = ecryptfs_read_xattr_region(
|
||||||
page_virt, page->mapping->host);
|
page_virt, page->mapping->host);
|
||||||
set_header_info(page_virt, crypt_stat);
|
strip_xattr_flag(page_virt + 16, crypt_stat);
|
||||||
|
ecryptfs_write_header_metadata(page_virt + 20,
|
||||||
|
crypt_stat,
|
||||||
|
&written);
|
||||||
}
|
}
|
||||||
kunmap_atomic(page_virt, KM_USER0);
|
kunmap_atomic(page_virt, KM_USER0);
|
||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
@@ -162,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
|
|||||||
/* This is an encrypted data extent */
|
/* This is an encrypted data extent */
|
||||||
loff_t lower_offset =
|
loff_t lower_offset =
|
||||||
((view_extent_num * crypt_stat->extent_size)
|
((view_extent_num * crypt_stat->extent_size)
|
||||||
- crypt_stat->num_header_bytes_at_front);
|
- crypt_stat->metadata_size);
|
||||||
|
|
||||||
rc = ecryptfs_read_lower_page_segment(
|
rc = ecryptfs_read_lower_page_segment(
|
||||||
page, (lower_offset >> PAGE_CACHE_SHIFT),
|
page, (lower_offset >> PAGE_CACHE_SHIFT),
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode)
|
|||||||
if (lower_dentry->d_inode) {
|
if (lower_dentry->d_inode) {
|
||||||
fput(inode_info->lower_file);
|
fput(inode_info->lower_file);
|
||||||
inode_info->lower_file = NULL;
|
inode_info->lower_file = NULL;
|
||||||
d_drop(lower_dentry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
|
ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
|
||||||
|
|||||||
Reference in New Issue
Block a user