You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'serge-next-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux-security
Pull security layer updates from Serge Hallyn: "This is a merge of James Morris' security-next tree from 3.14 to yesterday's master, plus four patches from Paul Moore which are in linux-next, plus one patch from Mimi" * 'serge-next-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux-security: ima: audit log files opened with O_DIRECT flag selinux: conditionally reschedule in hashtab_insert while loading selinux policy selinux: conditionally reschedule in mls_convert_context while loading selinux policy selinux: reject setexeccon() on MNT_NOSUID applications with -EACCES selinux: Report permissive mode in avc: denied messages. Warning in scanf string typing Smack: Label cgroup files for systemd Smack: Verify read access on file open - v3 security: Convert use of typedef ctl_table to struct ctl_table Smack: bidirectional UDS connect check Smack: Correctly remove SMACK64TRANSMUTE attribute SMACK: Fix handling value==NULL in post setxattr bugfix patch for SMACK Smack: adds smackfs/ptrace interface Smack: unify all ptrace accesses in the smack Smack: fix the subject/object order in smack_ptrace_traceme() Minor improvement of 'smack_sb_kern_mount' smack: fix key permission verification KEYS: Move the flags representing required permission to linux/key.h
This commit is contained in:
@@ -23,7 +23,7 @@ Description:
|
||||
[fowner]]
|
||||
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||
[obj_user=] [obj_role=] [obj_type=]]
|
||||
option: [[appraise_type=]]
|
||||
option: [[appraise_type=]] [permit_directio]
|
||||
|
||||
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
|
||||
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
|
||||
|
||||
@@ -204,6 +204,16 @@ onlycap
|
||||
these capabilities are effective at for processes with any
|
||||
label. The value is set by writing the desired label to the
|
||||
file or cleared by writing "-" to the file.
|
||||
ptrace
|
||||
This is used to define the current ptrace policy
|
||||
0 - default: this is the policy that relies on smack access rules.
|
||||
For the PTRACE_READ a subject needs to have a read access on
|
||||
object. For the PTRACE_ATTACH a read-write access is required.
|
||||
1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
|
||||
only allowed when subject's and object's labels are equal.
|
||||
PTRACE_READ is not affected. Can be overriden with CAP_SYS_PTRACE.
|
||||
2 - draconian: this policy behaves like the 'exact' above with an
|
||||
exception that it can't be overriden with CAP_SYS_PTRACE.
|
||||
revoke-subject
|
||||
Writing a Smack label here sets the access to '-' for all access
|
||||
rules with that subject label.
|
||||
|
||||
@@ -309,6 +309,17 @@ static inline key_serial_t key_serial(const struct key *key)
|
||||
|
||||
extern void key_set_timeout(struct key *, unsigned);
|
||||
|
||||
/*
|
||||
* The permissions required on a key that we're looking up.
|
||||
*/
|
||||
#define KEY_NEED_VIEW 0x01 /* Require permission to view attributes */
|
||||
#define KEY_NEED_READ 0x02 /* Require permission to read content */
|
||||
#define KEY_NEED_WRITE 0x04 /* Require permission to update / modify */
|
||||
#define KEY_NEED_SEARCH 0x08 /* Require permission to search (keyring) or find (key) */
|
||||
#define KEY_NEED_LINK 0x10 /* Require permission to link */
|
||||
#define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */
|
||||
#define KEY_NEED_ALL 0x3f /* All the above permissions */
|
||||
|
||||
/**
|
||||
* key_is_instantiated - Determine if a key has been positively instantiated
|
||||
* @key: The key to check.
|
||||
|
||||
@@ -1708,7 +1708,7 @@ struct security_operations {
|
||||
void (*key_free) (struct key *key);
|
||||
int (*key_permission) (key_ref_t key_ref,
|
||||
const struct cred *cred,
|
||||
key_perm_t perm);
|
||||
unsigned perm);
|
||||
int (*key_getsecurity)(struct key *key, char **_buffer);
|
||||
#endif /* CONFIG_KEYS */
|
||||
|
||||
@@ -3034,7 +3034,7 @@ static inline int security_path_chroot(struct path *path)
|
||||
int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags);
|
||||
void security_key_free(struct key *key);
|
||||
int security_key_permission(key_ref_t key_ref,
|
||||
const struct cred *cred, key_perm_t perm);
|
||||
const struct cred *cred, unsigned perm);
|
||||
int security_key_getsecurity(struct key *key, char **_buffer);
|
||||
|
||||
#else
|
||||
@@ -3052,7 +3052,7 @@ static inline void security_key_free(struct key *key)
|
||||
|
||||
static inline int security_key_permission(key_ref_t key_ref,
|
||||
const struct cred *cred,
|
||||
key_perm_t perm)
|
||||
unsigned perm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -879,7 +879,7 @@ static void cap_key_free(struct key *key)
|
||||
}
|
||||
|
||||
static int cap_key_permission(key_ref_t key_ref, const struct cred *cred,
|
||||
key_perm_t perm)
|
||||
unsigned perm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
struct evm_ima_xattr_data **xattr_value,
|
||||
int *xattr_len)
|
||||
{
|
||||
const char *audit_cause = "failed";
|
||||
struct inode *inode = file_inode(file);
|
||||
const char *filename = file->f_dentry->d_name.name;
|
||||
int result = 0;
|
||||
@@ -213,6 +214,12 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
if (!(iint->flags & IMA_COLLECTED)) {
|
||||
u64 i_version = file_inode(file)->i_version;
|
||||
|
||||
if (file->f_flags & O_DIRECT) {
|
||||
audit_cause = "failed(directio)";
|
||||
result = -EACCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* use default hash algorithm */
|
||||
hash.hdr.algo = ima_hash_algo;
|
||||
|
||||
@@ -233,9 +240,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
result = -ENOMEM;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (result)
|
||||
integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
|
||||
filename, "collect_data", "failed",
|
||||
filename, "collect_data", audit_cause,
|
||||
result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -214,8 +214,11 @@ static int process_measurement(struct file *file, const char *filename,
|
||||
xattr_ptr = &xattr_value;
|
||||
|
||||
rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
|
||||
if (rc != 0)
|
||||
if (rc != 0) {
|
||||
if (file->f_flags & O_DIRECT)
|
||||
rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
|
||||
goto out_digsig;
|
||||
}
|
||||
|
||||
pathname = filename ?: ima_d_path(&file->f_path, &pathbuf);
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ enum {
|
||||
Opt_obj_user, Opt_obj_role, Opt_obj_type,
|
||||
Opt_subj_user, Opt_subj_role, Opt_subj_type,
|
||||
Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
|
||||
Opt_appraise_type, Opt_fsuuid
|
||||
Opt_appraise_type, Opt_fsuuid, Opt_permit_directio
|
||||
};
|
||||
|
||||
static match_table_t policy_tokens = {
|
||||
@@ -375,6 +375,7 @@ static match_table_t policy_tokens = {
|
||||
{Opt_uid, "uid=%s"},
|
||||
{Opt_fowner, "fowner=%s"},
|
||||
{Opt_appraise_type, "appraise_type=%s"},
|
||||
{Opt_permit_directio, "permit_directio"},
|
||||
{Opt_err, NULL}
|
||||
};
|
||||
|
||||
@@ -622,6 +623,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
else
|
||||
result = -EINVAL;
|
||||
break;
|
||||
case Opt_permit_directio:
|
||||
entry->flags |= IMA_PERMIT_DIRECTIO;
|
||||
break;
|
||||
case Opt_err:
|
||||
ima_log_string(ab, "UNKNOWN", p);
|
||||
result = -EINVAL;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define IMA_ACTION_FLAGS 0xff000000
|
||||
#define IMA_DIGSIG 0x01000000
|
||||
#define IMA_DIGSIG_REQUIRED 0x02000000
|
||||
#define IMA_PERMIT_DIRECTIO 0x04000000
|
||||
|
||||
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
|
||||
IMA_APPRAISE_SUBMASK)
|
||||
|
||||
@@ -176,20 +176,11 @@ extern int key_task_permission(const key_ref_t key_ref,
|
||||
/*
|
||||
* Check to see whether permission is granted to use a key in the desired way.
|
||||
*/
|
||||
static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
|
||||
static inline int key_permission(const key_ref_t key_ref, unsigned perm)
|
||||
{
|
||||
return key_task_permission(key_ref, current_cred(), perm);
|
||||
}
|
||||
|
||||
/* required permissions */
|
||||
#define KEY_VIEW 0x01 /* require permission to view attributes */
|
||||
#define KEY_READ 0x02 /* require permission to read content */
|
||||
#define KEY_WRITE 0x04 /* require permission to update / modify */
|
||||
#define KEY_SEARCH 0x08 /* require permission to search (keyring) or find (key) */
|
||||
#define KEY_LINK 0x10 /* require permission to link */
|
||||
#define KEY_SETATTR 0x20 /* require permission to change attributes */
|
||||
#define KEY_ALL 0x3f /* all the above permissions */
|
||||
|
||||
/*
|
||||
* Authorisation record for request_key().
|
||||
*/
|
||||
|
||||
+3
-3
@@ -714,7 +714,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
|
||||
int ret;
|
||||
|
||||
/* need write permission on the key to update it */
|
||||
ret = key_permission(key_ref, KEY_WRITE);
|
||||
ret = key_permission(key_ref, KEY_NEED_WRITE);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
@@ -838,7 +838,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||
|
||||
/* if we're going to allocate a new key, we're going to have
|
||||
* to modify the keyring */
|
||||
ret = key_permission(keyring_ref, KEY_WRITE);
|
||||
ret = key_permission(keyring_ref, KEY_NEED_WRITE);
|
||||
if (ret < 0) {
|
||||
key_ref = ERR_PTR(ret);
|
||||
goto error_link_end;
|
||||
@@ -928,7 +928,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
|
||||
key_check(key);
|
||||
|
||||
/* the key must be writable */
|
||||
ret = key_permission(key_ref, KEY_WRITE);
|
||||
ret = key_permission(key_ref, KEY_NEED_WRITE);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
|
||||
+22
-22
@@ -111,7 +111,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
|
||||
}
|
||||
|
||||
/* find the target keyring (which must be writable) */
|
||||
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
|
||||
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
|
||||
if (IS_ERR(keyring_ref)) {
|
||||
ret = PTR_ERR(keyring_ref);
|
||||
goto error3;
|
||||
@@ -195,7 +195,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
|
||||
dest_ref = NULL;
|
||||
if (destringid) {
|
||||
dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE,
|
||||
KEY_WRITE);
|
||||
KEY_NEED_WRITE);
|
||||
if (IS_ERR(dest_ref)) {
|
||||
ret = PTR_ERR(dest_ref);
|
||||
goto error3;
|
||||
@@ -253,7 +253,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
|
||||
long ret;
|
||||
|
||||
lflags = create ? KEY_LOOKUP_CREATE : 0;
|
||||
key_ref = lookup_user_key(id, lflags, KEY_SEARCH);
|
||||
key_ref = lookup_user_key(id, lflags, KEY_NEED_SEARCH);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
goto error;
|
||||
@@ -334,7 +334,7 @@ long keyctl_update_key(key_serial_t id,
|
||||
}
|
||||
|
||||
/* find the target key (which must be writable) */
|
||||
key_ref = lookup_user_key(id, 0, KEY_WRITE);
|
||||
key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
goto error2;
|
||||
@@ -365,12 +365,12 @@ long keyctl_revoke_key(key_serial_t id)
|
||||
key_ref_t key_ref;
|
||||
long ret;
|
||||
|
||||
key_ref = lookup_user_key(id, 0, KEY_WRITE);
|
||||
key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
if (ret != -EACCES)
|
||||
goto error;
|
||||
key_ref = lookup_user_key(id, 0, KEY_SETATTR);
|
||||
key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
goto error;
|
||||
@@ -401,7 +401,7 @@ long keyctl_invalidate_key(key_serial_t id)
|
||||
|
||||
kenter("%d", id);
|
||||
|
||||
key_ref = lookup_user_key(id, 0, KEY_SEARCH);
|
||||
key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
goto error;
|
||||
@@ -428,7 +428,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
|
||||
key_ref_t keyring_ref;
|
||||
long ret;
|
||||
|
||||
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
|
||||
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
|
||||
if (IS_ERR(keyring_ref)) {
|
||||
ret = PTR_ERR(keyring_ref);
|
||||
|
||||
@@ -470,13 +470,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
|
||||
key_ref_t keyring_ref, key_ref;
|
||||
long ret;
|
||||
|
||||
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
|
||||
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
|
||||
if (IS_ERR(keyring_ref)) {
|
||||
ret = PTR_ERR(keyring_ref);
|
||||
goto error;
|
||||
}
|
||||
|
||||
key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_LINK);
|
||||
key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_NEED_LINK);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
goto error2;
|
||||
@@ -505,7 +505,7 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
|
||||
key_ref_t keyring_ref, key_ref;
|
||||
long ret;
|
||||
|
||||
keyring_ref = lookup_user_key(ringid, 0, KEY_WRITE);
|
||||
keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_WRITE);
|
||||
if (IS_ERR(keyring_ref)) {
|
||||
ret = PTR_ERR(keyring_ref);
|
||||
goto error;
|
||||
@@ -548,7 +548,7 @@ long keyctl_describe_key(key_serial_t keyid,
|
||||
char *tmpbuf;
|
||||
long ret;
|
||||
|
||||
key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW);
|
||||
key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW);
|
||||
if (IS_ERR(key_ref)) {
|
||||
/* viewing a key under construction is permitted if we have the
|
||||
* authorisation token handy */
|
||||
@@ -639,7 +639,7 @@ long keyctl_keyring_search(key_serial_t ringid,
|
||||
}
|
||||
|
||||
/* get the keyring at which to begin the search */
|
||||
keyring_ref = lookup_user_key(ringid, 0, KEY_SEARCH);
|
||||
keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_SEARCH);
|
||||
if (IS_ERR(keyring_ref)) {
|
||||
ret = PTR_ERR(keyring_ref);
|
||||
goto error2;
|
||||
@@ -649,7 +649,7 @@ long keyctl_keyring_search(key_serial_t ringid,
|
||||
dest_ref = NULL;
|
||||
if (destringid) {
|
||||
dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE,
|
||||
KEY_WRITE);
|
||||
KEY_NEED_WRITE);
|
||||
if (IS_ERR(dest_ref)) {
|
||||
ret = PTR_ERR(dest_ref);
|
||||
goto error3;
|
||||
@@ -676,7 +676,7 @@ long keyctl_keyring_search(key_serial_t ringid,
|
||||
|
||||
/* link the resulting key to the destination keyring if we can */
|
||||
if (dest_ref) {
|
||||
ret = key_permission(key_ref, KEY_LINK);
|
||||
ret = key_permission(key_ref, KEY_NEED_LINK);
|
||||
if (ret < 0)
|
||||
goto error6;
|
||||
|
||||
@@ -727,7 +727,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
|
||||
key = key_ref_to_ptr(key_ref);
|
||||
|
||||
/* see if we can read it directly */
|
||||
ret = key_permission(key_ref, KEY_READ);
|
||||
ret = key_permission(key_ref, KEY_NEED_READ);
|
||||
if (ret == 0)
|
||||
goto can_read_key;
|
||||
if (ret != -EACCES)
|
||||
@@ -799,7 +799,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
|
||||
goto error;
|
||||
|
||||
key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
|
||||
KEY_SETATTR);
|
||||
KEY_NEED_SETATTR);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
goto error;
|
||||
@@ -905,7 +905,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
|
||||
goto error;
|
||||
|
||||
key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
|
||||
KEY_SETATTR);
|
||||
KEY_NEED_SETATTR);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
goto error;
|
||||
@@ -947,7 +947,7 @@ static long get_instantiation_keyring(key_serial_t ringid,
|
||||
|
||||
/* if a specific keyring is nominated by ID, then use that */
|
||||
if (ringid > 0) {
|
||||
dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
|
||||
dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
|
||||
if (IS_ERR(dkref))
|
||||
return PTR_ERR(dkref);
|
||||
*_dest_keyring = key_ref_to_ptr(dkref);
|
||||
@@ -1315,7 +1315,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
|
||||
long ret;
|
||||
|
||||
key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
|
||||
KEY_SETATTR);
|
||||
KEY_NEED_SETATTR);
|
||||
if (IS_ERR(key_ref)) {
|
||||
/* setting the timeout on a key under construction is permitted
|
||||
* if we have the authorisation token handy */
|
||||
@@ -1418,7 +1418,7 @@ long keyctl_get_security(key_serial_t keyid,
|
||||
char *context;
|
||||
long ret;
|
||||
|
||||
key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW);
|
||||
key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW);
|
||||
if (IS_ERR(key_ref)) {
|
||||
if (PTR_ERR(key_ref) != -EACCES)
|
||||
return PTR_ERR(key_ref);
|
||||
@@ -1482,7 +1482,7 @@ long keyctl_session_to_parent(void)
|
||||
struct cred *cred;
|
||||
int ret;
|
||||
|
||||
keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK);
|
||||
keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_NEED_LINK);
|
||||
if (IS_ERR(keyring_r))
|
||||
return PTR_ERR(keyring_r);
|
||||
|
||||
|
||||
@@ -541,7 +541,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
|
||||
/* key must have search permissions */
|
||||
if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) &&
|
||||
key_task_permission(make_key_ref(key, ctx->possessed),
|
||||
ctx->cred, KEY_SEARCH) < 0) {
|
||||
ctx->cred, KEY_NEED_SEARCH) < 0) {
|
||||
ctx->result = ERR_PTR(-EACCES);
|
||||
kleave(" = %d [!perm]", ctx->skipped_ret);
|
||||
goto skipped;
|
||||
@@ -721,7 +721,7 @@ ascend_to_node:
|
||||
/* Search a nested keyring */
|
||||
if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) &&
|
||||
key_task_permission(make_key_ref(key, ctx->possessed),
|
||||
ctx->cred, KEY_SEARCH) < 0)
|
||||
ctx->cred, KEY_NEED_SEARCH) < 0)
|
||||
continue;
|
||||
|
||||
/* stack the current position */
|
||||
@@ -843,7 +843,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
|
||||
return ERR_PTR(-ENOTDIR);
|
||||
|
||||
if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM)) {
|
||||
err = key_task_permission(keyring_ref, ctx->cred, KEY_SEARCH);
|
||||
err = key_task_permission(keyring_ref, ctx->cred, KEY_NEED_SEARCH);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
@@ -973,7 +973,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
|
||||
|
||||
if (!skip_perm_check &&
|
||||
key_permission(make_key_ref(keyring, 0),
|
||||
KEY_SEARCH) < 0)
|
||||
KEY_NEED_SEARCH) < 0)
|
||||
continue;
|
||||
|
||||
/* we've got a match but we might end up racing with
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* permissions bits or the LSM check.
|
||||
*/
|
||||
int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
|
||||
key_perm_t perm)
|
||||
unsigned perm)
|
||||
{
|
||||
struct key *key;
|
||||
key_perm_t kperm;
|
||||
@@ -68,7 +68,7 @@ use_these_perms:
|
||||
if (is_key_possessed(key_ref))
|
||||
kperm |= key->perm >> 24;
|
||||
|
||||
kperm = kperm & perm & KEY_ALL;
|
||||
kperm = kperm & perm & KEY_NEED_ALL;
|
||||
|
||||
if (kperm != perm)
|
||||
return -EACCES;
|
||||
|
||||
@@ -108,7 +108,7 @@ static long key_get_persistent(struct user_namespace *ns, kuid_t uid,
|
||||
return PTR_ERR(persistent_ref);
|
||||
|
||||
found:
|
||||
ret = key_task_permission(persistent_ref, current_cred(), KEY_LINK);
|
||||
ret = key_task_permission(persistent_ref, current_cred(), KEY_NEED_LINK);
|
||||
if (ret == 0) {
|
||||
persistent = key_ref_to_ptr(persistent_ref);
|
||||
ret = key_link(key_ref_to_ptr(dest_ref), persistent);
|
||||
@@ -151,7 +151,7 @@ long keyctl_get_persistent(uid_t _uid, key_serial_t destid)
|
||||
}
|
||||
|
||||
/* There must be a destination keyring */
|
||||
dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_WRITE);
|
||||
dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
|
||||
if (IS_ERR(dest_ref))
|
||||
return PTR_ERR(dest_ref);
|
||||
if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) {
|
||||
|
||||
@@ -218,7 +218,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
|
||||
* - the caller holds a spinlock, and thus the RCU read lock, making our
|
||||
* access to __current_cred() safe
|
||||
*/
|
||||
rc = key_task_permission(key_ref, ctx.cred, KEY_VIEW);
|
||||
rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW);
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
static const int zero, one = 1, max = INT_MAX;
|
||||
|
||||
ctl_table key_sysctls[] = {
|
||||
struct ctl_table key_sysctls[] = {
|
||||
{
|
||||
.procname = "maxkeys",
|
||||
.data = &key_quota_maxkeys,
|
||||
|
||||
+1
-1
@@ -1425,7 +1425,7 @@ void security_key_free(struct key *key)
|
||||
}
|
||||
|
||||
int security_key_permission(key_ref_t key_ref,
|
||||
const struct cred *cred, key_perm_t perm)
|
||||
const struct cred *cred, unsigned perm)
|
||||
{
|
||||
return security_ops->key_permission(key_ref, cred, perm);
|
||||
}
|
||||
|
||||
@@ -444,11 +444,15 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
|
||||
avc_dump_query(ab, ad->selinux_audit_data->ssid,
|
||||
ad->selinux_audit_data->tsid,
|
||||
ad->selinux_audit_data->tclass);
|
||||
if (ad->selinux_audit_data->denied) {
|
||||
audit_log_format(ab, " permissive=%u",
|
||||
ad->selinux_audit_data->result ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is the slow part of avc audit with big stack footprint */
|
||||
noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
|
||||
u32 requested, u32 audited, u32 denied,
|
||||
u32 requested, u32 audited, u32 denied, int result,
|
||||
struct common_audit_data *a,
|
||||
unsigned flags)
|
||||
{
|
||||
@@ -477,6 +481,7 @@ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
|
||||
sad.tsid = tsid;
|
||||
sad.audited = audited;
|
||||
sad.denied = denied;
|
||||
sad.result = result;
|
||||
|
||||
a->selinux_audit_data = &sad;
|
||||
|
||||
|
||||
@@ -2123,11 +2123,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
|
||||
new_tsec->exec_sid = 0;
|
||||
|
||||
/*
|
||||
* Minimize confusion: if no_new_privs and a transition is
|
||||
* explicitly requested, then fail the exec.
|
||||
* Minimize confusion: if no_new_privs or nosuid and a
|
||||
* transition is explicitly requested, then fail the exec.
|
||||
*/
|
||||
if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
|
||||
return -EPERM;
|
||||
if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
|
||||
return -EACCES;
|
||||
} else {
|
||||
/* Check for a default transition on this program. */
|
||||
rc = security_transition_sid(old_tsec->sid, isec->sid,
|
||||
@@ -2770,6 +2772,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
|
||||
|
||||
static noinline int audit_inode_permission(struct inode *inode,
|
||||
u32 perms, u32 audited, u32 denied,
|
||||
int result,
|
||||
unsigned flags)
|
||||
{
|
||||
struct common_audit_data ad;
|
||||
@@ -2780,7 +2783,7 @@ static noinline int audit_inode_permission(struct inode *inode,
|
||||
ad.u.inode = inode;
|
||||
|
||||
rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
|
||||
audited, denied, &ad, flags);
|
||||
audited, denied, result, &ad, flags);
|
||||
if (rc)
|
||||
return rc;
|
||||
return 0;
|
||||
@@ -2822,7 +2825,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
|
||||
if (likely(!audited))
|
||||
return rc;
|
||||
|
||||
rc2 = audit_inode_permission(inode, perms, audited, denied, flags);
|
||||
rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
|
||||
if (rc2)
|
||||
return rc2;
|
||||
return rc;
|
||||
@@ -5722,7 +5725,7 @@ static void selinux_key_free(struct key *k)
|
||||
|
||||
static int selinux_key_permission(key_ref_t key_ref,
|
||||
const struct cred *cred,
|
||||
key_perm_t perm)
|
||||
unsigned perm)
|
||||
{
|
||||
struct key *key;
|
||||
struct key_security_struct *ksec;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user