Great! Note that the code before was considered PoC and there was an important TODO item in it. I implemented this now, but in doing so noticed that the default policy does not allow hardlinking to the semaphore file, so I’m filing a PR to snapd and added a fallback mechanism to the library if the hardlink fails with permission denied. As such, until the PR is committed to snapd, the above pasted output will be different and there will be a “l” denial, but the operation on the whole continues to be successful. Example successful output until the PR lands:
$ test-sem-open.named 1 2
sem_open() wrapper: hard linking tempfile denied. Falling back to rename()
main() sem_getvalue() init: 0
main() about to call sem_timedwait()
sem_post() from handler
sem_getvalue() from hander pre: 0
sem_getvalue() from hander post: 1
sem_timedwait() succeeded
main() sem_getvalue() after sem_timedwait: 0
$ grep test-sem-open.named /var/log/syslog
audit: type=1400 audit(1544198965.450:2332): apparmor="DENIED" operation="link" profile="snap.test-sem-open.named" name="/dev/shm/sem.snap.test-sem-open.sem-named-test" pid=13742 comm="sem-named-test" requested_mask="l" denied_mask="l" fsuid=1000 ouid=1000 target="/dev/shm/snap.test-sem-open.sem-named-test.lTZ0rH"
Notice the new sem_open() wrapper: hard linking tempfile denied. Falling back to rename()
message and a new, but harmless hardlink denial for the rewritten path.
The broken behavior remains the same:
$ test-sem-open.named-broken 1 2
sem_open: Permission denied
[1]
$ grep test-sem-open.named /var/log/syslog
audit: type=1400 audit(1544199149.495:2334): apparmor="DENIED" operation="mknod" profile="snap.test-sem-open.named-broken" name="/dev/shm/toNu6V" pid=13872 comm="sem-named-test" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
Notice the broken, non-rewritten behavior is a “c” denial with an un-rewritten path.