summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2012-08-03 12:48:49 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-08-03 12:48:49 -0400
commitd40ec4e609bd24cfa2a1f2251dfda9dec7df8470 (patch)
treeb41335e3d5655dc1025a066d07aa677109083202
parent9860579d0e2236325ff8aa02bebddb967bcfb8a6 (diff)
downloadlongterm-queue-2.6.34-d40ec4e609bd24cfa2a1f2251dfda9dec7df8470.tar.gz
add ecryptfs patches
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--queue/eCryptfs-Improve-statfs-reporting.patch207
-rw-r--r--queue/ecryptfs-use-lower-filesystem-stat-if-it-exists.patch55
-rw-r--r--queue/series3
3 files changed, 265 insertions, 0 deletions
diff --git a/queue/eCryptfs-Improve-statfs-reporting.patch b/queue/eCryptfs-Improve-statfs-reporting.patch
new file mode 100644
index 0000000..e24ef5a
--- /dev/null
+++ b/queue/eCryptfs-Improve-statfs-reporting.patch
@@ -0,0 +1,207 @@
+From 535b97b1e42ab3d857e8bff248c4f196599fb70b Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Sat, 5 Nov 2011 13:45:08 -0400
+Subject: [PATCH] eCryptfs: Improve statfs reporting
+
+commit 4a26620df451ad46151ad21d711ed43e963c004e upstream.
+
+statfs() calls on eCryptfs files returned the wrong filesystem type and,
+when using filename encryption, the wrong maximum filename length.
+
+If mount-wide filename encryption is enabled, the cipher block size and
+the lower filesystem's max filename length will determine the max
+eCryptfs filename length. Pre-tested, known good lengths are used when
+the lower filesystem's namelen is 255 and a cipher with 8 or 16 byte
+block sizes is used. In other, less common cases, we fall back to a safe
+rounded-down estimate when determining the eCryptfs namelen.
+
+https://launchpad.net/bugs/885744
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Reported-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: John Johansen <john.johansen@canonical.com>
+[PG: trivial tweak since .34 doesn't define ECRYPTFS_MIN/MAX_PKT_LEN_SIZE]
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+
+diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
+index 1cc0876..414e5ad 100644
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -2015,6 +2015,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
+@@ -2033,13 +2044,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) {
+@@ -2265,3 +2270,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;
++}
+diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
+index bfc2e0f..87e8fb5 100644
+--- a/fs/ecryptfs/ecryptfs_kernel.h
++++ b/fs/ecryptfs/ecryptfs_kernel.h
+@@ -226,6 +226,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 + 1 /* MIN_PKT_LEN_SIZE */ \
++ + ECRYPTFS_SIG_SIZE + 1 + 1)
++#define ECRYPTFS_TAG_70_MAX_METADATA_SIZE (1 + 2 /* 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."
+@@ -773,6 +777,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);
+
+diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
+index 07f23c5..164349b 100644
+--- a/fs/ecryptfs/keystore.c
++++ b/fs/ecryptfs/keystore.c
+@@ -549,10 +549,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;
+@@ -807,10 +804,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;
+ }
+diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
+index 8a789db..93ee8a6 100644
+--- a/fs/ecryptfs/super.c
++++ b/fs/ecryptfs/super.c
+@@ -31,6 +31,8 @@
+ #include <linux/smp_lock.h>
+ #include <linux/file.h>
+ #include <linux/crypto.h>
++#include <linux/statfs.h>
++#include <linux/magic.h>
+ #include "ecryptfs_kernel.h"
+
+ struct kmem_cache *ecryptfs_inode_info_cache;
+@@ -140,10 +142,20 @@ static void ecryptfs_put_super(struct super_block *sb)
+ static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+ {
+ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
++ int rc;
+
+ if (!lower_dentry->d_sb->s_op->statfs)
+ return -ENOSYS;
+- return lower_dentry->d_sb->s_op->statfs(lower_dentry, buf);
++
++ rc = lower_dentry->d_sb->s_op->statfs(lower_dentry, buf);
++ if (rc)
++ return rc;
++
++ buf->f_type = ECRYPTFS_SUPER_MAGIC;
++ rc = ecryptfs_set_f_namelen(&buf->f_namelen, buf->f_namelen,
++ &ecryptfs_superblock_to_private(dentry->d_sb)->mount_crypt_stat);
++
++ return rc;
+ }
+
+ /**
+--
+1.7.12.rc1.1.gbce1580
+
diff --git a/queue/ecryptfs-use-lower-filesystem-stat-if-it-exists.patch b/queue/ecryptfs-use-lower-filesystem-stat-if-it-exists.patch
new file mode 100644
index 0000000..256cd61
--- /dev/null
+++ b/queue/ecryptfs-use-lower-filesystem-stat-if-it-exists.patch
@@ -0,0 +1,55 @@
+From 47f49986fa2b2fbd14ba3ccd1995227ce85bbc9b Mon Sep 17 00:00:00 2001
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+Date: Fri, 3 Aug 2012 10:43:30 -0400
+Subject: [PATCH] ecryptfs: use lower filesystem stat if it exists
+
+part of commit ebabe9a9001af0af56c0c2780ca1576246e7a74b upstream.
+
+ ----------------------
+ From ebabe9a9001af0af56c0c2780ca1576246e7a74b Mon Sep 17 00:00:00 2001
+ From: Christoph Hellwig <hch@lst.de>
+ Date: Wed, 7 Jul 2010 18:53:11 +0200
+ Subject: [PATCH] pass a struct path to vfs_statfs
+
+ We'll need the path to implement the flags field for statvfs support.
+ We do have it available in all callers except:
+
+ - ecryptfs_statfs. This one doesn't actually need vfs_statfs but just
+ needs to do a caller to the lower filesystem statfs method.
+ - sys_ustat. Add a non-exported statfs_by_dentry helper for it which
+ doesn't won't be able to fill out the flags field later on.
+
+ In addition rename the helpers for statfs vs fstatfs to do_*statfs instead
+ of the misleading vfs prefix.
+
+ Signed-off-by: Christoph Hellwig <hch@lst.de>
+ Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+ ----------------------
+
+We want the ENOSYS test, and it also paves the way for a cherry pick
+of 4a26620df4 ("eCryptfs: Improve statfs reporting") onto older stable.
+
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+
+diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
+index 0c0ae49..8a789db 100644
+--- a/fs/ecryptfs/super.c
++++ b/fs/ecryptfs/super.c
+@@ -139,7 +139,11 @@ static void ecryptfs_put_super(struct super_block *sb)
+ */
+ static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+ {
+- return vfs_statfs(ecryptfs_dentry_to_lower(dentry), buf);
++ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
++
++ if (!lower_dentry->d_sb->s_op->statfs)
++ return -ENOSYS;
++ return lower_dentry->d_sb->s_op->statfs(lower_dentry, buf);
+ }
+
+ /**
+--
+1.7.12.rc1.1.gbce1580
+
diff --git a/queue/series b/queue/series
index a031596..252930e 100644
--- a/queue/series
+++ b/queue/series
@@ -108,3 +108,6 @@ USB-Serial-Add-device-ID-for-Sierra-Wireless-MC8305.patch
USB-Serial-Add-PID-0xF7C0-to-FTDI-SIO-driver-for-a-z.patch
#misc
ACPI-AC-prevent-OOPS-on-some-boxes-due-to-missing-ch.patch
+ecryptfs-use-lower-filesystem-stat-if-it-exists.patch
+eCryptfs-Improve-statfs-reporting.patch
+