Commit bbcc5fa8 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] kNFSd: ip_map_init does a kmalloc which isn't checked...

From: NeilBrown <neilb@cse.unsw.edu.au>

There is no way to return an error from a cache init routine, so instead we
make sure to pre-allocate the memory needed, and free it after the lookup
if the lookup failed.
parent 9417bd87
...@@ -119,7 +119,8 @@ static inline int ip_map_match(struct ip_map *item, struct ip_map *tmp) ...@@ -119,7 +119,8 @@ static inline int ip_map_match(struct ip_map *item, struct ip_map *tmp)
} }
static inline void ip_map_init(struct ip_map *new, struct ip_map *item) static inline void ip_map_init(struct ip_map *new, struct ip_map *item)
{ {
new->m_class = strdup(item->m_class); new->m_class = item->m_class;
item->m_class = NULL;
new->m_addr.s_addr = item->m_addr.s_addr; new->m_addr.s_addr = item->m_addr.s_addr;
} }
static inline void ip_map_update(struct ip_map *new, struct ip_map *item) static inline void ip_map_update(struct ip_map *new, struct ip_map *item)
...@@ -191,7 +192,9 @@ static int ip_map_parse(struct cache_detail *cd, ...@@ -191,7 +192,9 @@ static int ip_map_parse(struct cache_detail *cd,
} else } else
dom = NULL; dom = NULL;
ipm.m_class = class; ipm.m_class = strdup(class);
if (ipm.m_class == NULL)
return -ENOMEM;
ipm.m_addr.s_addr = ipm.m_addr.s_addr =
htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
ipm.h.flags = 0; ipm.h.flags = 0;
...@@ -207,6 +210,7 @@ static int ip_map_parse(struct cache_detail *cd, ...@@ -207,6 +210,7 @@ static int ip_map_parse(struct cache_detail *cd,
ip_map_put(&ipmp->h, &ip_map_cache); ip_map_put(&ipmp->h, &ip_map_cache);
if (dom) if (dom)
auth_domain_put(dom); auth_domain_put(dom);
if (ipm.m_class) kfree(ipm.m_class);
if (!ipmp) if (!ipmp)
return -ENOMEM; return -ENOMEM;
cache_flush(); cache_flush();
...@@ -266,7 +270,9 @@ int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) ...@@ -266,7 +270,9 @@ int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
if (dom->flavour != RPC_AUTH_UNIX) if (dom->flavour != RPC_AUTH_UNIX)
return -EINVAL; return -EINVAL;
udom = container_of(dom, struct unix_domain, h); udom = container_of(dom, struct unix_domain, h);
ip.m_class = "nfsd"; ip.m_class = strdup("nfsd");
if (!ip.m_class)
return -ENOMEM;
ip.m_addr = addr; ip.m_addr = addr;
ip.m_client = udom; ip.m_client = udom;
ip.m_add_change = udom->addr_changes+1; ip.m_add_change = udom->addr_changes+1;
...@@ -274,6 +280,7 @@ int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) ...@@ -274,6 +280,7 @@ int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
ip.h.expiry_time = NEVER; ip.h.expiry_time = NEVER;
ipmp = ip_map_lookup(&ip, 1); ipmp = ip_map_lookup(&ip, 1);
if (ip.m_class) kfree(ip.m_class);
if (ipmp) { if (ipmp) {
ip_map_put(&ipmp->h, &ip_map_cache); ip_map_put(&ipmp->h, &ip_map_cache);
return 0; return 0;
......
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