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

Commit 46860666 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ecryptfs-3.3-rc4-fixes' of...

Merge tag 'ecryptfs-3.3-rc4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs

Fixes maximum filename length and filesystem type reporting in statfs() calls
and also fixes stale inode mode bits on eCryptfs inodes after a POSIX ACL was
set on the lower filesystem's inode.

* tag 'ecryptfs-3.3-rc4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs:
  ecryptfs: remove the second argument of k[un]map_atomic()
  eCryptfs: Copy up lower inode attrs after setting lower xattr
  eCryptfs: Improve statfs reporting
parents 7857b996 465c9343
Loading
Loading
Loading
Loading
+61 −7
Original line number Diff line number Diff line
@@ -1990,6 +1990,17 @@ out:
	return;
}

static size_t ecryptfs_max_decoded_size(size_t encoded_size)
{
	/* Not exact; conservatively long. Every block of 4
	 * encoded characters decodes into a block of 3
	 * decoded characters. This segment of code provides
	 * the caller with the maximum amount of allocated
	 * space that @dst will need to point to in a
	 * subsequent call. */
	return ((encoded_size + 1) * 3) / 4;
}

/**
 * ecryptfs_decode_from_filename
 * @dst: If NULL, this function only sets @dst_size and returns. If
@@ -2008,13 +2019,7 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size,
	size_t dst_byte_offset = 0;

	if (dst == NULL) {
		/* Not exact; conservatively long. Every block of 4
		 * encoded characters decodes into a block of 3
		 * decoded characters. This segment of code provides
		 * the caller with the maximum amount of allocated
		 * space that @dst will need to point to in a
		 * subsequent call. */
		(*dst_size) = (((src_size + 1) * 3) / 4);
		(*dst_size) = ecryptfs_max_decoded_size(src_size);
		goto out;
	}
	while (src_byte_offset < src_size) {
@@ -2239,3 +2244,52 @@ out_free:
out:
	return rc;
}

#define ENC_NAME_MAX_BLOCKLEN_8_OR_16	143

int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
			   struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{
	struct blkcipher_desc desc;
	struct mutex *tfm_mutex;
	size_t cipher_blocksize;
	int rc;

	if (!(mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) {
		(*namelen) = lower_namelen;
		return 0;
	}

	rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex,
			mount_crypt_stat->global_default_fn_cipher_name);
	if (unlikely(rc)) {
		(*namelen) = 0;
		return rc;
	}

	mutex_lock(tfm_mutex);
	cipher_blocksize = crypto_blkcipher_blocksize(desc.tfm);
	mutex_unlock(tfm_mutex);

	/* Return an exact amount for the common cases */
	if (lower_namelen == NAME_MAX
	    && (cipher_blocksize == 8 || cipher_blocksize == 16)) {
		(*namelen) = ENC_NAME_MAX_BLOCKLEN_8_OR_16;
		return 0;
	}

	/* Return a safe estimate for the uncommon cases */
	(*namelen) = lower_namelen;
	(*namelen) -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
	/* Since this is the max decoded size, subtract 1 "decoded block" len */
	(*namelen) = ecryptfs_max_decoded_size(*namelen) - 3;
	(*namelen) -= ECRYPTFS_TAG_70_MAX_METADATA_SIZE;
	(*namelen) -= ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES;
	/* Worst case is that the filename is padded nearly a full block size */
	(*namelen) -= cipher_blocksize - 1;

	if ((*namelen) < 0)
		(*namelen) = 0;

	return 0;
}
+6 −0
Original line number Diff line number Diff line
@@ -162,6 +162,10 @@ ecryptfs_get_key_payload_data(struct key *key)
#define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */
#define MD5_DIGEST_SIZE 16
#define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE
#define ECRYPTFS_TAG_70_MIN_METADATA_SIZE (1 + ECRYPTFS_MIN_PKT_LEN_SIZE \
					   + ECRYPTFS_SIG_SIZE + 1 + 1)
#define ECRYPTFS_TAG_70_MAX_METADATA_SIZE (1 + ECRYPTFS_MAX_PKT_LEN_SIZE \
					   + ECRYPTFS_SIG_SIZE + 1 + 1)
#define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FEK_ENCRYPTED."
#define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE 23
#define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FNEK_ENCRYPTED."
@@ -701,6 +705,8 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
			     size_t *packet_size,
			     struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
			     char *data, size_t max_packet_size);
int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
			   struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
		       loff_t offset);

+2 −0
Original line number Diff line number Diff line
@@ -1085,6 +1085,8 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
	}

	rc = vfs_setxattr(lower_dentry, name, value, size, flags);
	if (!rc)
		fsstack_copy_attr_all(dentry->d_inode, lower_dentry->d_inode);
out:
	return rc;
}
+3 −6
Original line number Diff line number Diff line
@@ -679,10 +679,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
	 * Octets N3-N4: Block-aligned encrypted filename
	 *  - Consists of a minimum number of random characters, a \0
	 *    separator, and then the filename */
	s->max_packet_size = (1                   /* Tag 70 identifier */
			      + 3                 /* Max Tag 70 packet size */
			      + ECRYPTFS_SIG_SIZE /* FNEK sig */
			      + 1                 /* Cipher identifier */
	s->max_packet_size = (ECRYPTFS_TAG_70_MAX_METADATA_SIZE
			      + s->block_aligned_filename_size);
	if (dest == NULL) {
		(*packet_size) = s->max_packet_size;
@@ -934,10 +931,10 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
		goto out;
	}
	s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
	if (max_packet_size < (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)) {
	if (max_packet_size < ECRYPTFS_TAG_70_MIN_METADATA_SIZE) {
		printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be "
		       "at least [%d]\n", __func__, max_packet_size,
			(1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1));
		       ECRYPTFS_TAG_70_MIN_METADATA_SIZE);
		rc = -EINVAL;
		goto out;
	}
+2 −2
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
			/* This is a header extent */
			char *page_virt;

			page_virt = kmap_atomic(page, KM_USER0);
			page_virt = kmap_atomic(page);
			memset(page_virt, 0, PAGE_CACHE_SIZE);
			/* TODO: Support more than one header extent */
			if (view_extent_num == 0) {
@@ -163,7 +163,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
							       crypt_stat,
							       &written);
			}
			kunmap_atomic(page_virt, KM_USER0);
			kunmap_atomic(page_virt);
			flush_dcache_page(page);
			if (rc) {
				printk(KERN_ERR "%s: Error reading xattr "
Loading