mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
apparmor-pr-2024-07-24 PR 2024-07-25
+ Cleanups - optimization: try to avoid refing the label in apparmor_file_open - remove useless static inline function is_deleted - use kvfree_sensitive to free data->data - fix typo in kernel doc + Bug fixes - unpack transition table if dfa is not present - test: add MODULE_DESCRIPTION() - take nosymfollow flag into account - fix possible NULL pointer dereference - fix null pointer deref when receiving skb during sock creation -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE7cSDD705q2rFEEf7BS82cBjVw9gFAmaikGkACgkQBS82cBjV w9gasBAAsnHikPshnqnCnIyA/Am9/LeOstKf8jQCbPWtjt1Fw3y8gmuJJOhRalM1 R343rFUF3Z5wb+Yy1xELww3eET91QgC9s5NLJceDXvKOnAppHD+YOphjfmRbpgaF rWHGN6/rD30HALKpsMw7Z3jTe9xOPhygh+lWlaiJIoXZ2hZwv2Chd6TDVR8BSFyq OLhuf++DLcZNEcvg1bUxccK49J+iAVeC0VtdzNXw+BRZU5zM/US8n+8EStxuY65n cAwBM+cJn6yhX3bsazUacw32SCgWePTJr87Wbfn1oF5znoU/HMM9CtPvivTwQSRN +nT0qm57CJW2IJdRfP2OhRpAbRvUgMjGjyIf7PJHn0zCXffiDNZhSuFOcKy9wAOQ H9qi7lkAC9KYIs1jI57Fogp+sgo11q+fPdzgGuuCgFnZp7gEPChsTewO346jNYES fORj62CsWL3lvhADq1cC/kgO9NZHwI7SLH5orobvrIoP9SGH2pGi0Nzdch62MNXo BwJctpsgS8QPl2XiQhf38+LIczf+USOkDlXO5tmYsTTSUNmjd+7fDc1pcBv0WCf+ 2DOEpI3DuaCr1oTr+jJ3zfysYZdeubFI/8uq5dCrMGQZZneEx0RSZAOGAbrWaPCy XrmkvrjDwGMPocBF0RVHgda60OofZRa/aJnUxhIkOXTDDWpdQPM= =kO+r -----END PGP SIGNATURE----- Merge tag 'apparmor-pr-2024-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor Pull apparmor updates from John Johansen: "Cleanups - optimization: try to avoid refing the label in apparmor_file_open - remove useless static inline function is_deleted - use kvfree_sensitive to free data->data - fix typo in kernel doc Bug fixes: - unpack transition table if dfa is not present - test: add MODULE_DESCRIPTION() - take nosymfollow flag into account - fix possible NULL pointer dereference - fix null pointer deref when receiving skb during sock creation" * tag 'apparmor-pr-2024-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: apparmor: unpack transition table if dfa is not present apparmor: try to avoid refing the label in apparmor_file_open apparmor: test: add MODULE_DESCRIPTION() apparmor: take nosymfollow flag into account apparmor: fix possible NULL pointer dereference apparmor: fix typo in kernel doc apparmor: remove useless static inline function is_deleted apparmor: use kvfree_sensitive to free data->data apparmor: Fix null pointer deref when receiving skb during sock creation
This commit is contained in:
commit
ff30564411
@ -1692,6 +1692,10 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
|
|||||||
struct aa_profile *p;
|
struct aa_profile *p;
|
||||||
p = aa_deref_parent(profile);
|
p = aa_deref_parent(profile);
|
||||||
dent = prof_dir(p);
|
dent = prof_dir(p);
|
||||||
|
if (!dent) {
|
||||||
|
error = -ENOENT;
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
/* adding to parent that previously didn't have children */
|
/* adding to parent that previously didn't have children */
|
||||||
dent = aafs_create_dir("profiles", dent);
|
dent = aafs_create_dir("profiles", dent);
|
||||||
if (IS_ERR(dent))
|
if (IS_ERR(dent))
|
||||||
|
@ -144,19 +144,6 @@ int aa_audit_file(const struct cred *subj_cred,
|
|||||||
return aa_audit(type, profile, &ad, file_audit_cb);
|
return aa_audit(type, profile, &ad, file_audit_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* is_deleted - test if a file has been completely unlinked
|
|
||||||
* @dentry: dentry of file to test for deletion (NOT NULL)
|
|
||||||
*
|
|
||||||
* Returns: true if deleted else false
|
|
||||||
*/
|
|
||||||
static inline bool is_deleted(struct dentry *dentry)
|
|
||||||
{
|
|
||||||
if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int path_name(const char *op, const struct cred *subj_cred,
|
static int path_name(const char *op, const struct cred *subj_cred,
|
||||||
struct aa_label *label,
|
struct aa_label *label,
|
||||||
const struct path *path, int flags, char *buffer,
|
const struct path *path, int flags, char *buffer,
|
||||||
|
@ -63,6 +63,26 @@ static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)
|
|||||||
return aa_get_newest_label(aa_cred_raw_label(cred));
|
return aa_get_newest_label(aa_cred_raw_label(cred));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct aa_label *aa_get_newest_cred_label_condref(const struct cred *cred,
|
||||||
|
bool *needput)
|
||||||
|
{
|
||||||
|
struct aa_label *l = aa_cred_raw_label(cred);
|
||||||
|
|
||||||
|
if (unlikely(label_is_stale(l))) {
|
||||||
|
*needput = true;
|
||||||
|
return aa_get_newest_label(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
*needput = false;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void aa_put_label_condref(struct aa_label *l, bool needput)
|
||||||
|
{
|
||||||
|
if (unlikely(needput))
|
||||||
|
aa_put_label(l);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aa_current_raw_label - find the current tasks confining label
|
* aa_current_raw_label - find the current tasks confining label
|
||||||
*
|
*
|
||||||
|
@ -461,6 +461,7 @@ static int apparmor_file_open(struct file *file)
|
|||||||
struct aa_file_ctx *fctx = file_ctx(file);
|
struct aa_file_ctx *fctx = file_ctx(file);
|
||||||
struct aa_label *label;
|
struct aa_label *label;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
bool needput;
|
||||||
|
|
||||||
if (!path_mediated_fs(file->f_path.dentry))
|
if (!path_mediated_fs(file->f_path.dentry))
|
||||||
return 0;
|
return 0;
|
||||||
@ -477,7 +478,7 @@ static int apparmor_file_open(struct file *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
label = aa_get_newest_cred_label(file->f_cred);
|
label = aa_get_newest_cred_label_condref(file->f_cred, &needput);
|
||||||
if (!unconfined(label)) {
|
if (!unconfined(label)) {
|
||||||
struct mnt_idmap *idmap = file_mnt_idmap(file);
|
struct mnt_idmap *idmap = file_mnt_idmap(file);
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
@ -494,7 +495,7 @@ static int apparmor_file_open(struct file *file)
|
|||||||
/* todo cache full allowed permissions set and state */
|
/* todo cache full allowed permissions set and state */
|
||||||
fctx->allow = aa_map_file_to_perms(file);
|
fctx->allow = aa_map_file_to_perms(file);
|
||||||
}
|
}
|
||||||
aa_put_label(label);
|
aa_put_label_condref(label, needput);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -1124,7 +1125,7 @@ static int apparmor_socket_create(int family, int type, int protocol, int kern)
|
|||||||
* @sock: socket that is being setup
|
* @sock: socket that is being setup
|
||||||
* @family: family of socket being created
|
* @family: family of socket being created
|
||||||
* @type: type of the socket
|
* @type: type of the socket
|
||||||
* @ptotocol: protocol of the socket
|
* @protocol: protocol of the socket
|
||||||
* @kern: socket is a special kernel socket
|
* @kern: socket is a special kernel socket
|
||||||
*
|
*
|
||||||
* Note:
|
* Note:
|
||||||
@ -1304,6 +1305,13 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|||||||
if (!skb->secmark)
|
if (!skb->secmark)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If reach here before socket_post_create hook is called, in which
|
||||||
|
* case label is null, drop the packet.
|
||||||
|
*/
|
||||||
|
if (!ctx->label)
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
return apparmor_secmark_check(ctx->label, OP_RECVMSG, AA_MAY_RECEIVE,
|
return apparmor_secmark_check(ctx->label, OP_RECVMSG, AA_MAY_RECEIVE,
|
||||||
skb->secmark, sk);
|
skb->secmark, sk);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
|
|||||||
audit_log_format(ab, ", mand");
|
audit_log_format(ab, ", mand");
|
||||||
if (flags & MS_DIRSYNC)
|
if (flags & MS_DIRSYNC)
|
||||||
audit_log_format(ab, ", dirsync");
|
audit_log_format(ab, ", dirsync");
|
||||||
|
if (flags & MS_NOSYMFOLLOW)
|
||||||
|
audit_log_format(ab, ", nosymfollow");
|
||||||
if (flags & MS_NOATIME)
|
if (flags & MS_NOATIME)
|
||||||
audit_log_format(ab, ", noatime");
|
audit_log_format(ab, ", noatime");
|
||||||
if (flags & MS_NODIRATIME)
|
if (flags & MS_NODIRATIME)
|
||||||
|
@ -225,7 +225,7 @@ static void aa_free_data(void *ptr, void *arg)
|
|||||||
{
|
{
|
||||||
struct aa_data *data = ptr;
|
struct aa_data *data = ptr;
|
||||||
|
|
||||||
kfree_sensitive(data->data);
|
kvfree_sensitive(data->data, data->size);
|
||||||
kfree_sensitive(data->key);
|
kfree_sensitive(data->key);
|
||||||
kfree_sensitive(data);
|
kfree_sensitive(data);
|
||||||
}
|
}
|
||||||
|
@ -747,34 +747,42 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy,
|
|||||||
*info = "missing required dfa";
|
*info = "missing required dfa";
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
goto out;
|
} else {
|
||||||
|
/*
|
||||||
|
* only unpack the following if a dfa is present
|
||||||
|
*
|
||||||
|
* sadly start was given different names for file and policydb
|
||||||
|
* but since it is optional we can try both
|
||||||
|
*/
|
||||||
|
if (!aa_unpack_u32(e, &pdb->start[0], "start"))
|
||||||
|
/* default start state */
|
||||||
|
pdb->start[0] = DFA_START;
|
||||||
|
if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) {
|
||||||
|
/* default start state for xmatch and file dfa */
|
||||||
|
pdb->start[AA_CLASS_FILE] = DFA_START;
|
||||||
|
} /* setup class index */
|
||||||
|
for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
|
||||||
|
pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0],
|
||||||
|
i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* only unpack the following if a dfa is present
|
* Unfortunately due to a bug in earlier userspaces, a
|
||||||
*
|
* transition table may be present even when the dfa is
|
||||||
* sadly start was given different names for file and policydb
|
* not. For compatibility reasons unpack and discard.
|
||||||
* but since it is optional we can try both
|
|
||||||
*/
|
*/
|
||||||
if (!aa_unpack_u32(e, &pdb->start[0], "start"))
|
|
||||||
/* default start state */
|
|
||||||
pdb->start[0] = DFA_START;
|
|
||||||
if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) {
|
|
||||||
/* default start state for xmatch and file dfa */
|
|
||||||
pdb->start[AA_CLASS_FILE] = DFA_START;
|
|
||||||
} /* setup class index */
|
|
||||||
for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
|
|
||||||
pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0],
|
|
||||||
i);
|
|
||||||
}
|
|
||||||
if (!unpack_trans_table(e, &pdb->trans) && required_trans) {
|
if (!unpack_trans_table(e, &pdb->trans) && required_trans) {
|
||||||
*info = "failed to unpack profile transition table";
|
*info = "failed to unpack profile transition table";
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pdb->dfa && pdb->trans.table)
|
||||||
|
aa_free_str_table(&pdb->trans);
|
||||||
|
|
||||||
/* TODO: move compat mapping here, requires dfa merging first */
|
/* TODO: move compat mapping here, requires dfa merging first */
|
||||||
/* TODO: move verify here, it has to be done after compat mappings */
|
/* TODO: move verify here, it has to be done after compat mappings */
|
||||||
out:
|
|
||||||
*policy = pdb;
|
*policy = pdb;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1071,6 +1079,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|||||||
|
|
||||||
if (rhashtable_insert_fast(profile->data, &data->head,
|
if (rhashtable_insert_fast(profile->data, &data->head,
|
||||||
profile->data->p)) {
|
profile->data->p)) {
|
||||||
|
kvfree_sensitive(data->data, data->size);
|
||||||
kfree_sensitive(data->key);
|
kfree_sensitive(data->key);
|
||||||
kfree_sensitive(data);
|
kfree_sensitive(data);
|
||||||
info = "failed to insert data to table";
|
info = "failed to insert data to table";
|
||||||
|
@ -604,4 +604,5 @@ static struct kunit_suite apparmor_policy_unpack_test_module = {
|
|||||||
|
|
||||||
kunit_test_suite(apparmor_policy_unpack_test_module);
|
kunit_test_suite(apparmor_policy_unpack_test_module);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("KUnit tests for AppArmor's policy unpack");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
Loading…
Reference in New Issue
Block a user