diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 7eba630ba..93eaa9969 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -148,6 +148,8 @@ ostream &mqueue_rule::dump(ostream &os) os << ")"; } + if (label) + os << " label=" << label; if (qname) os << " " << qname; @@ -238,6 +240,19 @@ int mqueue_rule::gen_policy_re(Profile &prof) audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, 1, vec, parseopts, false)) goto fail; + + /* create should be allowed when label is present since the + * queue needs to be created to have a label associated to it + */ + if (perms & AA_MQUEUE_CREATE && + !prof.policy.rules->add_rule_vec( + priority, + rule_mode, + map_mqueue_perms(perms & AA_MQUEUE_CREATE_PERMS), + audit == AUDIT_FORCE ? map_mqueue_perms(perms & AA_MQUEUE_CREATE_PERMS) : 0, 1, + vec, parseopts, false)) + goto fail; + /* also provide label match with perm */ if (!prof.policy.rules->add_rule_vec(priority, rule_mode, @@ -282,6 +297,19 @@ int mqueue_rule::gen_policy_re(Profile &prof) audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, 1, vec, parseopts, false)) goto fail; + + /* create should be allowed when label is present since the + * queue needs to be created to have a label associated to it + */ + if (perms & AA_MQUEUE_CREATE && + !prof.policy.rules->add_rule_vec( + priority, + rule_mode, + map_mqueue_perms(perms & AA_MQUEUE_CREATE_PERMS), + audit == AUDIT_FORCE ? map_mqueue_perms(perms & AA_MQUEUE_CREATE_PERMS) : 0, 1, + vec, parseopts, false)) + goto fail; + /* also provide label match with perm */ if (!prof.policy.rules->add_rule_vec(priority, rule_mode, diff --git a/parser/mqueue.h b/parser/mqueue.h index 0948c22e5..58d4d01c5 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -69,6 +69,12 @@ #define AA_VALID_MQUEUE_PERMS (AA_VALID_POSIX_MQ_PERMS | \ AA_VALID_SYSV_MQ_PERMS) +/* read and write needed with create because mq_open can be called + * with O_CREAT | O_RDWR, which all show up in the requested perms at + * the same time during creation + */ +#define AA_MQUEUE_CREATE_PERMS (AA_MQUEUE_CREATE | AA_MQUEUE_READ | \ + AA_MQUEUE_WRITE) // warning getting into overlap area /* Type of mqueue - can be explicit or implied by rule id/path */ diff --git a/tests/regression/apparmor/posix_mq.sh b/tests/regression/apparmor/posix_mq.sh index 40c3919d7..1bf820a3a 100755 --- a/tests/regression/apparmor/posix_mq.sh +++ b/tests/regression/apparmor/posix_mq.sh @@ -160,14 +160,19 @@ for username in "root" "$userid" ; do do_tests "confined receiver $username - unconfined sender" pass pass pass pass $usercmd + labelres="xpass" + if [ "$(kernel_features ipc/posix_mqueue/label)" = "true" ]; then + labelres="pass" + fi + # queue label genprofile "qual=deny:cap:sys_resource" "cap:setuid" "cap:fowner" "network:netlink" "mqueue:label=$receiver" "$sender:px" "$pipe:rw" -- "image=$sender" "mqueue:label=$receiver" "$pipe:rw" - do_tests "confined $username - mqueue label 1" xpass xpass xpass xpass $usercmd + do_tests "confined $username - mqueue label 1" $labelres $labelres $labelres $labelres $usercmd # queue name and label genprofile "qual=deny:cap:sys_resource" "cap:setuid" "cap:fowner" "network:netlink" "mqueue:(create,read,delete):type=posix:label=$receiver:$queuename" "$sender:px" "$pipe:rw" -- "image=$sender" "mqueue:(open,write):type=posix:label=$receiver:$queuename" "$pipe:rw" - do_tests "confined $username - mqueue label 2" xpass xpass xpass xpass $usercmd + do_tests "confined $username - mqueue label 2" $labelres $labelres $labelres $labelres $usercmd # ensure we are cleaned up for next pass removeprofile