Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

eCryptfs: NULL pointer dereference in ecryptfs_send_miscdev()

If data is NULL, msg_ctx->msg is set to NULL and then dereferenced
afterwards. ecryptfs_send_raw_message() is the only place that
ecryptfs_send_miscdev() is called with data being NULL, but the only
caller of that function (ecryptfs_process_helo()) is never called. In
short, there is currently no way to trigger the NULL pointer
dereference.

This patch removes the two unused functions and modifies
ecryptfs_send_miscdev() to remove the NULL dereferences.

Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>

+11 -99
-82
fs/ecryptfs/messaging.c
··· 133 133 return rc; 134 134 } 135 135 136 - static int 137 - ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type, 138 - struct ecryptfs_msg_ctx **msg_ctx); 139 - 140 - /** 141 - * ecryptfs_send_raw_message 142 - * @msg_type: Message type 143 - * @daemon: Daemon struct for recipient of message 144 - * 145 - * A raw message is one that does not include an ecryptfs_message 146 - * struct. It simply has a type. 147 - * 148 - * Must be called with ecryptfs_daemon_hash_mux held. 149 - * 150 - * Returns zero on success; non-zero otherwise 151 - */ 152 - static int ecryptfs_send_raw_message(u8 msg_type, 153 - struct ecryptfs_daemon *daemon) 154 - { 155 - struct ecryptfs_msg_ctx *msg_ctx; 156 - int rc; 157 - 158 - rc = ecryptfs_send_message_locked(NULL, 0, msg_type, &msg_ctx); 159 - if (rc) { 160 - printk(KERN_ERR "%s: Error whilst attempting to send " 161 - "message to ecryptfsd; rc = [%d]\n", __func__, rc); 162 - goto out; 163 - } 164 - /* Raw messages are logically context-free (e.g., no 165 - * reply is expected), so we set the state of the 166 - * ecryptfs_msg_ctx object to indicate that it should 167 - * be freed as soon as the message is sent. */ 168 - mutex_lock(&msg_ctx->mux); 169 - msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY; 170 - mutex_unlock(&msg_ctx->mux); 171 - out: 172 - return rc; 173 - } 174 - 175 136 /** 176 137 * ecryptfs_spawn_daemon - Create and initialize a new daemon struct 177 138 * @daemon: Pointer to set to newly allocated daemon struct ··· 169 208 hlist_add_head(&(*daemon)->euid_chain, 170 209 &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]); 171 210 out: 172 - return rc; 173 - } 174 - 175 - /** 176 - * ecryptfs_process_helo 177 - * @euid: The user ID owner of the message 178 - * @user_ns: The namespace in which @euid applies 179 - * @pid: The process ID for the userspace program that sent the 180 - * message 181 - * 182 - * Adds the euid and pid values to the daemon euid hash. If an euid 183 - * already has a daemon pid registered, the daemon will be 184 - * unregistered before the new daemon is put into the hash list. 185 - * Returns zero after adding a new daemon to the hash list; 186 - * non-zero otherwise. 187 - */ 188 - int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns, 189 - struct pid *pid) 190 - { 191 - struct ecryptfs_daemon *new_daemon; 192 - struct ecryptfs_daemon *old_daemon; 193 - int rc; 194 - 195 - mutex_lock(&ecryptfs_daemon_hash_mux); 196 - rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid, user_ns); 197 - if (rc != 0) { 198 - printk(KERN_WARNING "Received request from user [%d] " 199 - "to register daemon [0x%p]; unregistering daemon " 200 - "[0x%p]\n", euid, pid, old_daemon->pid); 201 - rc = ecryptfs_send_raw_message(ECRYPTFS_MSG_QUIT, old_daemon); 202 - if (rc) 203 - printk(KERN_WARNING "Failed to send QUIT " 204 - "message to daemon [0x%p]; rc = [%d]\n", 205 - old_daemon->pid, rc); 206 - hlist_del(&old_daemon->euid_chain); 207 - kfree(old_daemon); 208 - } 209 - rc = ecryptfs_spawn_daemon(&new_daemon, euid, user_ns, pid); 210 - if (rc) 211 - printk(KERN_ERR "%s: The gods are displeased with this attempt " 212 - "to create a new daemon object for euid [%d]; pid " 213 - "[0x%p]; rc = [%d]\n", __func__, euid, pid, rc); 214 - mutex_unlock(&ecryptfs_daemon_hash_mux); 215 211 return rc; 216 212 } 217 213
+11 -17
fs/ecryptfs/miscdev.c
··· 193 193 int rc = 0; 194 194 195 195 mutex_lock(&msg_ctx->mux); 196 - if (data) { 197 - msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), 198 - GFP_KERNEL); 199 - if (!msg_ctx->msg) { 200 - rc = -ENOMEM; 201 - printk(KERN_ERR "%s: Out of memory whilst attempting " 202 - "to kmalloc(%zd, GFP_KERNEL)\n", __func__, 203 - (sizeof(*msg_ctx->msg) + data_size)); 204 - goto out_unlock; 205 - } 206 - } else 207 - msg_ctx->msg = NULL; 196 + msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), 197 + GFP_KERNEL); 198 + if (!msg_ctx->msg) { 199 + rc = -ENOMEM; 200 + printk(KERN_ERR "%s: Out of memory whilst attempting " 201 + "to kmalloc(%zd, GFP_KERNEL)\n", __func__, 202 + (sizeof(*msg_ctx->msg) + data_size)); 203 + goto out_unlock; 204 + } 208 205 msg_ctx->msg->index = msg_ctx->index; 209 206 msg_ctx->msg->data_len = data_size; 210 207 msg_ctx->type = msg_type; 211 - if (data) { 212 - memcpy(msg_ctx->msg->data, data, data_size); 213 - msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); 214 - } else 215 - msg_ctx->msg_size = 0; 208 + memcpy(msg_ctx->msg->data, data, data_size); 209 + msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); 216 210 mutex_lock(&daemon->mux); 217 211 list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); 218 212 daemon->num_queued_msg_ctx++;