Commit 9d815234 authored by Steve French's avatar Steve French

[CIFS] clean up upcall handling for dns_resolver keys

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: default avatarJeff Layton <jlayton@redhat.com>
Acked-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent ee2fd967
...@@ -29,19 +29,55 @@ ...@@ -29,19 +29,55 @@
#include "cifsproto.h" #include "cifsproto.h"
#include "cifs_debug.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) size_t datalen)
{ {
int rc = 0; int rc = 0;
char *ip; char *ip;
ip = kmalloc(datalen+1, GFP_KERNEL); ip = kmalloc(datalen + 1, GFP_KERNEL);
if (!ip) if (!ip)
return -ENOMEM; return -ENOMEM;
memcpy(ip, data, datalen); memcpy(ip, data, datalen);
ip[datalen] = '\0'; 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); rcu_assign_pointer(key->payload.data, ip);
return rc; return rc;
...@@ -62,33 +98,6 @@ struct key_type key_type_dns_resolver = { ...@@ -62,33 +98,6 @@ struct key_type key_type_dns_resolver = {
.match = user_match, .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. /* Resolves server name to ip address.
* input: * input:
* unc - server UNC * unc - server UNC
...@@ -140,6 +149,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) ...@@ -140,6 +149,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
rkey = request_key(&key_type_dns_resolver, name, ""); rkey = request_key(&key_type_dns_resolver, name, "");
if (!IS_ERR(rkey)) { if (!IS_ERR(rkey)) {
len = rkey->type_data.x[0];
data = rkey->payload.data; data = rkey->payload.data;
} else { } else {
cERROR(1, ("%s: unable to resolve: %s", __func__, name)); cERROR(1, ("%s: unable to resolve: %s", __func__, name));
...@@ -148,11 +158,9 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) ...@@ -148,11 +158,9 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
skip_upcall: skip_upcall:
if (data) { if (data) {
len = strlen(data); *ip_addr = kmalloc(len + 1, GFP_KERNEL);
*ip_addr = kmalloc(len+1, GFP_KERNEL);
if (*ip_addr) { if (*ip_addr) {
memcpy(*ip_addr, data, len); memcpy(*ip_addr, data, len + 1);
(*ip_addr)[len] = '\0';
if (!IS_ERR(rkey)) if (!IS_ERR(rkey))
cFYI(1, ("%s: resolved: %s to %s", __func__, cFYI(1, ("%s: resolved: %s to %s", __func__,
name, name,
......
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