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-07 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, write to the Free Software
      36                 :            :  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
      37                 :            :  */
      38                 :            : 
      39                 :            : #include <linux/module.h>
      40                 :            : #include <linux/slab.h>
      41                 :            : #include <linux/dns_resolver.h>
      42                 :            : #include <linux/err.h>
      43                 :            : #include <keys/dns_resolver-type.h>
      44                 :            : #include <keys/user-type.h>
      45                 :            : 
      46                 :            : #include "internal.h"
      47                 :            : 
      48                 :            : /**
      49                 :            :  * dns_query - Query the DNS
      50                 :            :  * @type: Query type (or NULL for straight host->IP lookup)
      51                 :            :  * @name: Name to look up
      52                 :            :  * @namelen: Length of name
      53                 :            :  * @options: Request options (or NULL if no options)
      54                 :            :  * @_result: Where to place the returned data.
      55                 :            :  * @_expiry: Where to store the result expiry time (or NULL)
      56                 :            :  *
      57                 :            :  * The data will be returned in the pointer at *result, and the caller is
      58                 :            :  * responsible for freeing it.
      59                 :            :  *
      60                 :            :  * The description should be of the form "[<query_type>:]<domain_name>", and
      61                 :            :  * the options need to be appropriate for the query type requested.  If no
      62                 :            :  * query_type is given, then the query is a straight hostname to IP address
      63                 :            :  * lookup.
      64                 :            :  *
      65                 :            :  * The DNS resolution lookup is performed by upcalling to userspace by way of
      66                 :            :  * requesting a key of type dns_resolver.
      67                 :            :  *
      68                 :            :  * Returns the size of the result on success, -ve error code otherwise.
      69                 :            :  */
      70                 :          0 : int dns_query(const char *type, const char *name, size_t namelen,
      71                 :            :               const char *options, char **_result, time_t *_expiry)
      72                 :            : {
      73                 :            :         struct key *rkey;
      74                 :            :         struct user_key_payload *upayload;
      75                 :            :         const struct cred *saved_cred;
      76                 :            :         size_t typelen, desclen;
      77                 :            :         char *desc, *cp;
      78                 :            :         int ret, len;
      79                 :            : 
      80         [ #  # ]:          0 :         kenter("%s,%*.*s,%zu,%s",
      81                 :            :                type, (int)namelen, (int)namelen, name, namelen, options);
      82                 :            : 
      83 [ #  # ][ #  # ]:          0 :         if (!name || namelen == 0 || !_result)
      84                 :            :                 return -EINVAL;
      85                 :            : 
      86                 :            :         /* construct the query key description as "[<type>:]<name>" */
      87                 :            :         typelen = 0;
      88                 :            :         desclen = 0;
      89         [ #  # ]:          0 :         if (type) {
      90                 :          0 :                 typelen = strlen(type);
      91         [ #  # ]:          0 :                 if (typelen < 1)
      92                 :            :                         return -EINVAL;
      93                 :          0 :                 desclen += typelen + 1;
      94                 :            :         }
      95                 :            : 
      96         [ #  # ]:          0 :         if (!namelen)
      97                 :          0 :                 namelen = strlen(name);
      98         [ #  # ]:          0 :         if (namelen < 3)
      99                 :            :                 return -EINVAL;
     100                 :          0 :         desclen += namelen + 1;
     101                 :            : 
     102                 :            :         desc = kmalloc(desclen, GFP_KERNEL);
     103         [ #  # ]:          0 :         if (!desc)
     104                 :            :                 return -ENOMEM;
     105                 :            : 
     106                 :            :         cp = desc;
     107         [ #  # ]:          0 :         if (type) {
     108                 :          0 :                 memcpy(cp, type, typelen);
     109                 :          0 :                 cp += typelen;
     110                 :          0 :                 *cp++ = ':';
     111                 :            :         }
     112                 :          0 :         memcpy(cp, name, namelen);
     113                 :          0 :         cp += namelen;
     114                 :          0 :         *cp = '\0';
     115                 :            : 
     116         [ #  # ]:          0 :         if (!options)
     117                 :            :                 options = "";
     118         [ #  # ]:          0 :         kdebug("call request_key(,%s,%s)", desc, options);
     119                 :            : 
     120                 :            :         /* make the upcall, using special credentials to prevent the use of
     121                 :            :          * add_key() to preinstall malicious redirections
     122                 :            :          */
     123                 :          0 :         saved_cred = override_creds(dns_resolver_cache);
     124                 :          0 :         rkey = request_key(&key_type_dns_resolver, desc, options);
     125                 :          0 :         revert_creds(saved_cred);
     126                 :          0 :         kfree(desc);
     127         [ #  # ]:          0 :         if (IS_ERR(rkey)) {
     128                 :            :                 ret = PTR_ERR(rkey);
     129                 :          0 :                 goto out;
     130                 :            :         }
     131                 :            : 
     132                 :          0 :         down_read(&rkey->sem);
     133                 :          0 :         rkey->perm |= KEY_USR_VIEW;
     134                 :            : 
     135                 :          0 :         ret = key_validate(rkey);
     136         [ #  # ]:          0 :         if (ret < 0)
     137                 :            :                 goto put;
     138                 :            : 
     139                 :            :         /* If the DNS server gave an error, return that to the caller */
     140                 :          0 :         ret = rkey->type_data.x[0];
     141         [ #  # ]:          0 :         if (ret)
     142                 :            :                 goto put;
     143                 :            : 
     144                 :          0 :         upayload = rcu_dereference_protected(rkey->payload.data,
     145                 :            :                                              lockdep_is_held(&rkey->sem));
     146                 :          0 :         len = upayload->datalen;
     147                 :            : 
     148                 :            :         ret = -ENOMEM;
     149                 :          0 :         *_result = kmalloc(len + 1, GFP_KERNEL);
     150         [ #  # ]:          0 :         if (!*_result)
     151                 :            :                 goto put;
     152                 :            : 
     153                 :          0 :         memcpy(*_result, upayload->data, len + 1);
     154         [ #  # ]:          0 :         if (_expiry)
     155                 :          0 :                 *_expiry = rkey->expiry;
     156                 :            : 
     157                 :            :         ret = len;
     158                 :            : put:
     159                 :          0 :         up_read(&rkey->sem);
     160                 :          0 :         key_put(rkey);
     161                 :            : out:
     162         [ #  # ]:          0 :         kleave(" = %d", ret);
     163                 :          0 :         return ret;
     164                 :            : }
     165                 :            : EXPORT_SYMBOL(dns_query);

Generated by: LCOV version 1.9