Commit 8a001af4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ecryptfs-4.0-rc3-fixes' of...

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

Pull eCryptfs fixes from Tyler Hicks:
 "Fixes for proper ioctl handling and an untriggerable buffer overflow

   - The eCryptfs ioctl handling functions should only pass known-good
     ioctl commands to the lower filesystem

   - A static checker found a potential buffer overflow.  Upon
     inspection, it is not triggerable due to input validation performed
     on the mount parameters"

* tag 'ecryptfs-4.0-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs:
  eCryptfs: don't pass fs-specific ioctl commands through
  eCryptfs: ensure copy to crypt_stat->cipher does not overrun
parents 6587457b 6d65261a
...@@ -124,7 +124,7 @@ ecryptfs_get_key_payload_data(struct key *key) ...@@ -124,7 +124,7 @@ ecryptfs_get_key_payload_data(struct key *key)
} }
#define ECRYPTFS_MAX_KEYSET_SIZE 1024 #define ECRYPTFS_MAX_KEYSET_SIZE 1024
#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32 #define ECRYPTFS_MAX_CIPHER_NAME_SIZE 31
#define ECRYPTFS_MAX_NUM_ENC_KEYS 64 #define ECRYPTFS_MAX_NUM_ENC_KEYS 64
#define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */ #define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */
#define ECRYPTFS_SALT_BYTES 2 #define ECRYPTFS_SALT_BYTES 2
...@@ -237,7 +237,7 @@ struct ecryptfs_crypt_stat { ...@@ -237,7 +237,7 @@ struct ecryptfs_crypt_stat {
struct crypto_ablkcipher *tfm; struct crypto_ablkcipher *tfm;
struct crypto_hash *hash_tfm; /* Crypto context for generating struct crypto_hash *hash_tfm; /* Crypto context for generating
* the initialization vectors */ * the initialization vectors */
unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1];
unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
struct list_head keysig_list; struct list_head keysig_list;
......
...@@ -303,9 +303,22 @@ ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -303,9 +303,22 @@ ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct file *lower_file = ecryptfs_file_to_lower(file); struct file *lower_file = ecryptfs_file_to_lower(file);
long rc = -ENOTTY; long rc = -ENOTTY;
if (lower_file->f_op->unlocked_ioctl) if (!lower_file->f_op->unlocked_ioctl)
return rc;
switch (cmd) {
case FITRIM:
case FS_IOC_GETFLAGS:
case FS_IOC_SETFLAGS:
case FS_IOC_GETVERSION:
case FS_IOC_SETVERSION:
rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
return rc; fsstack_copy_attr_all(file_inode(file), file_inode(lower_file));
return rc;
default:
return rc;
}
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
...@@ -315,9 +328,22 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -315,9 +328,22 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct file *lower_file = ecryptfs_file_to_lower(file); struct file *lower_file = ecryptfs_file_to_lower(file);
long rc = -ENOIOCTLCMD; long rc = -ENOIOCTLCMD;
if (lower_file->f_op->compat_ioctl) if (!lower_file->f_op->compat_ioctl)
return rc;
switch (cmd) {
case FITRIM:
case FS_IOC32_GETFLAGS:
case FS_IOC32_SETFLAGS:
case FS_IOC32_GETVERSION:
case FS_IOC32_SETVERSION:
rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
return rc; fsstack_copy_attr_all(file_inode(file), file_inode(lower_file));
return rc;
default:
return rc;
}
} }
#endif #endif
......
...@@ -891,7 +891,7 @@ struct ecryptfs_parse_tag_70_packet_silly_stack { ...@@ -891,7 +891,7 @@ struct ecryptfs_parse_tag_70_packet_silly_stack {
struct blkcipher_desc desc; struct blkcipher_desc desc;
char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1];
char iv[ECRYPTFS_MAX_IV_BYTES]; char iv[ECRYPTFS_MAX_IV_BYTES];
char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1];
}; };
/** /**
......
...@@ -407,7 +407,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, ...@@ -407,7 +407,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options,
if (!cipher_name_set) { if (!cipher_name_set) {
int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER);
BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); BUG_ON(cipher_name_len > ECRYPTFS_MAX_CIPHER_NAME_SIZE);
strcpy(mount_crypt_stat->global_default_cipher_name, strcpy(mount_crypt_stat->global_default_cipher_name,
ECRYPTFS_DEFAULT_CIPHER); ECRYPTFS_DEFAULT_CIPHER);
} }
......
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