2019-06-01 01:08:55 -07:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2011-03-09 12:13:22 -07:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2009-2010 IBM Corporation
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Mimi Zohar <zohar@us.ibm.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/integrity.h>
|
|
|
|
#include <crypto/sha.h>
|
2013-02-06 15:12:08 -07:00
|
|
|
#include <linux/key.h>
|
2018-06-04 13:54:54 -07:00
|
|
|
#include <linux/audit.h>
|
2011-03-09 12:13:22 -07:00
|
|
|
|
keys: Replace uid/gid/perm permissions checking with an ACL
Replace the uid/gid/perm permissions checking on a key with an ACL to allow
the SETATTR and SEARCH permissions to be split. This will also allow a
greater range of subjects to represented.
============
WHY DO THIS?
============
The problem is that SETATTR and SEARCH cover a slew of actions, not all of
which should be grouped together.
For SETATTR, this includes actions that are about controlling access to a
key:
(1) Changing a key's ownership.
(2) Changing a key's security information.
(3) Setting a keyring's restriction.
And actions that are about managing a key's lifetime:
(4) Setting an expiry time.
(5) Revoking a key.
and (proposed) managing a key as part of a cache:
(6) Invalidating a key.
Managing a key's lifetime doesn't really have anything to do with
controlling access to that key.
Expiry time is awkward since it's more about the lifetime of the content
and so, in some ways goes better with WRITE permission. It can, however,
be set unconditionally by a process with an appropriate authorisation token
for instantiating a key, and can also be set by the key type driver when a
key is instantiated, so lumping it with the access-controlling actions is
probably okay.
As for SEARCH permission, that currently covers:
(1) Finding keys in a keyring tree during a search.
(2) Permitting keyrings to be joined.
(3) Invalidation.
But these don't really belong together either, since these actions really
need to be controlled separately.
Finally, there are number of special cases to do with granting the
administrator special rights to invalidate or clear keys that I would like
to handle with the ACL rather than key flags and special checks.
===============
WHAT IS CHANGED
===============
The SETATTR permission is split to create two new permissions:
(1) SET_SECURITY - which allows the key's owner, group and ACL to be
changed and a restriction to be placed on a keyring.
(2) REVOKE - which allows a key to be revoked.
The SEARCH permission is split to create:
(1) SEARCH - which allows a keyring to be search and a key to be found.
(2) JOIN - which allows a keyring to be joined as a session keyring.
(3) INVAL - which allows a key to be invalidated.
The WRITE permission is also split to create:
(1) WRITE - which allows a key's content to be altered and links to be
added, removed and replaced in a keyring.
(2) CLEAR - which allows a keyring to be cleared completely. This is
split out to make it possible to give just this to an administrator.
(3) REVOKE - see above.
Keys acquire ACLs which consist of a series of ACEs, and all that apply are
unioned together. An ACE specifies a subject, such as:
(*) Possessor - permitted to anyone who 'possesses' a key
(*) Owner - permitted to the key owner
(*) Group - permitted to the key group
(*) Everyone - permitted to everyone
Note that 'Other' has been replaced with 'Everyone' on the assumption that
you wouldn't grant a permit to 'Other' that you wouldn't also grant to
everyone else.
Further subjects may be made available by later patches.
The ACE also specifies a permissions mask. The set of permissions is now:
VIEW Can view the key metadata
READ Can read the key content
WRITE Can update/modify the key content
SEARCH Can find the key by searching/requesting
LINK Can make a link to the key
SET_SECURITY Can change owner, ACL, expiry
INVAL Can invalidate
REVOKE Can revoke
JOIN Can join this keyring
CLEAR Can clear this keyring
The KEYCTL_SETPERM function is then deprecated.
The KEYCTL_SET_TIMEOUT function then is permitted if SET_SECURITY is set,
or if the caller has a valid instantiation auth token.
The KEYCTL_INVALIDATE function then requires INVAL.
The KEYCTL_REVOKE function then requires REVOKE.
The KEYCTL_JOIN_SESSION_KEYRING function then requires JOIN to join an
existing keyring.
The JOIN permission is enabled by default for session keyrings and manually
created keyrings only.
======================
BACKWARD COMPATIBILITY
======================
To maintain backward compatibility, KEYCTL_SETPERM will translate the
permissions mask it is given into a new ACL for a key - unless
KEYCTL_SET_ACL has been called on that key, in which case an error will be
returned.
It will convert possessor, owner, group and other permissions into separate
ACEs, if each portion of the mask is non-zero.
SETATTR permission turns on all of INVAL, REVOKE and SET_SECURITY. WRITE
permission turns on WRITE, REVOKE and, if a keyring, CLEAR. JOIN is turned
on if a keyring is being altered.
The KEYCTL_DESCRIBE function translates the ACL back into a permissions
mask to return depending on possessor, owner, group and everyone ACEs.
It will make the following mappings:
(1) INVAL, JOIN -> SEARCH
(2) SET_SECURITY -> SETATTR
(3) REVOKE -> WRITE if SETATTR isn't already set
(4) CLEAR -> WRITE
Note that the value subsequently returned by KEYCTL_DESCRIBE may not match
the value set with KEYCTL_SETATTR.
=======
TESTING
=======
This passes the keyutils testsuite for all but a couple of tests:
(1) tests/keyctl/dh_compute/badargs: The first wrong-key-type test now
returns EOPNOTSUPP rather than ENOKEY as READ permission isn't removed
if the type doesn't have ->read(). You still can't actually read the
key.
(2) tests/keyctl/permitting/valid: The view-other-permissions test doesn't
work as Other has been replaced with Everyone in the ACL.
Signed-off-by: David Howells <dhowells@redhat.com>
2019-06-27 15:03:07 -07:00
|
|
|
struct key_acl;
|
|
|
|
|
2012-09-12 10:51:32 -07:00
|
|
|
/* iint action cache flags */
|
2012-12-05 07:29:09 -07:00
|
|
|
#define IMA_MEASURE 0x00000001
|
|
|
|
#define IMA_MEASURED 0x00000002
|
|
|
|
#define IMA_APPRAISE 0x00000004
|
|
|
|
#define IMA_APPRAISED 0x00000008
|
|
|
|
/*#define IMA_COLLECT 0x00000010 do not use this flag */
|
|
|
|
#define IMA_COLLECTED 0x00000020
|
|
|
|
#define IMA_AUDIT 0x00000040
|
|
|
|
#define IMA_AUDITED 0x00000080
|
ima: support new "hash" and "dont_hash" policy actions
The builtin ima_appraise_tcb policy, which is specified on the boot
command line, can be replaced with a custom policy, normally early in
the boot process. Custom policies can be more restrictive in some ways,
like requiring file signatures, but can be less restrictive in other
ways, like not appraising mutable files. With a less restrictive policy
in place, files in the builtin policy might not be hashed and labeled
with a security.ima hash. On reboot, files which should be labeled in
the ima_appraise_tcb are not labeled, possibly preventing the system
from booting properly.
To resolve this problem, this patch extends the existing IMA policy
actions "measure", "dont_measure", "appraise", "dont_appraise", and
"audit" with "hash" and "dont_hash". The new "hash" action will write
the file hash as security.ima, but without requiring the file to be
appraised as well.
For example, the builtin ima_appraise_tcb policy includes the rule,
"appraise fowner=0". Adding the "hash fowner=0" rule to a custom
policy, will cause the needed file hashes to be calculated and written
as security.ima xattrs.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
2016-09-29 07:04:52 -07:00
|
|
|
#define IMA_HASH 0x00000100
|
|
|
|
#define IMA_HASHED 0x00000200
|
2012-09-12 10:51:32 -07:00
|
|
|
|
2011-03-09 12:13:22 -07:00
|
|
|
/* iint cache flags */
|
2012-12-05 07:29:09 -07:00
|
|
|
#define IMA_ACTION_FLAGS 0xff000000
|
ima: re-introduce own integrity cache lock
Before IMA appraisal was introduced, IMA was using own integrity cache
lock along with i_mutex. process_measurement and ima_file_free took
the iint->mutex first and then the i_mutex, while setxattr, chmod and
chown took the locks in reverse order. To resolve the potential deadlock,
i_mutex was moved to protect entire IMA functionality and the redundant
iint->mutex was eliminated.
Solution was based on the assumption that filesystem code does not take
i_mutex further. But when file is opened with O_DIRECT flag, direct-io
implementation takes i_mutex and produces deadlock. Furthermore, certain
other filesystem operations, such as llseek, also take i_mutex.
More recently some filesystems have replaced their filesystem specific
lock with the global i_rwsem to read a file. As a result, when IMA
attempts to calculate the file hash, reading the file attempts to take
the i_rwsem again.
To resolve O_DIRECT related deadlock problem, this patch re-introduces
iint->mutex. But to eliminate the original chmod() related deadlock
problem, this patch eliminates the requirement for chmod hooks to take
the iint->mutex by introducing additional atomic iint->attr_flags to
indicate calling of the hooks. The allowed locking order is to take
the iint->mutex first and then the i_rwsem.
Original flags were cleared in chmod(), setxattr() or removwxattr()
hooks and tested when file was closed or opened again. New atomic flags
are set or cleared in those hooks and tested to clear iint->flags on
close or on open.
Atomic flags are following:
* IMA_CHANGE_ATTR - indicates that chATTR() was called (chmod, chown,
chgrp) and file attributes have changed. On file open, it causes IMA
to clear iint->flags to re-evaluate policy and perform IMA functions
again.
* IMA_CHANGE_XATTR - indicates that setxattr or removexattr was called
and extended attributes have changed. On file open, it causes IMA to
clear iint->flags IMA_DONE_MASK to re-appraise.
* IMA_UPDATE_XATTR - indicates that security.ima needs to be updated.
It is cleared if file policy changes and no update is needed.
* IMA_DIGSIG - indicates that file security.ima has signature and file
security.ima must not update to file has on file close.
* IMA_MUST_MEASURE - indicates the file is in the measurement policy.
Fixes: Commit 6552321831dc ("xfs: remove i_iolock and use i_rwsem in
the VFS inode instead")
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2017-12-05 12:06:34 -07:00
|
|
|
#define IMA_DIGSIG_REQUIRED 0x01000000
|
|
|
|
#define IMA_PERMIT_DIRECTIO 0x02000000
|
|
|
|
#define IMA_NEW_FILE 0x04000000
|
|
|
|
#define EVM_IMMUTABLE_DIGSIG 0x08000000
|
2018-02-21 09:36:32 -07:00
|
|
|
#define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
|
2012-09-12 10:51:32 -07:00
|
|
|
|
2012-12-03 15:08:11 -07:00
|
|
|
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
|
ima: support new "hash" and "dont_hash" policy actions
The builtin ima_appraise_tcb policy, which is specified on the boot
command line, can be replaced with a custom policy, normally early in
the boot process. Custom policies can be more restrictive in some ways,
like requiring file signatures, but can be less restrictive in other
ways, like not appraising mutable files. With a less restrictive policy
in place, files in the builtin policy might not be hashed and labeled
with a security.ima hash. On reboot, files which should be labeled in
the ima_appraise_tcb are not labeled, possibly preventing the system
from booting properly.
To resolve this problem, this patch extends the existing IMA policy
actions "measure", "dont_measure", "appraise", "dont_appraise", and
"audit" with "hash" and "dont_hash". The new "hash" action will write
the file hash as security.ima, but without requiring the file to be
appraised as well.
For example, the builtin ima_appraise_tcb policy includes the rule,
"appraise fowner=0". Adding the "hash fowner=0" rule to a custom
policy, will cause the needed file hashes to be calculated and written
as security.ima xattrs.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
2016-09-29 07:04:52 -07:00
|
|
|
IMA_HASH | IMA_APPRAISE_SUBMASK)
|
2012-12-03 15:08:11 -07:00
|
|
|
#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED | \
|
ima: support new "hash" and "dont_hash" policy actions
The builtin ima_appraise_tcb policy, which is specified on the boot
command line, can be replaced with a custom policy, normally early in
the boot process. Custom policies can be more restrictive in some ways,
like requiring file signatures, but can be less restrictive in other
ways, like not appraising mutable files. With a less restrictive policy
in place, files in the builtin policy might not be hashed and labeled
with a security.ima hash. On reboot, files which should be labeled in
the ima_appraise_tcb are not labeled, possibly preventing the system
from booting properly.
To resolve this problem, this patch extends the existing IMA policy
actions "measure", "dont_measure", "appraise", "dont_appraise", and
"audit" with "hash" and "dont_hash". The new "hash" action will write
the file hash as security.ima, but without requiring the file to be
appraised as well.
For example, the builtin ima_appraise_tcb policy includes the rule,
"appraise fowner=0". Adding the "hash fowner=0" rule to a custom
policy, will cause the needed file hashes to be calculated and written
as security.ima xattrs.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
2016-09-29 07:04:52 -07:00
|
|
|
IMA_HASHED | IMA_COLLECTED | \
|
|
|
|
IMA_APPRAISED_SUBMASK)
|
2012-12-03 15:08:11 -07:00
|
|
|
|
|
|
|
/* iint subaction appraise cache flags */
|
ima: support new "hash" and "dont_hash" policy actions
The builtin ima_appraise_tcb policy, which is specified on the boot
command line, can be replaced with a custom policy, normally early in
the boot process. Custom policies can be more restrictive in some ways,
like requiring file signatures, but can be less restrictive in other
ways, like not appraising mutable files. With a less restrictive policy
in place, files in the builtin policy might not be hashed and labeled
with a security.ima hash. On reboot, files which should be labeled in
the ima_appraise_tcb are not labeled, possibly preventing the system
from booting properly.
To resolve this problem, this patch extends the existing IMA policy
actions "measure", "dont_measure", "appraise", "dont_appraise", and
"audit" with "hash" and "dont_hash". The new "hash" action will write
the file hash as security.ima, but without requiring the file to be
appraised as well.
For example, the builtin ima_appraise_tcb policy includes the rule,
"appraise fowner=0". Adding the "hash fowner=0" rule to a custom
policy, will cause the needed file hashes to be calculated and written
as security.ima xattrs.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
2016-09-29 07:04:52 -07:00
|
|
|
#define IMA_FILE_APPRAISE 0x00001000
|
|
|
|
#define IMA_FILE_APPRAISED 0x00002000
|
|
|
|
#define IMA_MMAP_APPRAISE 0x00004000
|
|
|
|
#define IMA_MMAP_APPRAISED 0x00008000
|
|
|
|
#define IMA_BPRM_APPRAISE 0x00010000
|
|
|
|
#define IMA_BPRM_APPRAISED 0x00020000
|
|
|
|
#define IMA_READ_APPRAISE 0x00040000
|
|
|
|
#define IMA_READ_APPRAISED 0x00080000
|
2018-01-08 14:36:20 -07:00
|
|
|
#define IMA_CREDS_APPRAISE 0x00100000
|
|
|
|
#define IMA_CREDS_APPRAISED 0x00200000
|
2012-12-03 15:08:11 -07:00
|
|
|
#define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
|
2018-01-08 14:36:20 -07:00
|
|
|
IMA_BPRM_APPRAISE | IMA_READ_APPRAISE | \
|
|
|
|
IMA_CREDS_APPRAISE)
|
2012-12-03 15:08:11 -07:00
|
|
|
#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
|
2018-01-08 14:36:20 -07:00
|
|
|
IMA_BPRM_APPRAISED | IMA_READ_APPRAISED | \
|
|
|
|
IMA_CREDS_APPRAISED)
|
2011-03-09 12:13:22 -07:00
|
|
|
|
ima: re-introduce own integrity cache lock
Before IMA appraisal was introduced, IMA was using own integrity cache
lock along with i_mutex. process_measurement and ima_file_free took
the iint->mutex first and then the i_mutex, while setxattr, chmod and
chown took the locks in reverse order. To resolve the potential deadlock,
i_mutex was moved to protect entire IMA functionality and the redundant
iint->mutex was eliminated.
Solution was based on the assumption that filesystem code does not take
i_mutex further. But when file is opened with O_DIRECT flag, direct-io
implementation takes i_mutex and produces deadlock. Furthermore, certain
other filesystem operations, such as llseek, also take i_mutex.
More recently some filesystems have replaced their filesystem specific
lock with the global i_rwsem to read a file. As a result, when IMA
attempts to calculate the file hash, reading the file attempts to take
the i_rwsem again.
To resolve O_DIRECT related deadlock problem, this patch re-introduces
iint->mutex. But to eliminate the original chmod() related deadlock
problem, this patch eliminates the requirement for chmod hooks to take
the iint->mutex by introducing additional atomic iint->attr_flags to
indicate calling of the hooks. The allowed locking order is to take
the iint->mutex first and then the i_rwsem.
Original flags were cleared in chmod(), setxattr() or removwxattr()
hooks and tested when file was closed or opened again. New atomic flags
are set or cleared in those hooks and tested to clear iint->flags on
close or on open.
Atomic flags are following:
* IMA_CHANGE_ATTR - indicates that chATTR() was called (chmod, chown,
chgrp) and file attributes have changed. On file open, it causes IMA
to clear iint->flags to re-evaluate policy and perform IMA functions
again.
* IMA_CHANGE_XATTR - indicates that setxattr or removexattr was called
and extended attributes have changed. On file open, it causes IMA to
clear iint->flags IMA_DONE_MASK to re-appraise.
* IMA_UPDATE_XATTR - indicates that security.ima needs to be updated.
It is cleared if file policy changes and no update is needed.
* IMA_DIGSIG - indicates that file security.ima has signature and file
security.ima must not update to file has on file close.
* IMA_MUST_MEASURE - indicates the file is in the measurement policy.
Fixes: Commit 6552321831dc ("xfs: remove i_iolock and use i_rwsem in
the VFS inode instead")
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2017-12-05 12:06:34 -07:00
|
|
|
/* iint cache atomic_flags */
|
|
|
|
#define IMA_CHANGE_XATTR 0
|
|
|
|
#define IMA_UPDATE_XATTR 1
|
|
|
|
#define IMA_CHANGE_ATTR 2
|
|
|
|
#define IMA_DIGSIG 3
|
|
|
|
#define IMA_MUST_MEASURE 4
|
|
|
|
|
2011-03-09 12:28:20 -07:00
|
|
|
enum evm_ima_xattr_type {
|
|
|
|
IMA_XATTR_DIGEST = 0x01,
|
|
|
|
EVM_XATTR_HMAC,
|
|
|
|
EVM_IMA_XATTR_DIGSIG,
|
2013-08-12 01:22:51 -07:00
|
|
|
IMA_XATTR_DIGEST_NG,
|
2017-11-07 08:17:42 -07:00
|
|
|
EVM_XATTR_PORTABLE_DIGSIG,
|
2014-10-28 04:31:22 -07:00
|
|
|
IMA_XATTR_LAST
|
2011-03-09 12:28:20 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct evm_ima_xattr_data {
|
|
|
|
u8 type;
|
2019-06-10 23:28:08 -07:00
|
|
|
u8 data[];
|
|
|
|
} __packed;
|
|
|
|
|
|
|
|
/* Only used in the EVM HMAC code. */
|
|
|
|
struct evm_xattr {
|
|
|
|
struct evm_ima_xattr_data data;
|
2011-03-09 12:28:20 -07:00
|
|
|
u8 digest[SHA1_DIGEST_SIZE];
|
2013-04-25 00:43:56 -07:00
|
|
|
} __packed;
|
|
|
|
|
|
|
|
#define IMA_MAX_DIGEST_SIZE 64
|
|
|
|
|
|
|
|
struct ima_digest_data {
|
|
|
|
u8 algo;
|
|
|
|
u8 length;
|
2013-08-12 01:22:51 -07:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
u8 unused;
|
|
|
|
u8 type;
|
|
|
|
} sha1;
|
|
|
|
struct {
|
|
|
|
u8 type;
|
|
|
|
u8 algo;
|
|
|
|
} ng;
|
|
|
|
u8 data[2];
|
|
|
|
} xattr;
|
2013-04-25 00:44:04 -07:00
|
|
|
u8 digest[0];
|
2013-04-25 00:43:56 -07:00
|
|
|
} __packed;
|
2011-03-09 12:28:20 -07:00
|
|
|
|
2013-04-25 00:44:04 -07:00
|
|
|
/*
|
|
|
|
* signature format v2 - for using with asymmetric keys
|
|
|
|
*/
|
|
|
|
struct signature_v2_hdr {
|
2013-10-10 00:12:03 -07:00
|
|
|
uint8_t type; /* xattr type */
|
2013-04-25 00:44:04 -07:00
|
|
|
uint8_t version; /* signature format version */
|
2016-03-03 14:49:27 -07:00
|
|
|
uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */
|
2017-06-07 18:49:10 -07:00
|
|
|
__be32 keyid; /* IMA key identifier - not X509/PGP specific */
|
|
|
|
__be16 sig_size; /* signature size */
|
2013-04-25 00:44:04 -07:00
|
|
|
uint8_t sig[0]; /* signature payload */
|
|
|
|
} __packed;
|
|
|
|
|
2011-03-09 12:13:22 -07:00
|
|
|
/* integrity data associated with an inode */
|
|
|
|
struct integrity_iint_cache {
|
2013-04-25 00:43:56 -07:00
|
|
|
struct rb_node rb_node; /* rooted in integrity_iint_tree */
|
ima: re-introduce own integrity cache lock
Before IMA appraisal was introduced, IMA was using own integrity cache
lock along with i_mutex. process_measurement and ima_file_free took
the iint->mutex first and then the i_mutex, while setxattr, chmod and
chown took the locks in reverse order. To resolve the potential deadlock,
i_mutex was moved to protect entire IMA functionality and the redundant
iint->mutex was eliminated.
Solution was based on the assumption that filesystem code does not take
i_mutex further. But when file is opened with O_DIRECT flag, direct-io
implementation takes i_mutex and produces deadlock. Furthermore, certain
other filesystem operations, such as llseek, also take i_mutex.
More recently some filesystems have replaced their filesystem specific
lock with the global i_rwsem to read a file. As a result, when IMA
attempts to calculate the file hash, reading the file attempts to take
the i_rwsem again.
To resolve O_DIRECT related deadlock problem, this patch re-introduces
iint->mutex. But to eliminate the original chmod() related deadlock
problem, this patch eliminates the requirement for chmod hooks to take
the iint->mutex by introducing additional atomic iint->attr_flags to
indicate calling of the hooks. The allowed locking order is to take
the iint->mutex first and then the i_rwsem.
Original flags were cleared in chmod(), setxattr() or removwxattr()
hooks and tested when file was closed or opened again. New atomic flags
are set or cleared in those hooks and tested to clear iint->flags on
close or on open.
Atomic flags are following:
* IMA_CHANGE_ATTR - indicates that chATTR() was called (chmod, chown,
chgrp) and file attributes have changed. On file open, it causes IMA
to clear iint->flags to re-evaluate policy and perform IMA functions
again.
* IMA_CHANGE_XATTR - indicates that setxattr or removexattr was called
and extended attributes have changed. On file open, it causes IMA to
clear iint->flags IMA_DONE_MASK to re-appraise.
* IMA_UPDATE_XATTR - indicates that security.ima needs to be updated.
It is cleared if file policy changes and no update is needed.
* IMA_DIGSIG - indicates that file security.ima has signature and file
security.ima must not update to file has on file close.
* IMA_MUST_MEASURE - indicates the file is in the measurement policy.
Fixes: Commit 6552321831dc ("xfs: remove i_iolock and use i_rwsem in
the VFS inode instead")
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2017-12-05 12:06:34 -07:00
|
|
|
struct mutex mutex; /* protects: version, flags, digest */
|
2011-03-09 12:13:22 -07:00
|
|
|
struct inode *inode; /* back pointer to inode in question */
|
|
|
|
u64 version; /* track inode changes */
|
2012-12-05 07:29:09 -07:00
|
|
|
unsigned long flags;
|
2016-06-01 11:14:00 -07:00
|
|
|
unsigned long measured_pcrs;
|
ima: re-introduce own integrity cache lock
Before IMA appraisal was introduced, IMA was using own integrity cache
lock along with i_mutex. process_measurement and ima_file_free took
the iint->mutex first and then the i_mutex, while setxattr, chmod and
chown took the locks in reverse order. To resolve the potential deadlock,
i_mutex was moved to protect entire IMA functionality and the redundant
iint->mutex was eliminated.
Solution was based on the assumption that filesystem code does not take
i_mutex further. But when file is opened with O_DIRECT flag, direct-io
implementation takes i_mutex and produces deadlock. Furthermore, certain
other filesystem operations, such as llseek, also take i_mutex.
More recently some filesystems have replaced their filesystem specific
lock with the global i_rwsem to read a file. As a result, when IMA
attempts to calculate the file hash, reading the file attempts to take
the i_rwsem again.
To resolve O_DIRECT related deadlock problem, this patch re-introduces
iint->mutex. But to eliminate the original chmod() related deadlock
problem, this patch eliminates the requirement for chmod hooks to take
the iint->mutex by introducing additional atomic iint->attr_flags to
indicate calling of the hooks. The allowed locking order is to take
the iint->mutex first and then the i_rwsem.
Original flags were cleared in chmod(), setxattr() or removwxattr()
hooks and tested when file was closed or opened again. New atomic flags
are set or cleared in those hooks and tested to clear iint->flags on
close or on open.
Atomic flags are following:
* IMA_CHANGE_ATTR - indicates that chATTR() was called (chmod, chown,
chgrp) and file attributes have changed. On file open, it causes IMA
to clear iint->flags to re-evaluate policy and perform IMA functions
again.
* IMA_CHANGE_XATTR - indicates that setxattr or removexattr was called
and extended attributes have changed. On file open, it causes IMA to
clear iint->flags IMA_DONE_MASK to re-appraise.
* IMA_UPDATE_XATTR - indicates that security.ima needs to be updated.
It is cleared if file policy changes and no update is needed.
* IMA_DIGSIG - indicates that file security.ima has signature and file
security.ima must not update to file has on file close.
* IMA_MUST_MEASURE - indicates the file is in the measurement policy.
Fixes: Commit 6552321831dc ("xfs: remove i_iolock and use i_rwsem in
the VFS inode instead")
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2017-12-05 12:06:34 -07:00
|
|
|
unsigned long atomic_flags;
|
2012-12-03 15:08:11 -07:00
|
|
|
enum integrity_status ima_file_status:4;
|
|
|
|
enum integrity_status ima_mmap_status:4;
|
|
|
|
enum integrity_status ima_bprm_status:4;
|
2016-01-14 15:57:47 -07:00
|
|
|
enum integrity_status ima_read_status:4;
|
2018-01-08 14:36:20 -07:00
|
|
|
enum integrity_status ima_creds_status:4;
|
2012-09-21 07:00:43 -07:00
|
|
|
enum integrity_status evm_status:4;
|
2013-04-25 00:44:04 -07:00
|
|
|
struct ima_digest_data *ima_hash;
|
2011-03-09 12:13:22 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
/* rbtree tree calls to lookup, insert, delete
|
|
|
|
* integrity data associated with an inode.
|
|
|
|
*/
|
|
|
|
struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
|
2011-08-16 17:34:33 -07:00
|
|
|
|
2014-11-05 08:01:12 -07:00
|
|
|
int integrity_kernel_read(struct file *file, loff_t offset,
|
2017-06-07 18:49:10 -07:00
|
|
|
void *addr, unsigned long count);
|
|
|
|
|
2011-10-05 01:54:46 -07:00
|
|
|
#define INTEGRITY_KEYRING_EVM 0
|
2015-10-22 11:26:10 -07:00
|
|
|
#define INTEGRITY_KEYRING_IMA 1
|
2018-12-12 18:39:09 -07:00
|
|
|
#define INTEGRITY_KEYRING_PLATFORM 2
|
|
|
|
#define INTEGRITY_KEYRING_MAX 3
|
2011-10-05 01:54:46 -07:00
|
|
|
|
2018-05-11 16:12:34 -07:00
|
|
|
extern struct dentry *integrity_dir;
|
|
|
|
|
2012-01-17 08:12:07 -07:00
|
|
|
#ifdef CONFIG_INTEGRITY_SIGNATURE
|
2011-10-05 01:54:46 -07:00
|
|
|
|
|
|
|
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
2013-10-09 23:56:13 -07:00
|
|
|
const char *digest, int digestlen);
|
2011-10-05 01:54:46 -07:00
|
|
|
|
2014-10-01 11:43:07 -07:00
|
|
|
int __init integrity_init_keyring(const unsigned int id);
|
2014-11-26 07:55:00 -07:00
|
|
|
int __init integrity_load_x509(const unsigned int id, const char *path);
|
2018-12-08 13:27:00 -07:00
|
|
|
int __init integrity_load_cert(const unsigned int id, const char *source,
|
keys: Replace uid/gid/perm permissions checking with an ACL
Replace the uid/gid/perm permissions checking on a key with an ACL to allow
the SETATTR and SEARCH permissions to be split. This will also allow a
greater range of subjects to represented.
============
WHY DO THIS?
============
The problem is that SETATTR and SEARCH cover a slew of actions, not all of
which should be grouped together.
For SETATTR, this includes actions that are about controlling access to a
key:
(1) Changing a key's ownership.
(2) Changing a key's security information.
(3) Setting a keyring's restriction.
And actions that are about managing a key's lifetime:
(4) Setting an expiry time.
(5) Revoking a key.
and (proposed) managing a key as part of a cache:
(6) Invalidating a key.
Managing a key's lifetime doesn't really have anything to do with
controlling access to that key.
Expiry time is awkward since it's more about the lifetime of the content
and so, in some ways goes better with WRITE permission. It can, however,
be set unconditionally by a process with an appropriate authorisation token
for instantiating a key, and can also be set by the key type driver when a
key is instantiated, so lumping it with the access-controlling actions is
probably okay.
As for SEARCH permission, that currently covers:
(1) Finding keys in a keyring tree during a search.
(2) Permitting keyrings to be joined.
(3) Invalidation.
But these don't really belong together either, since these actions really
need to be controlled separately.
Finally, there are number of special cases to do with granting the
administrator special rights to invalidate or clear keys that I would like
to handle with the ACL rather than key flags and special checks.
===============
WHAT IS CHANGED
===============
The SETATTR permission is split to create two new permissions:
(1) SET_SECURITY - which allows the key's owner, group and ACL to be
changed and a restriction to be placed on a keyring.
(2) REVOKE - which allows a key to be revoked.
The SEARCH permission is split to create:
(1) SEARCH - which allows a keyring to be search and a key to be found.
(2) JOIN - which allows a keyring to be joined as a session keyring.
(3) INVAL - which allows a key to be invalidated.
The WRITE permission is also split to create:
(1) WRITE - which allows a key's content to be altered and links to be
added, removed and replaced in a keyring.
(2) CLEAR - which allows a keyring to be cleared completely. This is
split out to make it possible to give just this to an administrator.
(3) REVOKE - see above.
Keys acquire ACLs which consist of a series of ACEs, and all that apply are
unioned together. An ACE specifies a subject, such as:
(*) Possessor - permitted to anyone who 'possesses' a key
(*) Owner - permitted to the key owner
(*) Group - permitted to the key group
(*) Everyone - permitted to everyone
Note that 'Other' has been replaced with 'Everyone' on the assumption that
you wouldn't grant a permit to 'Other' that you wouldn't also grant to
everyone else.
Further subjects may be made available by later patches.
The ACE also specifies a permissions mask. The set of permissions is now:
VIEW Can view the key metadata
READ Can read the key content
WRITE Can update/modify the key content
SEARCH Can find the key by searching/requesting
LINK Can make a link to the key
SET_SECURITY Can change owner, ACL, expiry
INVAL Can invalidate
REVOKE Can revoke
JOIN Can join this keyring
CLEAR Can clear this keyring
The KEYCTL_SETPERM function is then deprecated.
The KEYCTL_SET_TIMEOUT function then is permitted if SET_SECURITY is set,
or if the caller has a valid instantiation auth token.
The KEYCTL_INVALIDATE function then requires INVAL.
The KEYCTL_REVOKE function then requires REVOKE.
The KEYCTL_JOIN_SESSION_KEYRING function then requires JOIN to join an
existing keyring.
The JOIN permission is enabled by default for session keyrings and manually
created keyrings only.
======================
BACKWARD COMPATIBILITY
======================
To maintain backward compatibility, KEYCTL_SETPERM will translate the
permissions mask it is given into a new ACL for a key - unless
KEYCTL_SET_ACL has been called on that key, in which case an error will be
returned.
It will convert possessor, owner, group and other permissions into separate
ACEs, if each portion of the mask is non-zero.
SETATTR permission turns on all of INVAL, REVOKE and SET_SECURITY. WRITE
permission turns on WRITE, REVOKE and, if a keyring, CLEAR. JOIN is turned
on if a keyring is being altered.
The KEYCTL_DESCRIBE function translates the ACL back into a permissions
mask to return depending on possessor, owner, group and everyone ACEs.
It will make the following mappings:
(1) INVAL, JOIN -> SEARCH
(2) SET_SECURITY -> SETATTR
(3) REVOKE -> WRITE if SETATTR isn't already set
(4) CLEAR -> WRITE
Note that the value subsequently returned by KEYCTL_DESCRIBE may not match
the value set with KEYCTL_SETATTR.
=======
TESTING
=======
This passes the keyutils testsuite for all but a couple of tests:
(1) tests/keyctl/dh_compute/badargs: The first wrong-key-type test now
returns EOPNOTSUPP rather than ENOKEY as READ permission isn't removed
if the type doesn't have ->read(). You still can't actually read the
key.
(2) tests/keyctl/permitting/valid: The view-other-permissions test doesn't
work as Other has been replaced with Everyone in the ACL.
Signed-off-by: David Howells <dhowells@redhat.com>
2019-06-27 15:03:07 -07:00
|
|
|
const void *data, size_t len, struct key_acl *acl);
|
2011-10-05 01:54:46 -07:00
|
|
|
#else
|
|
|
|
|
|
|
|
static inline int integrity_digsig_verify(const unsigned int id,
|
|
|
|
const char *sig, int siglen,
|
|
|
|
const char *digest, int digestlen)
|
|
|
|
{
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2013-08-13 05:47:43 -07:00
|
|
|
static inline int integrity_init_keyring(const unsigned int id)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2018-12-08 13:27:00 -07:00
|
|
|
|
|
|
|
static inline int __init integrity_load_cert(const unsigned int id,
|
|
|
|
const char *source,
|
|
|
|
const void *data, size_t len,
|
keys: Replace uid/gid/perm permissions checking with an ACL
Replace the uid/gid/perm permissions checking on a key with an ACL to allow
the SETATTR and SEARCH permissions to be split. This will also allow a
greater range of subjects to represented.
============
WHY DO THIS?
============
The problem is that SETATTR and SEARCH cover a slew of actions, not all of
which should be grouped together.
For SETATTR, this includes actions that are about controlling access to a
key:
(1) Changing a key's ownership.
(2) Changing a key's security information.
(3) Setting a keyring's restriction.
And actions that are about managing a key's lifetime:
(4) Setting an expiry time.
(5) Revoking a key.
and (proposed) managing a key as part of a cache:
(6) Invalidating a key.
Managing a key's lifetime doesn't really have anything to do with
controlling access to that key.
Expiry time is awkward since it's more about the lifetime of the content
and so, in some ways goes better with WRITE permission. It can, however,
be set unconditionally by a process with an appropriate authorisation token
for instantiating a key, and can also be set by the key type driver when a
key is instantiated, so lumping it with the access-controlling actions is
probably okay.
As for SEARCH permission, that currently covers:
(1) Finding keys in a keyring tree during a search.
(2) Permitting keyrings to be joined.
(3) Invalidation.
But these don't really belong together either, since these actions really
need to be controlled separately.
Finally, there are number of special cases to do with granting the
administrator special rights to invalidate or clear keys that I would like
to handle with the ACL rather than key flags and special checks.
===============
WHAT IS CHANGED
===============
The SETATTR permission is split to create two new permissions:
(1) SET_SECURITY - which allows the key's owner, group and ACL to be
changed and a restriction to be placed on a keyring.
(2) REVOKE - which allows a key to be revoked.
The SEARCH permission is split to create:
(1) SEARCH - which allows a keyring to be search and a key to be found.
(2) JOIN - which allows a keyring to be joined as a session keyring.
(3) INVAL - which allows a key to be invalidated.
The WRITE permission is also split to create:
(1) WRITE - which allows a key's content to be altered and links to be
added, removed and replaced in a keyring.
(2) CLEAR - which allows a keyring to be cleared completely. This is
split out to make it possible to give just this to an administrator.
(3) REVOKE - see above.
Keys acquire ACLs which consist of a series of ACEs, and all that apply are
unioned together. An ACE specifies a subject, such as:
(*) Possessor - permitted to anyone who 'possesses' a key
(*) Owner - permitted to the key owner
(*) Group - permitted to the key group
(*) Everyone - permitted to everyone
Note that 'Other' has been replaced with 'Everyone' on the assumption that
you wouldn't grant a permit to 'Other' that you wouldn't also grant to
everyone else.
Further subjects may be made available by later patches.
The ACE also specifies a permissions mask. The set of permissions is now:
VIEW Can view the key metadata
READ Can read the key content
WRITE Can update/modify the key content
SEARCH Can find the key by searching/requesting
LINK Can make a link to the key
SET_SECURITY Can change owner, ACL, expiry
INVAL Can invalidate
REVOKE Can revoke
JOIN Can join this keyring
CLEAR Can clear this keyring
The KEYCTL_SETPERM function is then deprecated.
The KEYCTL_SET_TIMEOUT function then is permitted if SET_SECURITY is set,
or if the caller has a valid instantiation auth token.
The KEYCTL_INVALIDATE function then requires INVAL.
The KEYCTL_REVOKE function then requires REVOKE.
The KEYCTL_JOIN_SESSION_KEYRING function then requires JOIN to join an
existing keyring.
The JOIN permission is enabled by default for session keyrings and manually
created keyrings only.
======================
BACKWARD COMPATIBILITY
======================
To maintain backward compatibility, KEYCTL_SETPERM will translate the
permissions mask it is given into a new ACL for a key - unless
KEYCTL_SET_ACL has been called on that key, in which case an error will be
returned.
It will convert possessor, owner, group and other permissions into separate
ACEs, if each portion of the mask is non-zero.
SETATTR permission turns on all of INVAL, REVOKE and SET_SECURITY. WRITE
permission turns on WRITE, REVOKE and, if a keyring, CLEAR. JOIN is turned
on if a keyring is being altered.
The KEYCTL_DESCRIBE function translates the ACL back into a permissions
mask to return depending on possessor, owner, group and everyone ACEs.
It will make the following mappings:
(1) INVAL, JOIN -> SEARCH
(2) SET_SECURITY -> SETATTR
(3) REVOKE -> WRITE if SETATTR isn't already set
(4) CLEAR -> WRITE
Note that the value subsequently returned by KEYCTL_DESCRIBE may not match
the value set with KEYCTL_SETATTR.
=======
TESTING
=======
This passes the keyutils testsuite for all but a couple of tests:
(1) tests/keyctl/dh_compute/badargs: The first wrong-key-type test now
returns EOPNOTSUPP rather than ENOKEY as READ permission isn't removed
if the type doesn't have ->read(). You still can't actually read the
key.
(2) tests/keyctl/permitting/valid: The view-other-permissions test doesn't
work as Other has been replaced with Everyone in the ACL.
Signed-off-by: David Howells <dhowells@redhat.com>
2019-06-27 15:03:07 -07:00
|
|
|
struct key_acl *acl)
|
2018-12-08 13:27:00 -07:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2012-01-17 08:12:07 -07:00
|
|
|
#endif /* CONFIG_INTEGRITY_SIGNATURE */
|
2011-10-05 01:54:46 -07:00
|
|
|
|
2013-02-06 15:12:08 -07:00
|
|
|
#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
|
|
|
|
int asymmetric_verify(struct key *keyring, const char *sig,
|
|
|
|
int siglen, const char *data, int datalen);
|
|
|
|
#else
|
|
|
|
static inline int asymmetric_verify(struct key *keyring, const char *sig,
|
|
|
|
int siglen, const char *data, int datalen)
|
|
|
|
{
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-11-05 08:01:14 -07:00
|
|
|
#ifdef CONFIG_IMA_LOAD_X509
|
|
|
|
void __init ima_load_x509(void);
|
|
|
|
#else
|
|
|
|
static inline void ima_load_x509(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-22 11:26:21 -07:00
|
|
|
#ifdef CONFIG_EVM_LOAD_X509
|
|
|
|
void __init evm_load_x509(void);
|
|
|
|
#else
|
|
|
|
static inline void evm_load_x509(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-03-18 11:48:02 -07:00
|
|
|
#ifdef CONFIG_INTEGRITY_AUDIT
|
|
|
|
/* declarations */
|
|
|
|
void integrity_audit_msg(int audit_msgno, struct inode *inode,
|
|
|
|
const unsigned char *fname, const char *op,
|
|
|
|
const char *cause, int result, int info);
|
2018-06-04 13:54:54 -07:00
|
|
|
|
|
|
|
static inline struct audit_buffer *
|
|
|
|
integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type)
|
|
|
|
{
|
|
|
|
return audit_log_start(ctx, gfp_mask, type);
|
|
|
|
}
|
|
|
|
|
2013-03-18 11:48:02 -07:00
|
|
|
#else
|
|
|
|
static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
|
|
|
|
const unsigned char *fname,
|
|
|
|
const char *op, const char *cause,
|
|
|
|
int result, int info)
|
|
|
|
{
|
|
|
|
}
|
2018-06-04 13:54:54 -07:00
|
|
|
|
|
|
|
static inline struct audit_buffer *
|
|
|
|
integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-03-18 11:48:02 -07:00
|
|
|
#endif
|
2018-12-08 13:27:00 -07:00
|
|
|
|
|
|
|
#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
|
|
|
|
void __init add_to_platform_keyring(const char *source, const void *data,
|
|
|
|
size_t len);
|
|
|
|
#else
|
|
|
|
static inline void __init add_to_platform_keyring(const char *source,
|
|
|
|
const void *data, size_t len)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|