| .. | .. |
|---|
| 1 | 1 | /* Upcall routine, designed to work as a key type and working through |
|---|
| 2 | 2 | * /sbin/request-key to contact userspace when handling DNS queries. |
|---|
| 3 | 3 | * |
|---|
| 4 | | - * See Documentation/networking/dns_resolver.txt |
|---|
| 4 | + * See Documentation/networking/dns_resolver.rst |
|---|
| 5 | 5 | * |
|---|
| 6 | 6 | * Copyright (c) 2007 Igor Mammedov |
|---|
| 7 | 7 | * Author(s): Igor Mammedov (niallain@gmail.com) |
|---|
| .. | .. |
|---|
| 40 | 40 | #include <linux/cred.h> |
|---|
| 41 | 41 | #include <linux/dns_resolver.h> |
|---|
| 42 | 42 | #include <linux/err.h> |
|---|
| 43 | +#include <net/net_namespace.h> |
|---|
| 43 | 44 | |
|---|
| 44 | 45 | #include <keys/dns_resolver-type.h> |
|---|
| 45 | 46 | #include <keys/user-type.h> |
|---|
| .. | .. |
|---|
| 48 | 49 | |
|---|
| 49 | 50 | /** |
|---|
| 50 | 51 | * dns_query - Query the DNS |
|---|
| 52 | + * @net: The network namespace to operate in. |
|---|
| 51 | 53 | * @type: Query type (or NULL for straight host->IP lookup) |
|---|
| 52 | 54 | * @name: Name to look up |
|---|
| 53 | 55 | * @namelen: Length of name |
|---|
| 54 | 56 | * @options: Request options (or NULL if no options) |
|---|
| 55 | 57 | * @_result: Where to place the returned data (or NULL) |
|---|
| 56 | 58 | * @_expiry: Where to store the result expiry time (or NULL) |
|---|
| 59 | + * @invalidate: Always invalidate the key after use |
|---|
| 57 | 60 | * |
|---|
| 58 | 61 | * The data will be returned in the pointer at *result, if provided, and the |
|---|
| 59 | 62 | * caller is responsible for freeing it. |
|---|
| .. | .. |
|---|
| 68 | 71 | * |
|---|
| 69 | 72 | * Returns the size of the result on success, -ve error code otherwise. |
|---|
| 70 | 73 | */ |
|---|
| 71 | | -int dns_query(const char *type, const char *name, size_t namelen, |
|---|
| 72 | | - const char *options, char **_result, time64_t *_expiry) |
|---|
| 74 | +int dns_query(struct net *net, |
|---|
| 75 | + const char *type, const char *name, size_t namelen, |
|---|
| 76 | + const char *options, char **_result, time64_t *_expiry, |
|---|
| 77 | + bool invalidate) |
|---|
| 73 | 78 | { |
|---|
| 74 | 79 | struct key *rkey; |
|---|
| 75 | 80 | struct user_key_payload *upayload; |
|---|
| .. | .. |
|---|
| 94 | 99 | desclen += typelen + 1; |
|---|
| 95 | 100 | } |
|---|
| 96 | 101 | |
|---|
| 97 | | - if (!namelen) |
|---|
| 98 | | - namelen = strnlen(name, 256); |
|---|
| 99 | 102 | if (namelen < 3 || namelen > 255) |
|---|
| 100 | 103 | return -EINVAL; |
|---|
| 101 | 104 | desclen += namelen + 1; |
|---|
| .. | .. |
|---|
| 122 | 125 | * add_key() to preinstall malicious redirections |
|---|
| 123 | 126 | */ |
|---|
| 124 | 127 | saved_cred = override_creds(dns_resolver_cache); |
|---|
| 125 | | - rkey = request_key(&key_type_dns_resolver, desc, options); |
|---|
| 128 | + rkey = request_key_net(&key_type_dns_resolver, desc, net, options); |
|---|
| 126 | 129 | revert_creds(saved_cred); |
|---|
| 127 | 130 | kfree(desc); |
|---|
| 128 | 131 | if (IS_ERR(rkey)) { |
|---|
| .. | .. |
|---|
| 148 | 151 | |
|---|
| 149 | 152 | if (_result) { |
|---|
| 150 | 153 | ret = -ENOMEM; |
|---|
| 151 | | - *_result = kmalloc(len + 1, GFP_KERNEL); |
|---|
| 154 | + *_result = kmemdup_nul(upayload->data, len, GFP_KERNEL); |
|---|
| 152 | 155 | if (!*_result) |
|---|
| 153 | 156 | goto put; |
|---|
| 154 | | - |
|---|
| 155 | | - memcpy(*_result, upayload->data, len); |
|---|
| 156 | | - (*_result)[len] = '\0'; |
|---|
| 157 | 157 | } |
|---|
| 158 | 158 | |
|---|
| 159 | 159 | if (_expiry) |
|---|
| .. | .. |
|---|
| 162 | 162 | ret = len; |
|---|
| 163 | 163 | put: |
|---|
| 164 | 164 | up_read(&rkey->sem); |
|---|
| 165 | + if (invalidate) |
|---|
| 166 | + key_invalidate(rkey); |
|---|
| 165 | 167 | key_put(rkey); |
|---|
| 166 | 168 | out: |
|---|
| 167 | 169 | kleave(" = %d", ret); |
|---|