diff options
author | Tyler Hicks <tyhicks@canonical.com> | 2012-01-14 10:46:46 -0500 |
---|---|---|
committer | Tyler Hicks <tyhicks@canonical.com> | 2012-01-25 15:43:40 -0500 |
commit | 48399c0b0e6172888a2e2e36df1595ab1e049ba8 (patch) | |
tree | 7fb94f7ce80de13fd419e69322d9e6b157a49f91 /fs | |
parent | 7f133504249afa48618becac546ce3c35c9f0185 (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 5 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 5 | ||||
-rw-r--r-- | fs/ecryptfs/miscdev.c | 86 |
3 files changed, 55 insertions, 41 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index a9f29b12fbf2..a2362df58ae8 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 ac1ad48c2376..8e3b943e330f 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 1145c58103e2..349209dc6a91 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 | */ |
402 | static ssize_t | 413 | static 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", |