linux/security/integrity/ima/ima_appraise.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 IBM Corporation
   3 *
   4 * Author:
   5 * Mimi Zohar <zohar@us.ibm.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation, version 2 of the License.
  10 */
  11#include <linux/module.h>
  12#include <linux/file.h>
  13#include <linux/fs.h>
  14#include <linux/xattr.h>
  15#include <linux/magic.h>
  16#include <linux/ima.h>
  17#include <linux/evm.h>
  18
  19#include "ima.h"
  20
  21static int __init default_appraise_setup(char *str)
  22{
  23        if (strncmp(str, "off", 3) == 0)
  24                ima_appraise = 0;
  25        else if (strncmp(str, "log", 3) == 0)
  26                ima_appraise = IMA_APPRAISE_LOG;
  27        else if (strncmp(str, "fix", 3) == 0)
  28                ima_appraise = IMA_APPRAISE_FIX;
  29        return 1;
  30}
  31
  32__setup("ima_appraise=", default_appraise_setup);
  33
  34/*
  35 * ima_must_appraise - set appraise flag
  36 *
  37 * Return 1 to appraise
  38 */
  39int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
  40{
  41        if (!ima_appraise)
  42                return 0;
  43
  44        return ima_match_policy(inode, func, mask, IMA_APPRAISE);
  45}
  46
  47static int ima_fix_xattr(struct dentry *dentry,
  48                         struct integrity_iint_cache *iint)
  49{
  50        int rc, offset;
  51        u8 algo = iint->ima_hash->algo;
  52
  53        if (algo <= HASH_ALGO_SHA1) {
  54                offset = 1;
  55                iint->ima_hash->xattr.sha1.type = IMA_XATTR_DIGEST;
  56        } else {
  57                offset = 0;
  58                iint->ima_hash->xattr.ng.type = IMA_XATTR_DIGEST_NG;
  59                iint->ima_hash->xattr.ng.algo = algo;
  60        }
  61        rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
  62                                   &iint->ima_hash->xattr.data[offset],
  63                                   (sizeof(iint->ima_hash->xattr) - offset) +
  64                                   iint->ima_hash->length, 0);
  65        return rc;
  66}
  67
  68/* Return specific func appraised cached result */
  69enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
  70                                           enum ima_hooks func)
  71{
  72        switch (func) {
  73        case MMAP_CHECK:
  74                return iint->ima_mmap_status;
  75        case BPRM_CHECK:
  76                return iint->ima_bprm_status;
  77        case FILE_CHECK:
  78        case POST_SETATTR:
  79                return iint->ima_file_status;
  80        case MODULE_CHECK ... MAX_CHECK - 1:
  81        default:
  82                return iint->ima_read_status;
  83        }
  84}
  85
  86static void ima_set_cache_status(struct integrity_iint_cache *iint,
  87                                 enum ima_hooks func,
  88                                 enum integrity_status status)
  89{
  90        switch (func) {
  91        case MMAP_CHECK:
  92                iint->ima_mmap_status = status;
  93                break;
  94        case BPRM_CHECK:
  95                iint->ima_bprm_status = status;
  96                break;
  97        case FILE_CHECK:
  98        case POST_SETATTR:
  99                iint->ima_file_status = status;
 100                break;
 101        case MODULE_CHECK ... MAX_CHECK - 1:
 102        default:
 103                iint->ima_read_status = status;
 104                break;
 105        }
 106}
 107
 108static void ima_cache_flags(struct integrity_iint_cache *iint,
 109                             enum ima_hooks func)
 110{
 111        switch (func) {
 112        case MMAP_CHECK:
 113                iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED);
 114                break;
 115        case BPRM_CHECK:
 116                iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
 117                break;
 118        case FILE_CHECK:
 119        case POST_SETATTR:
 120                iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
 121                break;
 122        case MODULE_CHECK ... MAX_CHECK - 1:
 123        default:
 124                iint->flags |= (IMA_READ_APPRAISED | IMA_APPRAISED);
 125                break;
 126        }
 127}
 128
 129enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
 130                                 int xattr_len)
 131{
 132        struct signature_v2_hdr *sig;
 133
 134        if (!xattr_value || xattr_len < 2)
 135                /* return default hash algo */
 136                return ima_hash_algo;
 137
 138        switch (xattr_value->type) {
 139        case EVM_IMA_XATTR_DIGSIG:
 140                sig = (typeof(sig))xattr_value;
 141                if (sig->version != 2 || xattr_len <= sizeof(*sig))
 142                        return ima_hash_algo;
 143                return sig->hash_algo;
 144                break;
 145        case IMA_XATTR_DIGEST_NG:
 146                return xattr_value->digest[0];
 147                break;
 148        case IMA_XATTR_DIGEST:
 149                /* this is for backward compatibility */
 150                if (xattr_len == 21) {
 151                        unsigned int zero = 0;
 152                        if (!memcmp(&xattr_value->digest[16], &zero, 4))
 153                                return HASH_ALGO_MD5;
 154                        else
 155                                return HASH_ALGO_SHA1;
 156                } else if (xattr_len == 17)
 157                        return HASH_ALGO_MD5;
 158                break;
 159        }
 160
 161        /* return default hash algo */
 162        return ima_hash_algo;
 163}
 164
 165int ima_read_xattr(struct dentry *dentry,
 166                   struct evm_ima_xattr_data **xattr_value)
 167{
 168        struct inode *inode = d_backing_inode(dentry);
 169
 170        if (!inode->i_op->getxattr)
 171                return 0;
 172
 173        return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
 174                                  0, GFP_NOFS);
 175}
 176
 177/*
 178 * ima_appraise_measurement - appraise file measurement
 179 *
 180 * Call evm_verifyxattr() to verify the integrity of 'security.ima'.
 181 * Assuming success, compare the xattr hash with the collected measurement.
 182 *
 183 * Return 0 on success, error code otherwise
 184 */
 185int ima_appraise_measurement(enum ima_hooks func,
 186                             struct integrity_iint_cache *iint,
 187                             struct file *file, const unsigned char *filename,
 188                             struct evm_ima_xattr_data *xattr_value,
 189                             int xattr_len, int opened)
 190{
 191        static const char op[] = "appraise_data";
 192        char *cause = "unknown";
 193        struct dentry *dentry = file->f_path.dentry;
 194        struct inode *inode = d_backing_inode(dentry);
 195        enum integrity_status status = INTEGRITY_UNKNOWN;
 196        int rc = xattr_len, hash_start = 0;
 197
 198        if (!inode->i_op->getxattr)
 199                return INTEGRITY_UNKNOWN;
 200
 201        if (rc <= 0) {
 202                if (rc && rc != -ENODATA)
 203                        goto out;
 204
 205                cause = "missing-hash";
 206                status = INTEGRITY_NOLABEL;
 207                if (opened & FILE_CREATED) {
 208                        iint->flags |= IMA_NEW_FILE;
 209                        status = INTEGRITY_PASS;
 210                }
 211                goto out;
 212        }
 213
 214        status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint);
 215        if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) {
 216                if ((status == INTEGRITY_NOLABEL)
 217                    || (status == INTEGRITY_NOXATTRS))
 218                        cause = "missing-HMAC";
 219                else if (status == INTEGRITY_FAIL)
 220                        cause = "invalid-HMAC";
 221                goto out;
 222        }
 223        switch (xattr_value->type) {
 224        case IMA_XATTR_DIGEST_NG:
 225                /* first byte contains algorithm id */
 226                hash_start = 1;
 227        case IMA_XATTR_DIGEST:
 228                if (iint->flags & IMA_DIGSIG_REQUIRED) {
 229                        cause = "IMA-signature-required";
 230                        status = INTEGRITY_FAIL;
 231                        break;
 232                }
 233                if (xattr_len - sizeof(xattr_value->type) - hash_start >=
 234                                iint->ima_hash->length)
 235                        /* xattr length may be longer. md5 hash in previous
 236                           version occupied 20 bytes in xattr, instead of 16
 237                         */
 238                        rc = memcmp(&xattr_value->digest[hash_start],
 239                                    iint->ima_hash->digest,
 240                                    iint->ima_hash->length);
 241                else
 242                        rc = -EINVAL;
 243                if (rc) {
 244                        cause = "invalid-hash";
 245                        status = INTEGRITY_FAIL;
 246                        break;
 247                }
 248                status = INTEGRITY_PASS;
 249                break;
 250        case EVM_IMA_XATTR_DIGSIG:
 251                iint->flags |= IMA_DIGSIG;
 252                rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
 253                                             (const char *)xattr_value, rc,
 254                                             iint->ima_hash->digest,
 255                                             iint->ima_hash->length);
 256                if (rc == -EOPNOTSUPP) {
 257                        status = INTEGRITY_UNKNOWN;
 258                } else if (rc) {
 259                        cause = "invalid-signature";
 260                        status = INTEGRITY_FAIL;
 261                } else {
 262                        status = INTEGRITY_PASS;
 263                }
 264                break;
 265        default:
 266                status = INTEGRITY_UNKNOWN;
 267                cause = "unknown-ima-data";
 268                break;
 269        }
 270
 271out:
 272        if (status != INTEGRITY_PASS) {
 273                if ((ima_appraise & IMA_APPRAISE_FIX) &&
 274                    (!xattr_value ||
 275                     xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
 276                        if (!ima_fix_xattr(dentry, iint))
 277                                status = INTEGRITY_PASS;
 278                }
 279                integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
 280                                    op, cause, rc, 0);
 281        } else {
 282                ima_cache_flags(iint, func);
 283        }
 284        ima_set_cache_status(iint, func, status);
 285        return status;
 286}
 287
 288/*
 289 * ima_update_xattr - update 'security.ima' hash value
 290 */
 291void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
 292{
 293        struct dentry *dentry = file->f_path.dentry;
 294        int rc = 0;
 295
 296        /* do not collect and update hash for digital signatures */
 297        if (iint->flags & IMA_DIGSIG)
 298                return;
 299
 300        rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo);
 301        if (rc < 0)
 302                return;
 303
 304        ima_fix_xattr(dentry, iint);
 305}
 306
 307/**
 308 * ima_inode_post_setattr - reflect file metadata changes
 309 * @dentry: pointer to the affected dentry
 310 *
 311 * Changes to a dentry's metadata might result in needing to appraise.
 312 *
 313 * This function is called from notify_change(), which expects the caller
 314 * to lock the inode's i_mutex.
 315 */
 316void ima_inode_post_setattr(struct dentry *dentry)
 317{
 318        struct inode *inode = d_backing_inode(dentry);
 319        struct integrity_iint_cache *iint;
 320        int must_appraise, rc;
 321
 322        if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode)
 323            || !inode->i_op->removexattr)
 324                return;
 325
 326        must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
 327        iint = integrity_iint_find(inode);
 328        if (iint) {
 329                iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
 330                                 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
 331                                 IMA_ACTION_FLAGS);
 332                if (must_appraise)
 333                        iint->flags |= IMA_APPRAISE;
 334        }
 335        if (!must_appraise)
 336                rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);
 337        return;
 338}
 339
 340/*
 341 * ima_protect_xattr - protect 'security.ima'
 342 *
 343 * Ensure that not just anyone can modify or remove 'security.ima'.
 344 */
 345static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
 346                             const void *xattr_value, size_t xattr_value_len)
 347{
 348        if (strcmp(xattr_name, XATTR_NAME_IMA) == 0) {
 349                if (!capable(CAP_SYS_ADMIN))
 350                        return -EPERM;
 351                return 1;
 352        }
 353        return 0;
 354}
 355
 356static void ima_reset_appraise_flags(struct inode *inode, int digsig)
 357{
 358        struct integrity_iint_cache *iint;
 359
 360        if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode))
 361                return;
 362
 363        iint = integrity_iint_find(inode);
 364        if (!iint)
 365                return;
 366
 367        iint->flags &= ~IMA_DONE_MASK;
 368        if (digsig)
 369                iint->flags |= IMA_DIGSIG;
 370        return;
 371}
 372
 373int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 374                       const void *xattr_value, size_t xattr_value_len)
 375{
 376        const struct evm_ima_xattr_data *xvalue = xattr_value;
 377        int result;
 378
 379        result = ima_protect_xattr(dentry, xattr_name, xattr_value,
 380                                   xattr_value_len);
 381        if (result == 1) {
 382                bool digsig;
 383
 384                if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
 385                        return -EINVAL;
 386                digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
 387                if (!digsig && (ima_appraise & IMA_APPRAISE_ENFORCE))
 388                        return -EPERM;
 389                ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
 390                result = 0;
 391        }
 392        return result;
 393}
 394
 395int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
 396{
 397        int result;
 398
 399        result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
 400        if (result == 1) {
 401                ima_reset_appraise_flags(d_backing_inode(dentry), 0);
 402                result = 0;
 403        }
 404        return result;
 405}
 406