Skip to content

Commit

Permalink
[CIFS] clean up upcall handling for dns_resolver keys
Browse files Browse the repository at this point in the history
We're given the datalen in the downcall, so there's no need to do any
calls to strlen(). Just keep track of the datalen in the key. Finally,
add a sanity check of the data in the downcall to make sure that it
looks like a real IP address.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Steve French committed Sep 23, 2008
1 parent ee2fd96 commit 9d81523
Showing 1 changed file with 41 additions and 33 deletions.
74 changes: 41 additions & 33 deletions fs/cifs/dns_resolve.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,55 @@
#include "cifsproto.h"
#include "cifs_debug.h"

static int dns_resolver_instantiate(struct key *key, const void *data,
/* Checks if supplied name is IP address
* returns:
* 1 - name is IP
* 0 - name is not IP
*/
static int
is_ip(const char *name)
{
int rc;
struct sockaddr_in sin_server;
struct sockaddr_in6 sin_server6;

rc = cifs_inet_pton(AF_INET, name,
&sin_server.sin_addr.s_addr);

if (rc <= 0) {
/* not ipv4 address, try ipv6 */
rc = cifs_inet_pton(AF_INET6, name,
&sin_server6.sin6_addr.in6_u);
if (rc > 0)
return 1;
} else {
return 1;
}
/* we failed translating address */
return 0;
}

static int
dns_resolver_instantiate(struct key *key, const void *data,
size_t datalen)
{
int rc = 0;
char *ip;

ip = kmalloc(datalen+1, GFP_KERNEL);
ip = kmalloc(datalen + 1, GFP_KERNEL);
if (!ip)
return -ENOMEM;

memcpy(ip, data, datalen);
ip[datalen] = '\0';

/* make sure this looks like an address */
if (!is_ip((const char *) ip)) {
kfree(ip);
return -EINVAL;
}

key->type_data.x[0] = datalen;
rcu_assign_pointer(key->payload.data, ip);

return rc;
Expand All @@ -62,33 +98,6 @@ struct key_type key_type_dns_resolver = {
.match = user_match,
};

/* Checks if supplied name is IP address
* returns:
* 1 - name is IP
* 0 - name is not IP
*/
static int is_ip(const char *name)
{
int rc;
struct sockaddr_in sin_server;
struct sockaddr_in6 sin_server6;

rc = cifs_inet_pton(AF_INET, name,
&sin_server.sin_addr.s_addr);

if (rc <= 0) {
/* not ipv4 address, try ipv6 */
rc = cifs_inet_pton(AF_INET6, name,
&sin_server6.sin6_addr.in6_u);
if (rc > 0)
return 1;
} else {
return 1;
}
/* we failed translating address */
return 0;
}

/* Resolves server name to ip address.
* input:
* unc - server UNC
Expand Down Expand Up @@ -140,6 +149,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)

rkey = request_key(&key_type_dns_resolver, name, "");
if (!IS_ERR(rkey)) {
len = rkey->type_data.x[0];
data = rkey->payload.data;
} else {
cERROR(1, ("%s: unable to resolve: %s", __func__, name));
Expand All @@ -148,11 +158,9 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)

skip_upcall:
if (data) {
len = strlen(data);
*ip_addr = kmalloc(len+1, GFP_KERNEL);
*ip_addr = kmalloc(len + 1, GFP_KERNEL);
if (*ip_addr) {
memcpy(*ip_addr, data, len);
(*ip_addr)[len] = '\0';
memcpy(*ip_addr, data, len + 1);
if (!IS_ERR(rkey))
cFYI(1, ("%s: resolved: %s to %s", __func__,
name,
Expand Down

0 comments on commit 9d81523

Please sign in to comment.