LCOV - code coverage report
Current view: top level - security/keys - user_defined.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 5 56 8.9 %
Date: 2014-02-18 Functions: 2 8 25.0 %
Branches: 2 32 6.2 %

           Branch data     Line data    Source code
       1                 :            : /* user_defined.c: user defined key type
       2                 :            :  *
       3                 :            :  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
       4                 :            :  * Written by David Howells (dhowells@redhat.com)
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or
       7                 :            :  * modify it under the terms of the GNU General Public License
       8                 :            :  * as published by the Free Software Foundation; either version
       9                 :            :  * 2 of the License, or (at your option) any later version.
      10                 :            :  */
      11                 :            : 
      12                 :            : #include <linux/module.h>
      13                 :            : #include <linux/init.h>
      14                 :            : #include <linux/slab.h>
      15                 :            : #include <linux/seq_file.h>
      16                 :            : #include <linux/err.h>
      17                 :            : #include <keys/user-type.h>
      18                 :            : #include <asm/uaccess.h>
      19                 :            : #include "internal.h"
      20                 :            : 
      21                 :            : static int logon_vet_description(const char *desc);
      22                 :            : 
      23                 :            : /*
      24                 :            :  * user defined keys take an arbitrary string as the description and an
      25                 :            :  * arbitrary blob of data as the payload
      26                 :            :  */
      27                 :            : struct key_type key_type_user = {
      28                 :            :         .name                   = "user",
      29                 :            :         .def_lookup_type        = KEYRING_SEARCH_LOOKUP_DIRECT,
      30                 :            :         .instantiate            = user_instantiate,
      31                 :            :         .update                 = user_update,
      32                 :            :         .match                  = user_match,
      33                 :            :         .revoke                 = user_revoke,
      34                 :            :         .destroy                = user_destroy,
      35                 :            :         .describe               = user_describe,
      36                 :            :         .read                   = user_read,
      37                 :            : };
      38                 :            : 
      39                 :            : EXPORT_SYMBOL_GPL(key_type_user);
      40                 :            : 
      41                 :            : /*
      42                 :            :  * This key type is essentially the same as key_type_user, but it does
      43                 :            :  * not define a .read op. This is suitable for storing username and
      44                 :            :  * password pairs in the keyring that you do not want to be readable
      45                 :            :  * from userspace.
      46                 :            :  */
      47                 :            : struct key_type key_type_logon = {
      48                 :            :         .name                   = "logon",
      49                 :            :         .def_lookup_type        = KEYRING_SEARCH_LOOKUP_DIRECT,
      50                 :            :         .instantiate            = user_instantiate,
      51                 :            :         .update                 = user_update,
      52                 :            :         .match                  = user_match,
      53                 :            :         .revoke                 = user_revoke,
      54                 :            :         .destroy                = user_destroy,
      55                 :            :         .describe               = user_describe,
      56                 :            :         .vet_description        = logon_vet_description,
      57                 :            : };
      58                 :            : EXPORT_SYMBOL_GPL(key_type_logon);
      59                 :            : 
      60                 :            : /*
      61                 :            :  * instantiate a user defined key
      62                 :            :  */
      63                 :          0 : int user_instantiate(struct key *key, struct key_preparsed_payload *prep)
      64                 :            : {
      65                 :            :         struct user_key_payload *upayload;
      66                 :          1 :         size_t datalen = prep->datalen;
      67                 :            :         int ret;
      68                 :            : 
      69                 :            :         ret = -EINVAL;
      70 [ +  - ][ -  + ]:          1 :         if (datalen <= 0 || datalen > 32767 || !prep->data)
      71                 :            :                 goto error;
      72                 :            : 
      73                 :          0 :         ret = key_payload_reserve(key, datalen);
      74         [ #  # ]:          0 :         if (ret < 0)
      75                 :            :                 goto error;
      76                 :            : 
      77                 :            :         ret = -ENOMEM;
      78                 :          0 :         upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
      79         [ #  # ]:          0 :         if (!upayload)
      80                 :            :                 goto error;
      81                 :            : 
      82                 :            :         /* attach the data */
      83                 :          0 :         upayload->datalen = datalen;
      84                 :          0 :         memcpy(upayload->data, prep->data, datalen);
      85                 :          0 :         rcu_assign_keypointer(key, upayload);
      86                 :            :         ret = 0;
      87                 :            : 
      88                 :            : error:
      89                 :          0 :         return ret;
      90                 :            : }
      91                 :            : 
      92                 :            : EXPORT_SYMBOL_GPL(user_instantiate);
      93                 :            : 
      94                 :            : /*
      95                 :            :  * update a user defined key
      96                 :            :  * - the key's semaphore is write-locked
      97                 :            :  */
      98                 :          0 : int user_update(struct key *key, struct key_preparsed_payload *prep)
      99                 :            : {
     100                 :            :         struct user_key_payload *upayload, *zap;
     101                 :          0 :         size_t datalen = prep->datalen;
     102                 :            :         int ret;
     103                 :            : 
     104                 :            :         ret = -EINVAL;
     105 [ #  # ][ #  # ]:          0 :         if (datalen <= 0 || datalen > 32767 || !prep->data)
     106                 :            :                 goto error;
     107                 :            : 
     108                 :            :         /* construct a replacement payload */
     109                 :            :         ret = -ENOMEM;
     110                 :          0 :         upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
     111         [ #  # ]:          0 :         if (!upayload)
     112                 :            :                 goto error;
     113                 :            : 
     114                 :          0 :         upayload->datalen = datalen;
     115                 :          0 :         memcpy(upayload->data, prep->data, datalen);
     116                 :            : 
     117                 :            :         /* check the quota and attach the new data */
     118                 :            :         zap = upayload;
     119                 :            : 
     120                 :          0 :         ret = key_payload_reserve(key, datalen);
     121                 :            : 
     122         [ #  # ]:          0 :         if (ret == 0) {
     123                 :            :                 /* attach the new data, displacing the old */
     124                 :          0 :                 zap = key->payload.data;
     125                 :          0 :                 rcu_assign_keypointer(key, upayload);
     126                 :          0 :                 key->expiry = 0;
     127                 :            :         }
     128                 :            : 
     129         [ #  # ]:          0 :         if (zap)
     130                 :          0 :                 kfree_rcu(zap, rcu);
     131                 :            : 
     132                 :            : error:
     133                 :          0 :         return ret;
     134                 :            : }
     135                 :            : 
     136                 :            : EXPORT_SYMBOL_GPL(user_update);
     137                 :            : 
     138                 :            : /*
     139                 :            :  * match users on their name
     140                 :            :  */
     141                 :          0 : int user_match(const struct key *key, const void *description)
     142                 :            : {
     143                 :          0 :         return strcmp(key->description, description) == 0;
     144                 :            : }
     145                 :            : 
     146                 :            : EXPORT_SYMBOL_GPL(user_match);
     147                 :            : 
     148                 :            : /*
     149                 :            :  * dispose of the links from a revoked keyring
     150                 :            :  * - called with the key sem write-locked
     151                 :            :  */
     152                 :          0 : void user_revoke(struct key *key)
     153                 :            : {
     154                 :          0 :         struct user_key_payload *upayload = key->payload.data;
     155                 :            : 
     156                 :            :         /* clear the quota */
     157                 :          0 :         key_payload_reserve(key, 0);
     158                 :            : 
     159         [ #  # ]:          0 :         if (upayload) {
     160                 :          0 :                 rcu_assign_keypointer(key, NULL);
     161                 :          0 :                 kfree_rcu(upayload, rcu);
     162                 :            :         }
     163                 :          0 : }
     164                 :            : 
     165                 :            : EXPORT_SYMBOL(user_revoke);
     166                 :            : 
     167                 :            : /*
     168                 :            :  * dispose of the data dangling from the corpse of a user key
     169                 :            :  */
     170                 :          0 : void user_destroy(struct key *key)
     171                 :            : {
     172                 :          1 :         struct user_key_payload *upayload = key->payload.data;
     173                 :            : 
     174                 :          1 :         kfree(upayload);
     175                 :          1 : }
     176                 :            : 
     177                 :            : EXPORT_SYMBOL_GPL(user_destroy);
     178                 :            : 
     179                 :            : /*
     180                 :            :  * describe the user key
     181                 :            :  */
     182                 :          0 : void user_describe(const struct key *key, struct seq_file *m)
     183                 :            : {
     184                 :          0 :         seq_puts(m, key->description);
     185         [ #  # ]:          0 :         if (key_is_instantiated(key))
     186                 :          0 :                 seq_printf(m, ": %u", key->datalen);
     187                 :          0 : }
     188                 :            : 
     189                 :            : EXPORT_SYMBOL_GPL(user_describe);
     190                 :            : 
     191                 :            : /*
     192                 :            :  * read the key data
     193                 :            :  * - the key's semaphore is read-locked
     194                 :            :  */
     195                 :          0 : long user_read(const struct key *key, char __user *buffer, size_t buflen)
     196                 :            : {
     197                 :            :         struct user_key_payload *upayload;
     198                 :            :         long ret;
     199                 :            : 
     200                 :          0 :         upayload = rcu_dereference_key(key);
     201                 :          0 :         ret = upayload->datalen;
     202                 :            : 
     203                 :            :         /* we can return the data as is */
     204         [ #  # ]:          0 :         if (buffer && buflen > 0) {
     205         [ #  # ]:          0 :                 if (buflen > upayload->datalen)
     206                 :            :                         buflen = upayload->datalen;
     207                 :            : 
     208         [ #  # ]:          0 :                 if (copy_to_user(buffer, upayload->data, buflen) != 0)
     209                 :            :                         ret = -EFAULT;
     210                 :            :         }
     211                 :            : 
     212                 :          0 :         return ret;
     213                 :            : }
     214                 :            : 
     215                 :            : EXPORT_SYMBOL_GPL(user_read);
     216                 :            : 
     217                 :            : /* Vet the description for a "logon" key */
     218                 :          0 : static int logon_vet_description(const char *desc)
     219                 :            : {
     220                 :            :         char *p;
     221                 :            : 
     222                 :            :         /* require a "qualified" description string */
     223                 :          0 :         p = strchr(desc, ':');
     224         [ #  # ]:          0 :         if (!p)
     225                 :            :                 return -EINVAL;
     226                 :            : 
     227                 :            :         /* also reject description with ':' as first char */
     228         [ #  # ]:          0 :         if (p == desc)
     229                 :            :                 return -EINVAL;
     230                 :            : 
     231                 :          0 :         return 0;
     232                 :            : }

Generated by: LCOV version 1.9