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

Commit 48399c0b authored by Tyler Hicks's avatar Tyler Hicks
Browse files

eCryptfs: Replace miscdev read/write magic numbers



ecryptfs_miscdev_read() and ecryptfs_miscdev_write() contained many
magic numbers for specifying packet header field sizes and offsets. This
patch defines those values and replaces the magic values.

Signed-off-by: default avatarTyler Hicks <tyhicks@canonical.com>
parent 7f133504
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -151,6 +151,11 @@ ecryptfs_get_key_payload_data(struct key *key)
					  * dentry name */
#define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as
					  * metadata */
#define ECRYPTFS_MIN_PKT_LEN_SIZE 1 /* Min size to specify packet length */
#define ECRYPTFS_MAX_PKT_LEN_SIZE 2 /* Pass at least this many bytes to
				     * ecryptfs_parse_packet_length() and
				     * ecryptfs_write_packet_length()
				     */
/* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >=
 * ECRYPTFS_MAX_IV_BYTES */
#define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16
+3 −2
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
		(*size) += ((unsigned char)(data[1]) + 192);
		(*length_size) = 2;
	} else if (data[0] == 255) {
		/* Five-byte length; we're not supposed to see this */
		/* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */
		ecryptfs_printk(KERN_ERR, "Five-byte packet length not "
				"supported\n");
		rc = -EINVAL;
@@ -126,7 +126,7 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
/**
 * ecryptfs_write_packet_length
 * @dest: The byte array target into which to write the length. Must
 *        have at least 5 bytes allocated.
 *        have at least ECRYPTFS_MAX_PKT_LEN_SIZE bytes allocated.
 * @size: The length to write.
 * @packet_size_length: The number of bytes used to encode the packet
 *                      length is written to this address.
@@ -146,6 +146,7 @@ int ecryptfs_write_packet_length(char *dest, size_t size,
		dest[1] = ((size - 192) % 256);
		(*packet_size_length) = 2;
	} else {
		/* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */
		rc = -EINVAL;
		ecryptfs_printk(KERN_WARNING,
				"Unsupported packet size: [%zd]\n", size);
+47 −39
Original line number Diff line number Diff line
@@ -218,6 +218,29 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
	return rc;
}

/*
 * miscdevfs packet format:
 *  Octet 0: Type
 *  Octets 1-4: network byte order msg_ctx->counter
 *  Octets 5-N0: Size of struct ecryptfs_message to follow
 *  Octets N0-N1: struct ecryptfs_message (including data)
 *
 *  Octets 5-N1 not written if the packet type does not include a message
 */
#define PKT_TYPE_SIZE		1
#define PKT_CTR_SIZE		4
#define MIN_NON_MSG_PKT_SIZE	(PKT_TYPE_SIZE + PKT_CTR_SIZE)
#define MIN_MSG_PKT_SIZE	(PKT_TYPE_SIZE + PKT_CTR_SIZE \
				 + ECRYPTFS_MIN_PKT_LEN_SIZE)
/* 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES comes from tag 65 packet format */
#define MAX_MSG_PKT_SIZE	(PKT_TYPE_SIZE + PKT_CTR_SIZE \
				 + ECRYPTFS_MAX_PKT_LEN_SIZE \
				 + sizeof(struct ecryptfs_message) \
				 + 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)
#define PKT_TYPE_OFFSET		0
#define PKT_CTR_OFFSET		PKT_TYPE_SIZE
#define PKT_LEN_OFFSET		(PKT_TYPE_SIZE + PKT_CTR_SIZE)

