summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-09-23 18:46:07 +0000
committerSteve French <sfrench@us.ibm.com>2008-09-23 18:46:07 +0000
commit9d81523480c8c5b07a4899a084b3f4264a575184 (patch)
treea404c0a8c6f88dfef828f0b3be9177097860bde5 /fs/cifs
parentee2fd967fb23c5eecabc8a660ec66fcd79acbd47 (diff)
[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: Jeff Layton <jlayton@redhat.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/dns_resolve.c74
1 files changed, 41 insertions, 33 deletions
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index a2e0673e1b0..1e0c1bd8f2e 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -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;
@@ -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);
+ *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,