Here's the test program that I used. It emulates the second clone(2) that Chris mentioned and then prints out the list of capabilities that it has after entering new user, pid, and net namespaces.
# Build it
$ gcc demo_ns.c -Wall -pedantic -lcap -o demo-ns
# Run it unconfined
$ ./demo-ns
eUID = 65534; eGID = 65534; capabilities: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,37+ep
# Create an AppArmor profile that only grants file access
$ echo "profile demo-ns { file, }" | sudo apparmor_parser -qr
# Rerun the demo program under confinement
$ aa-exec -p demo-ns -- ./demo-ns
clone: Operation not permitted
$ sudo tail /var/log/audit/audit.log | grep DENIED
type=AVC msg=audit(1429741255.712:2723): apparmor="DENIED" operation="capable" profile="demo-ns" pid=12921 comm="demo-ns" capability=21 capname="sys_admin"
# Add a CAP_SYS_ADMIN and CAP_NET_BIND_SERVICE
$ echo "profile demo-ns { file, capability sys_admin, capability net_bind_service, }" | sudo apparmor_parser -qr
# Rerun it
$ aa-exec -p demo-ns -- ./demo-ns
eUID = 65534; eGID = 65534; capabilities: = cap_net_bind_service,cap_sys_admin+ep
Here's the test program that I used. It emulates the second clone(2) that Chris mentioned and then prints out the list of capabilities that it has after entering new user, pid, and net namespaces.
# Build it cap_dac_ override, cap_dac_ read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_ immutable, cap_net_ bind_service, cap_net_ broadcast, cap_net_ admin,cap_ net_raw, cap_ipc_ lock,cap_ ipc_owner, cap_sys_ module, cap_sys_ rawio,cap_ sys_chroot, cap_sys_ ptrace, cap_sys_ pacct,cap_ sys_admin, cap_sys_ boot,cap_ sys_nice, cap_sys_ resource, cap_sys_ time,cap_ sys_tty_ config, cap_mknod, cap_lease, cap_audit_ write,cap_ audit_control, cap_setfcap, cap_mac_ override, cap_mac_ admin,cap_ syslog, cap_wake_ alarm,cap_ block_suspend, 37+ep audit/audit. log | grep DENIED 1429741255. 712:2723) : apparmor="DENIED" operation="capable" profile="demo-ns" pid=12921 comm="demo-ns" capability=21 capname="sys_admin" BIND_SERVICE bind_service, cap_sys_ admin+ep
$ gcc demo_ns.c -Wall -pedantic -lcap -o demo-ns
# Run it unconfined
$ ./demo-ns
eUID = 65534; eGID = 65534; capabilities: = cap_chown,
# Create an AppArmor profile that only grants file access
$ echo "profile demo-ns { file, }" | sudo apparmor_parser -qr
# Rerun the demo program under confinement
$ aa-exec -p demo-ns -- ./demo-ns
clone: Operation not permitted
$ sudo tail /var/log/
type=AVC msg=audit(
# Add a CAP_SYS_ADMIN and CAP_NET_
$ echo "profile demo-ns { file, capability sys_admin, capability net_bind_service, }" | sudo apparmor_parser -qr
# Rerun it
$ aa-exec -p demo-ns -- ./demo-ns
eUID = 65534; eGID = 65534; capabilities: = cap_net_