Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+41 −33
Original line number Diff line number Diff line
@@ -29,7 +29,36 @@
#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;
@@ -42,6 +71,13 @@ static int dns_resolver_instantiate(struct key *key, const void *data,
	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;
@@ -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
@@ -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));
@@ -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);
		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,