LCOV - code coverage report
Current view: top level - net/dns_resolver - dns_query.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 44 0.0 %
Date: 2014-04-16 Functions: 0 1 0.0 %
Branches: 0 34 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* Upcall routine, designed to work as a key type and working through
       2                 :            :  * /sbin/request-key to contact userspace when handling DNS queries.
       3                 :            :  *
       4                 :            :  * See Documentation/networking/dns_resolver.txt
       5                 :            :  *
       6                 :            :  *   Copyright (c) 2007 Igor Mammedov
       7                 :            :  *   Author(s): Igor Mammedov (niallain@gmail.com)
       8                 :            :  *              Steve French (sfrench@us.ibm.com)
       9                 :            :  *              Wang Lei (wang840925@gmail.com)
      10                 :            :  *              David Howells (dhowells@redhat.com)
      11                 :            :  *
      12                 :            :  *   The upcall wrapper used to make an arbitrary DNS query.
      13                 :            :  *
      14                 :            :  *   This function requires the appropriate userspace tool dns.upcall to be
      15                 :            :  *   installed and something like the following lines should be added to the
      16                 :            :  *   /etc/request-key.conf file:
      17                 :            :  *
      18                 :            :  *      create dns_resolver * * /sbin/dns.upcall %k
      19                 :            :  *
      20                 :            :  *   For example to use this module to query AFSDB RR:
      21                 :            :  *
      22                 :            :  *      create dns_resolver afsdb:* * /sbin/dns.afsdb %k
      23                 :            :  *
      24                 :            :  *   This library is free software; you can redistribute it and/or modify
      25                 :            :  *   it under the terms of the GNU Lesser General Public License as published
      26                 :            :  *   by the Free Software Foundation; either version 2.1 of the License, or
      27                 :            :  *   (at your option) any later version.
      28                 :            :  *
      29                 :            :  *   This library is distributed in the hope that it will be useful,
      30                 :            :  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
      31                 :            :  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
      32                 :            :  *   the GNU Lesser General Public License for more details.
      33                 :            :  *
      34                 :            :  *   You should have received a copy of the GNU Lesser General Public License
      35                 :            :  *   along with this library; if not, see <http://www.gnu.org/licenses/>.
      36                 :            :  */
      37                 :            : 
      38                 :            : #include <linux/module.h>
      39                 :            : #include <linux/slab.h>
      40                 :            : #include <linux/dns_resolver.h>
      41                 :            : #include <linux/err.h>
      42                 :            : #include <keys/dns_resolver-type.h>
      43                 :            : #include <keys/user-type.h>
      44                 :            : 
      45                 :            : #include "internal.h"
      46                 :            : 
      47                 :            : /**
      48                 :            :  * dns_query - Query the DNS
      49                 :            :  * @type: Query type (or NULL for straight host->IP lookup)
      50                 :            :  * @name: Name to look up
      51                 :            :  * @namelen: Length of name
      52                 :            :  * @options: Request options (or NULL if no options)
      53                 :            :  * @_result: Where to place the returned data.
      54                 :            :  * @_expiry: Where to store the result expiry time (or NULL)
      55                 :            :  *
      56                 :            :  * The data will be returned in the pointer at *result, and the caller is
      57                 :            :  * responsible for freeing it.
      58                 :            :  *
      59                 :            :  * The description should be of the form "[<query_type>:]<domain_name>", and
      60                 :            :  * the options need to be appropriate for the query type requested.  If no
      61                 :            :  * query_type is given, then the query is a straight hostname to IP address
      62                 :            :  * lookup.
      63                 :            :  *
      64                 :            :  * The DNS resolution lookup is performed by upcalling to userspace by way of
      65                 :            :  * requesting a key of type dns_resolver.
      66                 :            :  *
      67                 :            :  * Returns the size of the result on success, -ve error code otherwise.
      68                 :            :  */
      69                 :          0 : int dns_query(const char *type, const char *name, size_t namelen,
      70                 :            :               const char *options, char **_result, time_t *_expiry)
      71                 :            : {
      72                 :            :         struct key *rkey;
      73                 :            :         struct user_key_payload *upayload;
      74                 :            :         const struct cred *saved_cred;
      75                 :            :         size_t typelen, desclen;
      76                 :            :         char *desc, *cp;
      77                 :            :         int ret, len;
      78                 :            : 
      79         [ #  # ]:          0 :         kenter("%s,%*.*s,%zu,%s",
      80                 :            :                type, (int)namelen, (int)namelen, name, namelen, options);
      81                 :            : 
      82 [ #  # ][ #  # ]:          0 :         if (!name || namelen == 0 || !_result)
      83                 :            :                 return -EINVAL;
      84                 :            : 
      85                 :            :         /* construct the query key description as "[<type>:]<name>" */
      86                 :            :         typelen = 0;
      87                 :            :         desclen = 0;
      88         [ #  # ]:          0 :         if (type) {
      89                 :          0 :                 typelen = strlen(type);
      90         [ #  # ]:          0 :                 if (typelen < 1)
      91                 :            :                         return -EINVAL;
      92                 :          0 :                 desclen += typelen + 1;
      93                 :            :         }
      94                 :            : 
      95         [ #  # ]:          0 :         if (!namelen)
      96                 :          0 :                 namelen = strlen(name);
      97         [ #  # ]:          0 :         if (namelen < 3)
      98                 :            :                 return -EINVAL;
      99                 :          0 :         desclen += namelen + 1;
     100                 :            : 
     101                 :            :         desc = kmalloc(desclen, GFP_KERNEL);
     102         [ #  # ]:          0 :         if (!desc)
     103                 :            :                 return -ENOMEM;
     104                 :            : 
     105                 :            :         cp = desc;
     106         [ #  # ]:          0 :         if (type) {
     107                 :          0 :                 memcpy(cp, type, typelen);
     108                 :          0 :                 cp += typelen;
     109                 :          0 :                 *cp++ = ':';
     110                 :            :         }
     111                 :          0 :         memcpy(cp, name, namelen);
     112                 :          0 :         cp += namelen;
     113                 :          0 :         *cp = '\0';
     114                 :            : 
     115         [ #  # ]:          0 :         if (!options)
     116                 :            :                 options = "";
     117         [ #  # ]:          0 :         kdebug("call request_key(,%s,%s)", desc, options);
     118                 :            : 
     119                 :            :         /* make the upcall, using special credentials to prevent the use of
     120                 :            :          * add_key() to preinstall malicious redirections
     121                 :            :          */
     122                 :          0 :         saved_cred = override_creds(dns_resolver_cache);
     123                 :          0 :         rkey = request_key(&key_type_dns_resolver, desc, options);
     124                 :          0 :         revert_creds(saved_cred);
     125                 :          0 :         kfree(desc);
     126         [ #  # ]:          0 :         if (IS_ERR(rkey)) {
     127                 :            :                 ret = PTR_ERR(rkey);
     128                 :          0 :                 goto out;
     129                 :            :         }
     130                 :            : 
     131                 :          0 :         down_read(&rkey->sem);
     132                 :          0 :         rkey->perm |= KEY_USR_VIEW;
     133                 :            : 
     134                 :          0 :         ret = key_validate(rkey);
     135         [ #  # ]:          0 :         if (ret < 0)
     136                 :            :                 goto put;
     137                 :            : 
     138                 :            :         /* If the DNS server gave an error, return that to the caller */
     139                 :          0 :         ret = rkey->type_data.x[0];
     140         [ #  # ]:          0 :         if (ret)
     141                 :            :                 goto put;
     142                 :            : 
     143                 :          0 :         upayload = rcu_dereference_protected(rkey->payload.data,
     144                 :            :                                              lockdep_is_held(&rkey->sem));
     145                 :          0 :         len = upayload->datalen;
     146                 :            : 
     147                 :            :         ret = -ENOMEM;
     148                 :          0 :         *_result = kmalloc(len + 1, GFP_KERNEL);
     149         [ #  # ]:          0 :         if (!*_result)
     150                 :            :                 goto put;
     151                 :            : 
     152                 :          0 :         memcpy(*_result, upayload->data, len + 1);
     153         [ #  # ]:          0 :         if (_expiry)
     154                 :          0 :                 *_expiry = rkey->expiry;
     155                 :            : 
     156                 :            :         ret = len;
     157                 :            : put:
     158                 :          0 :         up_read(&rkey->sem);
     159                 :          0 :         key_put(rkey);
     160                 :            : out:
     161         [ #  # ]:          0 :         kleave(" = %d", ret);
     162                 :          0 :         return ret;
     163                 :            : }
     164                 :            : EXPORT_SYMBOL(dns_query);

Generated by: LCOV version 1.9