CVE-2010-3849: Linux kernel PF_ECONET NULL Pointer Dereference
This is the next vulnerability being killed by Nelson Elhage. While reading econet_sendmsg() (check out CVE-2010-3848) is almost impossible to avoid noticing this comment:
/*
* Get and verify the address.
*/
mutex_lock(&econet_mutex);
if (saddr == NULL) {
struct econet_sock *eo = ec_sk(sk);
addr.station = eo->station;
addr.net = eo->net;
port = eo->port;
cb = eo->cb;
} else {
if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
mutex_unlock(&econet_mutex);
return -EINVAL;
}
addr.station = saddr->addr.station;
addr.net = saddr->addr.net;
port = saddr->port;
cb = saddr->cb;
}
...
if (dev->type == ARPHRD_ECONET) {
/* Real hardware Econet. We're not worthy etc. */
#ifdef CONFIG_ECONET_NATIVE
...
/* BUG: saddr may be NULL */
eb->cookie = saddr->cookie;
eb->sec = *saddr;
eb->sent = ec_tx_done;
You can read that there is an initial check of ‘saddr’ being NULL that initializes ‘addr’ appropriately. However, In case of a hardware ECONET type, it will initialize ‘eb’ structure’s members without any checks. There is even a comment to help us out. To fix this, the NULL checking code was changed.
mutex_lock(&econet_mutex);
- if (saddr == NULL) {
- struct econet_sock *eo = ec_sk(sk);
-
- addr.station = eo->station;
- addr.net = eo->net;
- port = eo->port;
- cb = eo->cb;
- } else {
- if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
- mutex_unlock(&econet_mutex);
- return -EINVAL;
- }
- addr.station = saddr->addr.station;
- addr.net = saddr->addr.net;
- port = saddr->port;
- cb = saddr->cb;
- }
+ if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
+ mutex_unlock(&econet_mutex);
+ return -EINVAL;
+ }
+ addr.station = saddr->addr.station;
+ addr.net = saddr->addr.net;
+ port = saddr->port;
+ cb = saddr->cb;
/* Look for a device with the right network number. */
This way, if either ‘saddr’ is NULL or ‘msg->msg_namelen’ is less than the size of ‘sockaddr_ec’ structure it will immediately return with ‘-EINVAL’ (Invalid Argument) before reaching the code that triggers the NULL pointer dereference. If this is not the case, it will initialize the appropriate structures using ‘saddr’.
