diff options
Diffstat (limited to 'fs/ecryptfs/miscdev.c')
| -rw-r--r-- | fs/ecryptfs/miscdev.c | 86 | 
1 files changed, 47 insertions, 39 deletions
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 1145c58103e..349209dc6a9 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c @@ -218,6 +218,29 @@ out_unlock:  	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 @@ check_list:  		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 @@ check_list:  	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 @@ out:   * @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,25 +463,25 @@ memdup:  		       __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(), -					       task_pid(current), seq); +		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 "  			       "response to requesting operation; rc = [%zd]\n",  |