So, since the job is being restarted by neutron (or at least it is trying to re-start it, causing the apparmor to block the access), I created a systemtap script to monitor path_name and check for dnsmasq trying to open "log" (allegedly /dev/log) file.
function task_dentry_path:string(task:long,dentry:long,vfsmnt:long)
Couldn't handle the udev (vfsmnt) path. With that, I thought apparmor couldn't be handling udev path for different root vfsmnt (like a different FS namespace).
Checking iproute2 ipnetns.c I saw that executing a command in a new network namespace causes:
unshare(CLONE_NEWNS) AND
mount("", "/", "none", MS_SLAVE | MS_REC, NULL)
This second being possibly the "problem" - its intent is not to allow mounts to propagate back to parent task - since it basically removes a root vfsmnt from the execution taken in place, breaking apparmor (or even dentry cache) path resolution logic. Here, the needed flag "attach_disconnected" (present in apparmor path resolution logic) comes in place, to allow "/" to be added in path names missing leading / due to missing root vfsmnt from dentry cache.
To observe: 3.13 (apparmor 3 alpha 6) doesn't complain on disconnected paths but 3.16 and beyond (rc1) does (needing the flag "attach_disconnected").
Okay, so, I had more time to dig a bit into this and, after some analysis, I got:
Errors being reproduced:
[1668392.078137] audit: type=1400 audit(145931178 6.129:1375455) : apparmor="DENIED" operation="sendmsg" info="Failed name lookup - disconnected path" error=-13 profile= "/usr/sbin/ dnsmasq" name="dev/log" pid=15735 comm="dnsmasq" requested_mask="w" denied_mask="w" fsuid=0 ouid=0
And apparmor dnsmasq profile:
#/usr/sbin/dnsmasq flags=( attach_ disconnected) {
#/usr/sbin/dnsmasq flags=(complain) {
/usr/sbin/dnsmasq {
Without any flags.
And the command causing the apparmor errors:
root 16877 0.0 0.2 66416 3648 ? S 13:23 0:00 sudo /usr/bin/ neutron- rootwrap /etc/neutron/ rootwrap. conf ip netns exec qdhcp-37d013b6- f6fa-4652- 8073-5e7d2c418a 9d env NEUTRON_ NETWORK_ ID=37d013b6- f6fa-4652- 8073-5e7d2c418a 9d dnsmasq --no-hosts --no-resolv --strict-order --bind-interfaces --interface= ns-aa95fe20- ff --except- interface= lo --pid-file= /var/lib/ neutron/ dhcp/37d013b6- f6fa-4652- 8073-5e7d2c418a 9d/pid --dhcp- hostsfile= /var/lib/ neutron/ dhcp/37d013b6- f6fa-4652- 8073-5e7d2c418a 9d/host --addn- hosts=/ var/lib/ neutron/ dhcp/37d013b6- f6fa-4652- 8073-5e7d2c418a 9d/addn_ hosts --dhcp- optsfile= /var/lib/ neutron/ dhcp/37d013b6- f6fa-4652- 8073-5e7d2c418a 9d/opts --dhcp- leasefile= /var/lib/ neutron/ dhcp/37d013b6- f6fa-4652- 8073-5e7d2c418a 9d/leases --dhcp- range=set: tag0,192. 168.21. 0,static, 86400s --dhcp- lease-max= 256 --conf- file=/etc/ neutron/ dnsmasq. conf --domain= openstacklocal
It is a "sudo-like" approach from openstack (rootwrap) to execute dnsmasq in a new network namespace with different privileges.
Ubuntu kernel 3.13.X has apparmor 3 alpha 6 code: https:/ /pastebin. canonical. com/152812/ /pastebin. canonical. com/152813/
Ubuntu kernel 3.16 and 3.19 has apparmor 3 rc 1 code: https:/
From apparmor I could see that the error comes from "aa_path_name" called by either:
- path_name * change_ type
- aa_remount
- aa_bind_mount
- aa_mount_
- aa_move_mount
- aa_new_mount
- aa_unmount
- aa_pivotroot
So, since the job is being restarted by neutron (or at least it is trying to re-start it, causing the apparmor to block the access), I created a systemtap script to monitor path_name and check for dnsmasq trying to open "log" (allegedly /dev/log) file.
probe kernel. function( "path_name" ).call { path_walk( $path-> dentry) ; backtrace( );
funcname = execname();
if (funcname == "dnsmasq") {
filename = reverse_
if (filename == "log") {
printf("(%s) %s\n", execname(), filename);
print_
}
}
}
And got the backtrace from the denials:
(dnsmasq) log
0xffffffff8132deb0 : path_name+0x0/0x140 [kernel] perm+0xa3/ 0x130 [kernel] peer_perm+ 0x536/0x990 [kernel] unix_may_ send+0x73/ 0x150 [kernel] unix_may_ send+0x16/ 0x20 [kernel] connect+ 0x23b/0x250 [kernel] 0xe7/0x120 [kernel] 0xe/0x10 [kernel] call_fastpath+ 0x1a/0x1f [kernel]
0xffffffff8132e413 : aa_path_
0xffffffff81337e26 : aa_unix_
0xffffffff8132c653 : apparmor_
0xffffffff812eb8a6 : security_
0xffffffff817019db : unix_dgram_
0xffffffff8164a987 : SYSC_connect+
0xffffffff8164b68e : sys_connect+
0xffffffff817700cd : system_
When trying to check if "log" could be converted to "fullpath" by using systemtap function:
return task_dentry_ path(task_ current( ), path,"path" ,"kernel: nfs:kernel< linux/path. h>")->dentry, path,"path" ,"kernel: nfs:kernel< linux/path. h>")->mnt)
@cast(
@cast(
I saw that I could resolve path for all other files but "/dev/log":
(dnsmasq) /usr/lib/ x86_64- linux-gnu/ libnfnetlink. so.0.2. 0 x86_64- linux-gnu/ libmnl. so.0.1. 0 x86_64- linux-gnu/ gconv/gconv- modules. cache dnsmasq. conf dnsmasq. conf
(dnsmasq) /usr/lib/
(dnsmasq) /usr/lib/
(dnsmasq) /etc/neutron/
(dnsmasq) /etc/neutron/
(dnsmasq) /etc/localtime
(dnsmasq) /etc/localtime
(dnsmasq) /etc/localtime
(dnsmasq) <unknown>
Because
function task_dentry_ path:string( task:long, dentry: long,vfsmnt: long)
Couldn't handle the udev (vfsmnt) path. With that, I thought apparmor couldn't be handling udev path for different root vfsmnt (like a different FS namespace).
Checking iproute2 ipnetns.c I saw that executing a command in a new network namespace causes:
unshare( CLONE_NEWNS) AND
mount("", "/", "none", MS_SLAVE | MS_REC, NULL)
This second being possibly the "problem" - its intent is not to allow mounts to propagate back to parent task - since it basically removes a root vfsmnt from the execution taken in place, breaking apparmor (or even dentry cache) path resolution logic. Here, the needed flag "attach_ disconnected" (present in apparmor path resolution logic) comes in place, to allow "/" to be added in path names missing leading / due to missing root vfsmnt from dentry cache.
To observe: 3.13 (apparmor 3 alpha 6) doesn't complain on disconnected paths but 3.16 and beyond (rc1) does (needing the flag "attach_ disconnected" ).