Commit f66e883e authored by Michael Halcrow's avatar Michael Halcrow Committed by Linus Torvalds

eCryptfs: integrate eCryptfs device handle into the module.

Update the versioning information.  Make the message types generic.  Add an
outgoing message queue to the daemon struct.  Make the functions to parse
and write the packet lengths available to the rest of the module.  Add
functions to create and destroy the daemon structs.  Clean up some of the
comments and make the code a little more consistent with itself.

[akpm@linux-foundation.org: printk fixes]
Signed-off-by: default avatarMichael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8bf2debd
......@@ -4,4 +4,4 @@
obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o debug.o
ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o miscdev.o debug.o
......@@ -4,7 +4,7 @@
*
* Copyright (C) 1997-2003 Erez Zadok
* Copyright (C) 2001-2003 Stony Brook University
* Copyright (C) 2004-2007 International Business Machines Corp.
* Copyright (C) 2004-2008 International Business Machines Corp.
* Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
* Trevor S. Highland <trevor.highland@gmail.com>
* Tyler Hicks <tyhicks@ou.edu>
......@@ -49,11 +49,13 @@
#define ECRYPTFS_VERSIONING_POLICY 0x00000008
#define ECRYPTFS_VERSIONING_XATTR 0x00000010
#define ECRYPTFS_VERSIONING_MULTKEY 0x00000020
#define ECRYPTFS_VERSIONING_DEVMISC 0x00000040
#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
| ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
| ECRYPTFS_VERSIONING_PUBKEY \
| ECRYPTFS_VERSIONING_XATTR \
| ECRYPTFS_VERSIONING_MULTKEY)
| ECRYPTFS_VERSIONING_MULTKEY \
| ECRYPTFS_VERSIONING_DEVMISC)
#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
#define ECRYPTFS_SALT_SIZE 8
......@@ -73,17 +75,14 @@
#define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32
#define ECRYPTFS_DEFAULT_SEND_TIMEOUT HZ
#define ECRYPTFS_MAX_MSG_CTX_TTL (HZ*3)
#define ECRYPTFS_NLMSG_HELO 100
#define ECRYPTFS_NLMSG_QUIT 101
#define ECRYPTFS_NLMSG_REQUEST 102
#define ECRYPTFS_NLMSG_RESPONSE 103
#define ECRYPTFS_MAX_PKI_NAME_BYTES 16
#define ECRYPTFS_DEFAULT_NUM_USERS 4
#define ECRYPTFS_MAX_NUM_USERS 32768
#define ECRYPTFS_TRANSPORT_NETLINK 0
#define ECRYPTFS_TRANSPORT_CONNECTOR 1
#define ECRYPTFS_TRANSPORT_RELAYFS 2
#define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_NETLINK
#define ECRYPTFS_TRANSPORT_MISCDEV 3
#define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_MISCDEV
#define ECRYPTFS_XATTR_NAME "user.ecryptfs"
#define RFC2440_CIPHER_DES3_EDE 0x02
......@@ -366,32 +365,62 @@ struct ecryptfs_auth_tok_list_item {
};
struct ecryptfs_message {
/* Can never be greater than ecryptfs_message_buf_len */
/* Used to find the parent msg_ctx */
/* Inherits from msg_ctx->index */
u32 index;
u32 data_len;
u8 data[];
};
struct ecryptfs_msg_ctx {
#define ECRYPTFS_MSG_CTX_STATE_FREE 0x0001
#define ECRYPTFS_MSG_CTX_STATE_PENDING 0x0002
#define ECRYPTFS_MSG_CTX_STATE_DONE 0x0003
u32 state;
unsigned int index;
unsigned int counter;
#define ECRYPTFS_MSG_CTX_STATE_FREE 0x01
#define ECRYPTFS_MSG_CTX_STATE_PENDING 0x02
#define ECRYPTFS_MSG_CTX_STATE_DONE 0x03
#define ECRYPTFS_MSG_CTX_STATE_NO_REPLY 0x04
u8 state;
#define ECRYPTFS_MSG_HELO 100
#define ECRYPTFS_MSG_QUIT 101
#define ECRYPTFS_MSG_REQUEST 102
#define ECRYPTFS_MSG_RESPONSE 103
u8 type;
u32 index;
/* Counter converts to a sequence number. Each message sent
* out for which we expect a response has an associated
* sequence number. The response must have the same sequence
* number as the counter for the msg_stc for the message to be
* valid. */
u32 counter;
size_t msg_size;
struct ecryptfs_message *msg;
struct task_struct *task;
struct list_head node;
struct list_head daemon_out_list;
struct mutex mux;
};
extern unsigned int ecryptfs_transport;
struct ecryptfs_daemon_id {
struct ecryptfs_daemon;
struct ecryptfs_daemon {
#define ECRYPTFS_DAEMON_IN_READ 0x00000001
#define ECRYPTFS_DAEMON_IN_POLL 0x00000002
#define ECRYPTFS_DAEMON_ZOMBIE 0x00000004
#define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008
u32 flags;
u32 num_queued_msg_ctx;
pid_t pid;
uid_t uid;
struct hlist_node id_chain;
uid_t euid;
struct task_struct *task;
struct mutex mux;
struct list_head msg_ctx_out_queue;
wait_queue_head_t wait;
struct hlist_node euid_chain;
};
extern struct mutex ecryptfs_daemon_hash_mux;
static inline struct ecryptfs_file_info *
ecryptfs_file_to_private(struct file *file)
{
......@@ -593,13 +622,13 @@ int ecryptfs_init_messaging(unsigned int transport);
void ecryptfs_release_messaging(unsigned int transport);
int ecryptfs_send_netlink(char *data, int data_len,
struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type,
struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
u16 msg_flags, pid_t daemon_pid);
int ecryptfs_init_netlink(void);
void ecryptfs_release_netlink(void);
int ecryptfs_send_connector(char *data, int data_len,
struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type,
struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
u16 msg_flags, pid_t daemon_pid);
int ecryptfs_init_connector(void);
void ecryptfs_release_connector(void);
......@@ -642,5 +671,19 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
size_t offset_in_page, size_t size,
struct inode *ecryptfs_inode);
struct page *ecryptfs_get_locked_page(struct file *file, loff_t index);
int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon);
int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid);
int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
size_t *length_size);
int ecryptfs_write_packet_length(char *dest, size_t size,
size_t *packet_size_length);
int ecryptfs_init_ecryptfs_miscdev(void);
void ecryptfs_destroy_ecryptfs_miscdev(void);
int ecryptfs_send_miscdev(char *data, size_t data_size,
struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
u16 msg_flags, struct ecryptfs_daemon *daemon);
void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx);
int
ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, pid_t pid);
#endif /* #ifndef ECRYPTFS_KERNEL_H */
......@@ -65,7 +65,7 @@ static int process_request_key_err(long err_code)
}
/**
* parse_packet_length
* ecryptfs_parse_packet_length
* @data: Pointer to memory containing length at offset
* @size: This function writes the decoded size to this memory
* address; zero on error
......@@ -73,8 +73,8 @@ static int process_request_key_err(long err_code)
*
* Returns zero on success; non-zero on error
*/
static int parse_packet_length(unsigned char *data, size_t *size,
size_t *length_size)
int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
size_t *length_size)
{
int rc = 0;
......@@ -105,7 +105,7 @@ static int parse_packet_length(unsigned char *data, size_t *size,
}
/**
* write_packet_length
* ecryptfs_write_packet_length
* @dest: The byte array target into which to write the length. Must
* have at least 5 bytes allocated.
* @size: The length to write.
......@@ -114,8 +114,8 @@ static int parse_packet_length(unsigned char *data, size_t *size,
*
* Returns zero on success; non-zero on error.
*/
static int write_packet_length(char *dest, size_t size,
size_t *packet_size_length)
int ecryptfs_write_packet_length(char *dest, size_t size,
size_t *packet_size_length)
{
int rc = 0;
......@@ -162,8 +162,8 @@ write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key,
goto out;
}
message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE;
rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX,
&packet_size_len);
rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX,
&packet_size_len);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet "
"header; cannot generate packet length\n");
......@@ -172,8 +172,9 @@ write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key,
i += packet_size_len;
memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX);
i += ECRYPTFS_SIG_SIZE_HEX;
rc = write_packet_length(&message[i], session_key->encrypted_key_size,
&packet_size_len);
rc = ecryptfs_write_packet_length(&message[i],
session_key->encrypted_key_size,
&packet_size_len);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet "
"header; cannot generate packet length\n");
......@@ -225,7 +226,7 @@ parse_tag_65_packet(struct ecryptfs_session_key *session_key, u8 *cipher_code,
rc = -EIO;
goto out;
}
rc = parse_packet_length(&data[i], &m_size, &data_len);
rc = ecryptfs_parse_packet_length(&data[i], &m_size, &data_len);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error parsing packet length; "
"rc = [%d]\n", rc);
......@@ -304,8 +305,8 @@ write_tag_66_packet(char *signature, u8 cipher_code,
goto out;
}
message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE;
rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX,
&packet_size_len);
rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX,
&packet_size_len);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet "
"header; cannot generate packet length\n");
......@@ -315,8 +316,8 @@ write_tag_66_packet(char *signature, u8 cipher_code,
memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX);
i += ECRYPTFS_SIG_SIZE_HEX;
/* The encrypted key includes 1 byte cipher code and 2 byte checksum */
rc = write_packet_length(&message[i], crypt_stat->key_size + 3,
&packet_size_len);
rc = ecryptfs_write_packet_length(&message[i], crypt_stat->key_size + 3,
&packet_size_len);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet "
"header; cannot generate packet length\n");
......@@ -357,20 +358,25 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec,
/* verify that everything through the encrypted FEK size is present */
if (message_len < 4) {
rc = -EIO;
printk(KERN_ERR "%s: message_len is [%Zd]; minimum acceptable "
"message length is [%d]\n", __func__, message_len, 4);
goto out;
}
if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) {
ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_67\n");
rc = -EIO;
printk(KERN_ERR "%s: Type should be ECRYPTFS_TAG_67\n",
__func__);
goto out;
}
if (data[i++]) {
ecryptfs_printk(KERN_ERR, "Status indicator has non zero value"
" [%d]\n", data[i-1]);
rc = -EIO;
printk(KERN_ERR "%s: Status indicator has non zero "
"value [%d]\n", __func__, data[i-1]);
goto out;
}
rc = parse_packet_length(&data[i], &key_rec->enc_key_size, &data_len);
rc = ecryptfs_parse_packet_length(&data[i], &key_rec->enc_key_size,
&data_len);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error parsing packet length; "
"rc = [%d]\n", rc);
......@@ -378,17 +384,17 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec,
}
i += data_len;
if (message_len < (i + key_rec->enc_key_size)) {
ecryptfs_printk(KERN_ERR, "message_len [%d]; max len is [%d]\n",
message_len, (i + key_rec->enc_key_size));
rc = -EIO;
printk(KERN_ERR "%s: message_len [%Zd]; max len is [%Zd]\n",
__func__, message_len, (i + key_rec->enc_key_size));
goto out;
}
if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
ecryptfs_printk(KERN_ERR, "Encrypted key_size [%d] larger than "
"the maximum key size [%d]\n",
key_rec->enc_key_size,
ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES);
rc = -EIO;
printk(KERN_ERR "%s: Encrypted key_size [%Zd] larger than "
"the maximum key size [%d]\n", __func__,
key_rec->enc_key_size,
ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES);
goto out;
}
memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size);
......@@ -445,7 +451,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key),
&netlink_message, &netlink_message_length);
if (rc) {
ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet");
ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet\n");
goto out;
}
rc = ecryptfs_send_message(ecryptfs_transport, netlink_message,
......@@ -570,8 +576,8 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat,
goto out;
}
(*new_auth_tok) = &auth_tok_list_item->auth_tok;
rc = parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
if (rc) {
printk(KERN_WARNING "Error parsing packet length; "
"rc = [%d]\n", rc);
......@@ -704,8 +710,8 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
goto out;
}
(*new_auth_tok) = &auth_tok_list_item->auth_tok;
rc = parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
if (rc) {
printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n",
rc);
......@@ -852,8 +858,8 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents,
rc = -EINVAL;
goto out;
}
rc = parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
if (rc) {
printk(KERN_WARNING "Invalid tag 11 packet format\n");
goto out;
......@@ -1405,8 +1411,8 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes,
auth_tok->token.private_key.key_size;
rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec);
if (rc) {
ecryptfs_printk(KERN_ERR, "Failed to encrypt session key "
"via a pki");
printk(KERN_ERR "Failed to encrypt session key via a key "
"module; rc = [%d]\n", rc);
goto out;
}
if (ecryptfs_verbosity > 0) {
......@@ -1430,8 +1436,9 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes,
goto out;
}
dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE;
rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),
&packet_size_length);
rc = ecryptfs_write_packet_length(&dest[(*packet_size)],
(max_packet_size - 4),
&packet_size_length);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet "
"header; cannot generate packet length\n");
......@@ -1489,8 +1496,9 @@ write_tag_11_packet(char *dest, size_t *remaining_bytes, char *contents,
goto out;
}
dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE;
rc = write_packet_length(&dest[(*packet_length)],
(max_packet_size - 4), &packet_size_length);
rc = ecryptfs_write_packet_length(&dest[(*packet_length)],
(max_packet_size - 4),
&packet_size_length);
if (rc) {
printk(KERN_ERR "Error generating tag 11 packet header; cannot "
"generate packet length. rc = [%d]\n", rc);
......@@ -1682,8 +1690,9 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE;
/* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3)
* to get the number of octets in the actual Tag 3 packet */
rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),
&packet_size_length);
rc = ecryptfs_write_packet_length(&dest[(*packet_size)],
(max_packet_size - 4),
&packet_size_length);
if (rc) {
printk(KERN_ERR "Error generating tag 3 packet header; cannot "
"generate packet length. rc = [%d]\n", rc);
......
This diff is collapsed.
......@@ -196,7 +196,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
if (!msg_ctx->msg) {
rc = -ENOMEM;
printk(KERN_ERR "%s: Out of memory whilst attempting "
"to kmalloc(%d, GFP_KERNEL)\n", __func__,
"to kmalloc(%Zd, GFP_KERNEL)\n", __func__,
(sizeof(*msg_ctx->msg) + data_size));
goto out_unlock;
}
......@@ -232,7 +232,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
*
* Returns the number of bytes copied into the user buffer
*/
static int
static ssize_t
ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
......
......@@ -44,7 +44,7 @@ static struct sock *ecryptfs_nl_sock;
* upon sending the message; non-zero upon error.
*/
int ecryptfs_send_netlink(char *data, int data_len,
struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type,
struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
u16 msg_flags, pid_t daemon_pid)
{
struct sk_buff *skb;
......@@ -176,20 +176,20 @@ static void ecryptfs_receive_nl_message(struct sk_buff *skb)
goto free;
}
switch (nlh->nlmsg_type) {
case ECRYPTFS_NLMSG_RESPONSE:
case ECRYPTFS_MSG_RESPONSE:
if (ecryptfs_process_nl_response(skb)) {
ecryptfs_printk(KERN_WARNING, "Failed to "
"deliver netlink response to "
"requesting operation\n");
}
break;
case ECRYPTFS_NLMSG_HELO:
case ECRYPTFS_MSG_HELO:
if (ecryptfs_process_nl_helo(skb)) {
ecryptfs_printk(KERN_WARNING, "Failed to "
"fulfill HELO request\n");
}
break;
case ECRYPTFS_NLMSG_QUIT:
case ECRYPTFS_MSG_QUIT:
if (ecryptfs_process_nl_quit(skb)) {
ecryptfs_printk(KERN_WARNING, "Failed to "
"fulfill QUIT request\n");
......
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