/**
 * ecryptfs_miscdev_read - format and send message from queue
 * @file: fs/ecryptfs/euid miscdevfs handle (ignored)
@@ -237,7 +260,7 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
	struct ecryptfs_daemon *daemon;
	struct ecryptfs_msg_ctx *msg_ctx;
	size_t packet_length_size;
	char packet_length[3];
	char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE];
	size_t i;
	size_t total_length;
	uid_t euid = current_euid();
@@ -305,15 +328,8 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
		packet_length_size = 0;
		msg_ctx->msg_size = 0;
	}
	/* miscdevfs packet format:
	 *  Octet 0: Type
	 *  Octets 1-4: network byte order msg_ctx->counter
	 *  Octets 5-N0: Size of struct ecryptfs_message to follow
	 *  Octets N0-N1: struct ecryptfs_message (including data)
	 *
	 *  Octets 5-N1 not written if the packet type does not
	 *  include a message */
	total_length = (1 + 4 + packet_length_size + msg_ctx->msg_size);
	total_length = (PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_length_size
			+ msg_ctx->msg_size);
	if (count < total_length) {
		rc = 0;
		printk(KERN_WARNING "%s: Only given user buffer of "
@@ -324,9 +340,10 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
	rc = -EFAULT;
	if (put_user(msg_ctx->type, buf))
		goto out_unlock_msg_ctx;
	if (put_user(cpu_to_be32(msg_ctx->counter), (__be32 __user *)(buf + 1)))
	if (put_user(cpu_to_be32(msg_ctx->counter),
		     (__be32 __user *)(&buf[PKT_CTR_OFFSET])))
		goto out_unlock_msg_ctx;
	i = 5;
	i = PKT_TYPE_SIZE + PKT_CTR_SIZE;
	if (msg_ctx->msg) {
		if (copy_to_user(&buf[i], packet_length, packet_length_size))
			goto out_unlock_msg_ctx;
@@ -391,12 +408,6 @@ static int ecryptfs_miscdev_response(char *data, size_t data_size,
 * @count: Amount of data in @buf
 * @ppos: Pointer to offset in file (ignored)
 *
 * miscdevfs packet format:
 *  Octet 0: Type
 *  Octets 1-4: network byte order msg_ctx->counter (0's for non-response)
 *  Octets 5-N0: Size of struct ecryptfs_message to follow
 *  Octets N0-N1: struct ecryptfs_message (including data)
 *
 * Returns the number of bytes read from @buf
 */
static ssize_t
@@ -405,29 +416,25 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
{
	__be32 counter_nbo;
	u32 seq;
	size_t packet_size, packet_size_length, i;
	size_t packet_size, packet_size_length;
	char *data;
	uid_t euid = current_euid();
	unsigned char packet_size_peek[3];
	unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE];
	ssize_t rc;

	if (count == 0) {
		return 0;
	} else if (count == (1 + 4)) {
	} else if (count == MIN_NON_MSG_PKT_SIZE) {
		/* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
		goto memdup;
	} else if (count < (1 + 4 + 1)
		   || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
			       + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
	} else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) {
		printk(KERN_WARNING "%s: Acceptable packet size range is "
		       "[%d-%lu], but amount of data written is [%zu].",
		       __func__, (1 + 4 + 1),
		       (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
			+ ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
		       __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count);
		return -EINVAL;
	}

	if (copy_from_user(packet_size_peek, (buf + 1 + 4),
	if (copy_from_user(packet_size_peek, &buf[PKT_LEN_OFFSET],
			   sizeof(packet_size_peek))) {
		printk(KERN_WARNING "%s: Error while inspecting packet size\n",
		       __func__);
@@ -442,7 +449,8 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
		return rc;
	}

	if ((1 + 4 + packet_size_length + packet_size) != count) {
	if ((PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_size_length + packet_size)
	    != count) {
		printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
		       packet_size);
		return -EINVAL;
@@ -455,24 +463,24 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
		       __func__, PTR_ERR(data));
		return PTR_ERR(data);
	}
	i = 0;
	switch (data[i++]) {
	switch (data[PKT_TYPE_OFFSET]) {
	case ECRYPTFS_MSG_RESPONSE:
		if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) {
		if (count < (MIN_MSG_PKT_SIZE
			     + sizeof(struct ecryptfs_message))) {
			printk(KERN_WARNING "%s: Minimum acceptable packet "
			       "size is [%zd], but amount of data written is "
			       "only [%zd]. Discarding response packet.\n",
			       __func__,
			       (1 + 4 + 1 + sizeof(struct ecryptfs_message)),
			       count);
			       (MIN_MSG_PKT_SIZE
				+ sizeof(struct ecryptfs_message)), count);
			rc = -EINVAL;
			goto out_free;
		}
		memcpy(&counter_nbo, &data[i], 4);
		memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE);
		seq = be32_to_cpu(counter_nbo);
		i += 4 + packet_size_length;
		rc = ecryptfs_miscdev_response(&data[i], packet_size,
					       euid, current_user_ns(),
		rc = ecryptfs_miscdev_response(
				&data[PKT_LEN_OFFSET + packet_size_length],
				packet_size, euid, current_user_ns(),
				task_pid(current), seq);
		if (rc) {
			printk(KERN_WARNING "%s: Failed to deliver miscdev "