aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2012-01-14 10:46:46 -0500
committerTyler Hicks <tyhicks@canonical.com>2012-01-25 15:43:40 -0500
commit48399c0b0e6172888a2e2e36df1595ab1e049ba8 (patch)
tree7fb94f7ce80de13fd419e69322d9e6b157a49f91
parent7f133504249afa48618becac546ce3c35c9f0185 (diff)
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: Tyler Hicks <tyhicks@canonical.com>
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h5
-rw-r--r--fs/ecryptfs/keystore.c5
-rw-r--r--fs/ecryptfs/miscdev.c86
3 files changed, 55 insertions, 41 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index a9f29b12fbf..a2362df58ae 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -151,6 +151,11 @@ ecryptfs_get_key_payload_data(struct key *key)
151 * dentry name */ 151 * dentry name */
152#define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as 152#define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as
153 * metadata */ 153 * metadata */
154#define ECRYPTFS_MIN_PKT_LEN_SIZE 1 /* Min size to specify packet length */
155#define ECRYPTFS_MAX_PKT_LEN_SIZE 2 /* Pass at least this many bytes to
156 * ecryptfs_parse_packet_length() and
157 * ecryptfs_write_packet_length()
158 */
154/* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >= 159/* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >=
155 * ECRYPTFS_MAX_IV_BYTES */ 160 * ECRYPTFS_MAX_IV_BYTES */
156#define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16 161#define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index ac1ad48c237..8e3b943e330 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -109,7 +109,7 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
109 (*size) += ((unsigned char)(data[1]) + 192); 109 (*size) += ((unsigned char)(data[1]) + 192);
110 (*length_size) = 2; 110 (*length_size) = 2;
111 } else if (data[0] == 255) { 111 } else if (data[0] == 255) {
112 /* Five-byte length; we're not supposed to see this */ 112 /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */
113 ecryptfs_printk(KERN_ERR, "Five-byte packet length not " 113 ecryptfs_printk(KERN_ERR, "Five-byte packet length not "
114 "supported\n"); 114 "supported\n");
115 rc = -EINVAL; 115 rc = -EINVAL;
@@ -126,7 +126,7 @@ out:
126/** 126/**
127 * ecryptfs_write_packet_length 127 * ecryptfs_write_packet_length
128 * @dest: The byte array target into which to write the length. Must 128 * @dest: The byte array target into which to write the length. Must
129 * have at least 5 bytes allocated. 129 * have at least ECRYPTFS_MAX_PKT_LEN_SIZE bytes allocated.
130 * @size: The length to write. 130 * @size: The length to write.
131 * @packet_size_length: The number of bytes used to encode the packet 131 * @packet_size_length: The number of bytes used to encode the packet
132 * length is written to this address. 132 * length is written to this address.
@@ -146,6 +146,7 @@ int ecryptfs_write_packet_length(char *dest, size_t size,
146 dest[1] = ((size - 192) % 256); 146 dest[1] = ((size - 192) % 256);
147 (*packet_size_length) = 2; 147 (*packet_size_length) = 2;
148 } else { 148 } else {
149 /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */
149 rc = -EINVAL; 150 rc = -EINVAL;
150 ecryptfs_printk(KERN_WARNING, 151 ecryptfs_printk(KERN_WARNING,
151 "Unsupported packet size: [%zd]\n", size); 152 "Unsupported packet size: [%zd]\n", size);
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:
218 return rc; 218 return rc;
219} 219}
220 220
221/*
222 * miscdevfs packet format:
223 * Octet 0: Type
224 * Octets 1-4: network byte order msg_ctx->counter
225 * Octets 5-N0: Size of struct ecryptfs_message to follow
226 * Octets N0-N1: struct ecryptfs_message (including data)
227 *
228 * Octets 5-N1 not written if the packet type does not include a message
229 */
230#define PKT_TYPE_SIZE 1
231#define PKT_CTR_SIZE 4
232#define MIN_NON_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE)
233#define MIN_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \
234 + ECRYPTFS_MIN_PKT_LEN_SIZE)
235/* 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES comes from tag 65 packet format */
236#define MAX_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \
237 + ECRYPTFS_MAX_PKT_LEN_SIZE \
238 + sizeof(struct ecryptfs_message) \
239 + 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)
240#define PKT_TYPE_OFFSET 0
241#define PKT_CTR_OFFSET PKT_TYPE_SIZE
242#define PKT_LEN_OFFSET (PKT_TYPE_SIZE + PKT_CTR_SIZE)
243
221/** 244/**
222 * ecryptfs_miscdev_read - format and send message from queue 245 * ecryptfs_miscdev_read - format and send message from queue
223 * @file: fs/ecryptfs/euid miscdevfs handle (ignored) 246 * @file: fs/ecryptfs/euid miscdevfs handle (ignored)
@@ -237,7 +260,7 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
237 struct ecryptfs_daemon *daemon; 260 struct ecryptfs_daemon *daemon;
238 struct ecryptfs_msg_ctx *msg_ctx; 261 struct ecryptfs_msg_ctx *msg_ctx;
239 size_t packet_length_size; 262 size_t packet_length_size;
240 char packet_length[3]; 263 char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE];
241 size_t i; 264 size_t i;
242 size_t total_length; 265 size_t total_length;
243 uid_t euid = current_euid(); 266 uid_t euid = current_euid();
@@ -305,15 +328,8 @@ check_list:
305 packet_length_size = 0; 328 packet_length_size = 0;
306 msg_ctx->msg_size = 0; 329 msg_ctx->msg_size = 0;
307 } 330 }
308 /* miscdevfs packet format: 331 total_length = (PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_length_size
309 * Octet 0: Type 332 + msg_ctx->msg_size);
310 * Octets 1-4: network byte order msg_ctx->counter
311 * Octets 5-N0: Size of struct ecryptfs_message to follow
312 * Octets N0-N1: struct ecryptfs_message (including data)
313 *
314 * Octets 5-N1 not written if the packet type does not
315 * include a message */
316 total_length = (1 + 4 + packet_length_size + msg_ctx->msg_size);
317 if (count < total_length) { 333 if (count < total_length) {
318 rc = 0; 334 rc = 0;
319 printk(KERN_WARNING "%s: Only given user buffer of " 335 printk(KERN_WARNING "%s: Only given user buffer of "
@@ -324,9 +340,10 @@ check_list:
324 rc = -EFAULT; 340 rc = -EFAULT;
325 if (put_user(msg_ctx->type, buf)) 341 if (put_user(msg_ctx->type, buf))
326 goto out_unlock_msg_ctx; 342 goto out_unlock_msg_ctx;
327 if (put_user(cpu_to_be32(msg_ctx->counter), (__be32 __user *)(buf + 1))) 343 if (put_user(cpu_to_be32(msg_ctx->counter),
344 (__be32 __user *)(&buf[PKT_CTR_OFFSET])))
328 goto out_unlock_msg_ctx; 345 goto out_unlock_msg_ctx;
329 i = 5; 346 i = PKT_TYPE_SIZE + PKT_CTR_SIZE;
330 if (msg_ctx->msg) { 347 if (msg_ctx->msg) {
331 if (copy_to_user(&buf[i], packet_length, packet_length_size)) 348 if (copy_to_user(&buf[i], packet_length, packet_length_size))
332 goto out_unlock_msg_ctx; 349 goto out_unlock_msg_ctx;
@@ -391,12 +408,6 @@ out:
391 * @count: Amount of data in @buf 408 * @count: Amount of data in @buf
392 * @ppos: Pointer to offset in file (ignored) 409 * @ppos: Pointer to offset in file (ignored)
393 * 410 *
394 * miscdevfs packet format:
395 * Octet 0: Type
396 * Octets 1-4: network byte order msg_ctx->counter (0's for non-response)
397 * Octets 5-N0: Size of struct ecryptfs_message to follow
398 * Octets N0-N1: struct ecryptfs_message (including data)
399 *
400 * Returns the number of bytes read from @buf 411 * Returns the number of bytes read from @buf
401 */ 412 */
402static ssize_t 413static ssize_t
@@ -405,29 +416,25 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
405{ 416{
406 __be32 counter_nbo; 417 __be32 counter_nbo;
407 u32 seq; 418 u32 seq;
408 size_t packet_size, packet_size_length, i; 419 size_t packet_size, packet_size_length;
409 char *data; 420 char *data;
410 uid_t euid = current_euid(); 421 uid_t euid = current_euid();
411 unsigned char packet_size_peek[3]; 422 unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE];
412 ssize_t rc; 423 ssize_t rc;
413 424
414 if (count == 0) { 425 if (count == 0) {
415 return 0; 426 return 0;
416 } else if (count == (1 + 4)) { 427 } else if (count == MIN_NON_MSG_PKT_SIZE) {
417 /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */ 428 /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
418 goto memdup; 429 goto memdup;
419 } else if (count < (1 + 4 + 1) 430 } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) {
420 || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
421 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
422 printk(KERN_WARNING "%s: Acceptable packet size range is " 431 printk(KERN_WARNING "%s: Acceptable packet size range is "
423 "[%d-%lu], but amount of data written is [%zu].", 432 "[%d-%lu], but amount of data written is [%zu].",
424 __func__, (1 + 4 + 1), 433 __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count);
425 (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
426 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
427 return -EINVAL; 434 return -EINVAL;
428 } 435 }
429 436
430 if (copy_from_user(packet_size_peek, (buf + 1 + 4), 437 if (copy_from_user(packet_size_peek, &buf[PKT_LEN_OFFSET],
431 sizeof(packet_size_peek))) { 438 sizeof(packet_size_peek))) {
432 printk(KERN_WARNING "%s: Error while inspecting packet size\n", 439 printk(KERN_WARNING "%s: Error while inspecting packet size\n",
433 __func__); 440 __func__);
@@ -442,7 +449,8 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
442 return rc; 449 return rc;
443 } 450 }
444 451
445 if ((1 + 4 + packet_size_length + packet_size) != count) { 452 if ((PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_size_length + packet_size)
453 != count) {
446 printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__, 454 printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
447 packet_size); 455 packet_size);
448 return -EINVAL; 456 return -EINVAL;
@@ -455,25 +463,25 @@ memdup:
455 __func__, PTR_ERR(data)); 463 __func__, PTR_ERR(data));
456 return PTR_ERR(data); 464 return PTR_ERR(data);
457 } 465 }
458 i = 0; 466 switch (data[PKT_TYPE_OFFSET]) {
459 switch (data[i++]) {
460 case ECRYPTFS_MSG_RESPONSE: 467 case ECRYPTFS_MSG_RESPONSE:
461 if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) { 468 if (count < (MIN_MSG_PKT_SIZE
469 + sizeof(struct ecryptfs_message))) {
462 printk(KERN_WARNING "%s: Minimum acceptable packet " 470 printk(KERN_WARNING "%s: Minimum acceptable packet "
463 "size is [%zd], but amount of data written is " 471 "size is [%zd], but amount of data written is "
464 "only [%zd]. Discarding response packet.\n", 472 "only [%zd]. Discarding response packet.\n",
465 __func__, 473 __func__,
466 (1 + 4 + 1 + sizeof(struct ecryptfs_message)), 474 (MIN_MSG_PKT_SIZE
467 count); 475 + sizeof(struct ecryptfs_message)), count);
468 rc = -EINVAL; 476 rc = -EINVAL;
469 goto out_free; 477 goto out_free;
470 } 478 }
471 memcpy(&counter_nbo, &data[i], 4); 479 memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE);
472 seq = be32_to_cpu(counter_nbo); 480 seq = be32_to_cpu(counter_nbo);
473 i += 4 + packet_size_length; 481 rc = ecryptfs_miscdev_response(
474 rc = ecryptfs_miscdev_response(&data[i], packet_size, 482 &data[PKT_LEN_OFFSET + packet_size_length],
475 euid, current_user_ns(), 483 packet_size, euid, current_user_ns(),
476 task_pid(current), seq); 484 task_pid(current), seq);
477 if (rc) { 485 if (rc) {
478 printk(KERN_WARNING "%s: Failed to deliver miscdev " 486 printk(KERN_WARNING "%s: Failed to deliver miscdev "
479 "response to requesting operation; rc = [%zd]\n", 487 "response to requesting operation; rc = [%zd]\n",