Linux Kernel áá¯á¶ááŒá¯á¶áá±ážá áááºážáá¡ááºá¹áá«áááºáá»á¬ážááŸáá·áº Seccomp
BPF ááẠáááºááŒáááºááŸá¯á áá¯á¶ááŒá¯á¶áá±áž ááá¯á·ááá¯áẠááŒááºááŸá¯ááºážááᯠáááááá¯ááºá á±áá² kernel ááᯠááá¯ážáá»á²á·ááẠá¡á áœááºážáááºáá±á¬áááºážáááºážááᯠáá¶á·ááá¯ážáá±ážáá«áááºá á€á¡ááŒá±á¬ááºážááŒá±á¬áá·áºá kernel developer áá»á¬ážááẠSeccomp BPF áá¯áááºážááááŒáá±á¬ BPF áááá¯ááááºáá»á¬ážááŸáá¶á·ááá¯ážáá±á¬ Seccomp á á áºáá¯ááºááŸá¯áá»á¬ážááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážááŒáá·áº Seccomp ááœáẠáá¯ááºáááºážá ááºá¡áá®ážáá»ááºááŸá¯ááᯠááŒáŸáá·áºáááºááẠáááºážááááºá á¯á¶á áœááºážááá¬ážááᯠá¡áá¯á¶ážááŒá¯ááẠá¡ááŒá¶áá±á¬ááºážááŒá áºáááºáᯠáá°ááá«áááºá á€á¡áááºážááœáẠSeccomp ááẠá¡áááºá¡áá¬ááŸáá·áº áááºážááá¯á¡áá¯á¶ážááŒá¯ááŒá±á¬ááºážááᯠáá»áœááºá¯ááºááá¯á·ááŸááºážááŒáá«áááºá ááá¯á·áá±á¬áẠBPF áááá¯ááááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á Seccomp filters áá»á¬ážááᯠáááºááá¯á·áá±ážááááºááᯠáá±á·áá¬ááááºááŒá áºáá«áááºá áááºážáá±á¬ááºá Linux áá¯á¶ááŒá¯á¶áá±áž modules á¡ááœáẠkernel ááœááºáá«ááŸááá±á¬ built-in BPF áá»áááºáá»á¬ážááᯠááŒáá·áºááŸá¯áá«áááºá
Linux Security Modules (LSM) ááẠá á¶áááºááŸááºáá¬ážááá·áºáá¯á¶á á¶ááŒáá·áº á¡áá»áá¯ážáá»áá¯ážáá±á¬ áá¯á¶ááŒá¯á¶áá±ážáá±á¬áºáááºáá»á¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááẠá¡áá¯á¶ážááŒá¯ááá¯ááºááá·áº áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá¡á á¯á¶ááᯠáá±á¬ááºáá¶á·áá±ážááá·áº áá°áá±á¬ááºáá áºáá¯ááŒá áºáááºá LSM ááᯠApparmorá SELinux ááŸáá·áº Tomoyo áá²á·ááá¯á·áá±á¬ kernel áááºážááŒá áºáá áºááœáẠááá¯ááºááá¯ááºá¡áá¯á¶ážááŒá¯ááá¯ááºáá«áááºá
Linux áá áœááºážáááºáá»á¬ážááᯠááœá±ážááœá±ážááŒááºážááŒáá·áº á áááºááŒáá«á áá¯á·á
á¡ááœááºá·á¡áááºáž
Linux áá áœááºážáá±á¬ááºááá¯ááºááŸá¯áá¡ááŸá áºáá¬áááŸá¬ áááºááẠá¡áá»áá¯á·áá±á¬áá¯ááºáááºážáá¬áááºáá áºáá¯áá¯ááºáá±á¬ááºááẠá¡ááœáá·áºáá°ážááá¶ááá±ážáá±á¬ áá¯ááºáááºážá ááºááᯠááœáá·áºááŒá¯áá»ááºáá±ážááẠááá¯á¡ááºáááºá ááá¯á·áá±á¬áº ááá¯áááºááœááºáá»ááºá¡ááœáẠsuid ááá¯ááá¯á¶ážáá² ááá¯á·ááá¯áẠá¡ááŒá¬ážáááºážááŒáá·áº áá¯ááºáááºážá ááºááᯠá¡ááœáá·áºáá°ážáá¶ááŒá áºá á±áááºá ááá¯ááºááá¯ááºááŸá¯ááŒá áºááá¯ááºááŒá±ááᯠáá»áŸá±á¬á·áá»áááºááŸáá·áº áá¯ááºáááºážá ááºá¡áá»áá¯á·ááᯠáá¯ááºáá±á¬ááºááẠááœáá·áºááŒá¯ááŒááºážáááºááŒá áºáááºá á¥ááá¬á¡á¬ážááŒáá·áºá ááá·áºá¡ááá®áá±ážááŸááºážááẠá¡ááœáá·áºáá°ážáá¶ááááºáááºážááá¯ááœáá·áºááẠááá¯á¡ááºáá«áá áá¯ááºáááºážá ááºááᯠroot á¡ááŒá áºáá¯ááºáá±á¬ááºááá·áºá¡á á¬áž 80 áá¯ááŒá±á¬áá«á áááºážááᯠCAP_NET_BIND_SERVICE á áœááºážáááºááᯠááá¯ážááá¯ážááŸááºážááŸááºážáá±ážááá¯ááºáá«áááºá
main.go á¡áááºááŸá Go áááá¯ááááºááᯠáá¯á¶ážáááºááŒáá·áºáá«-
package main
import (
"net/http"
"log"
)
func main() {
log.Fatalf("%v", http.ListenAndServe(":80", nil))
}
á€áááá¯ááááºááẠááááºáááºáž 80 ááœáẠHTTP áá¬áá¬ááᯠáá±á¬ááºááœááºáá±ážááẠ(áááºážááẠá¡ááœáá·áºáá°ážáᶠááááºáááºážáá áºáá¯ááŒá áºáááº)á á¡áá»á¬ážá¡á¬ážááŒáá·áº áá»áœááºá¯ááºááá¯á·ááẠáááºážááᯠá á¯á ááºážááŒá®ážáá±á¬áẠáá»ááºáá»ááºážáá¯ááºáá±á¬ááºáááº-
$ go build -o capabilities main.go
$ ./capabilities
ááá¯á·áá±á¬áºá áá»áœááºá¯ááºááá¯á·ááẠroot á¡ááœáá·áºáá°ážáá»á¬ážááᯠááá±ážáá±á¬ááŒá±á¬áá·áºá port ááᯠbinding áá¯ááºáá±á¬á¡áá«á á€áá¯ááºááẠá¡ááŸá¬ážá¡ááœááºážááŒá áºááœá¬ážáááº-
2019/04/25 23:17:06 listen tcp :80: bind: permission denied
exit status 1
capsh (shell manager) ááẠáááá»áá±á¬á áœááºážáááºá¡á á¯á¶ááŒáá·áº shell áá áºáá¯ááᯠrun ááá·áºáááááá¬áá áºáá¯ááŒá áºáááºá
á€ááá á¹á ááœááºá áá±á¬áºááŒáá¬ážááŒá®ážááŒá áºááá·áºá¡ááá¯ááºážá á¡ááŒáá·áºá¡ááááá¯ááºááœáá·áºáá»á¬ážááᯠáá±ážááá·áºá¡á á¬ážá áááá¯ááááºááœááºááŸáááŒá®ážáá¬ážá¡áá¬á¡á¬ážáá¯á¶ážááŸáá·áºá¡áá° cap_net_bind_service á áœááºážáááºááᯠáá±ážááŒááºážááŒáá·áº áááºááẠprivileged port binding ááᯠááœáá·áºááá¯ááºáááºá áááºážááá¯áá¯ááºáá±á¬ááºááẠáá»áœááºá¯ááºááá¯á·ááááá¯ááááºááᯠcapsh ááŒáá·áº ááá·áºááœááºážááá¯ááºáááº-
# capsh --caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep'
--keep=1 --user="nobody"
--addamb=cap_net_bind_service -- -c "./capabilities"
áá®á¡ááœá²á·ááᯠáááºážáááºážáá¬ážáááºáá¡á±á¬ááºá
- capsh - capsh ááᯠshell á¡ááŒá áºá¡áá¯á¶ážááŒá¯áá«á
- âcaps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' - áá»áœááºá¯ááºááá¯á·ááẠá¡áá¯á¶ážááŒá¯áá°ááᯠááŒá±á¬ááºážáá²ááẠááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº (áá»áœááºá¯ááºááá¯á·ááẠroot á¡áá±ááŒáá·áº ááá¯ááºáá±á¬ááºááá¯áá«) cap_net_bind_service ááᯠáááºááŸááºáá±ážáááºááŒá áºááŒá®áž á¡áá¯á¶ážááŒá¯áá° ID ááᯠá¡ááŸááºáááẠááŒá±á¬ááºážáá²ááá¯ááºá á±áááºááŒá áºáááºá cap_setuid ááŸáá·áº cap_setgid ááᯠáááºáá°á០root áá¯ááºáá«á
- âkeep=1 â áá»áœááºá¯ááºááá¯á·ááẠroot á¡áá±á¬áá·áºááŸááŒá±á¬ááºážáá±á¬á¡áá«ááœáẠááá·áºááœááºážáá¬ážáá±á¬á áœááºážáááºáá»á¬ážááᯠááááºážááááºážáá¬ážááá¯áá«áááºá
- âuser=ânobodyâ â áááá¯ááááºááᯠá¡áá¯á¶ážááŒá¯áá°ááẠáááºáá°áá»áŸ ááŒá áºáááºááá¯ááºáá±á
- âaddamb=cap_net_bind_service â á¡ááŒá áºáá¯ááºááŸááŒá±á¬ááºážááŒá®ážáá±á¬áẠáááºááá¯ááºáá¬á áœááºážáááºáá»á¬ážááᯠááŸááºážáááºážáááºááŸááºáá«á
- - -c "./capabilities" - áááá¯ááááºááᯠrun ááá¯ááºáá«á
áá»áááºáááºáá¬ážáá±á¬á áœááºážáááºáá»á¬ážááẠáááºááŸááááá¯ááááºá áááºážááá¯á·ááᯠexecve() ááá¯á¡áá¯á¶ážááŒá¯á áá¯ááºáá±á¬ááºááá·áºá¡áá« ááá±ážáááá¯ááááºáá»á¬ážá០á¡ááœá±áááºáá¶ááá·áº á¡áá°ážá áœááºážáááºáá áºáá»áá¯ážááŒá áºáááºá áááºá ááºááá¯ááºááœáá·áºááŸááá±á¬ á áœááºážáááºáá»á¬ážáᬠááá¯á·ááá¯áẠááááºážá¡á¬ážááŒáá·áº áááºáááºážáá»ááºá áœááºážáááºáá»á¬ážá¡ááŒá Ạá¡ááœá±áááºáá¶ááá¯ááºáá«áááºá
--caps ááœá±ážáá»ááºááŸá¯ááœáẠáá¯ááºááá¯ááºá áœááºážááᯠáááºááŸááºááŒá®ážáá±á¬áẠ+eip á áá¬ááá¯ááá¯ááá¯áááºááᯠáááºá¡á¶á·ááŒáá±áá±áááºá á áœááºážáááºááᯠáá¯á¶ážááŒááºááẠá€á¡áá¶áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯áááº-
- activated ááŒá áºáááẠ(p);
- á¡áá¯á¶ážááŒá¯ááẠ(á);
- ááá±ážáá¯ááºáááºážá ááºáá»á¬ážááŒáá·áº á¡ááœá±áááºáá¶ááá¯ááºááẠ(i)á
cap_net_bind_service ááᯠá¡áá¯á¶ážááŒá¯ááá¯áá±á¬ááŒá±á¬áá·áºá áááºážááᯠe á¡áá¶ááŒáá·áº ááŒá¯áá¯ááºááẠááá¯á¡ááºáá«áááºá ááá¯á·áá±á¬áẠcommand ááœáẠshell ááá¯á áááºáá«áááºá áááºážááẠáá¯ááºáá±á¬ááºááá¯ááºá áœááºáž binary ááᯠáá¯ááºáá±á¬ááºáááºááŒá áºááŒá®áž áááºážááᯠi á¡áá¶ááŒáá·áº á¡ááŸááºá¡áá¬ážááŒá¯ááẠááá¯á¡ááºáááºá áá±á¬ááºáá¯á¶ážááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááºá¹áá«áááºááᯠááœáá·áºáá¬ážá á±ááá¯ááẠ(áá»áœááºá¯ááºááá¯á·ááẠUID ááᯠáááŒá±á¬ááºážáá²áá² áááºážááᯠp ááŒáá·áº ááŒá¯áá¯ááºáá²á·áááº)á cap_net_bind_service+eip ááŒá áºáá¯á¶ááááºá
ss ááá¯á¡áá¯á¶ážááŒá¯á ááááºááá¯áááºá á áºáá±ážááá¯ááºáááºá á á¬áá»ááºááŸá¬áá±á«áºááœáẠá¡á¶áááºááœááºáá»ááŒá áºá á±ááẠá¡ááœááºááᯠá¡áááºážááẠá¡ááá¯áá»á¯á¶ážááŒáá«á áá¯á·á ááá¯á·áá±á¬áº áááºážááẠ0 ááŸááœá²á á¡ááŒá¬ážáááºá ááºáá±á¬ port ááŸáá·áº á¡áá¯á¶ážááŒá¯áá° ID ááá¯ááŒááááºááŒá áºááŒá®ážá á€ááá á¹á ááœáẠ65-
# ss -tulpn -e -H | cut -d' ' -f17-
128 *:80 *:*
users:(("capabilities",pid=30040,fd=3)) uid:65534 ino:11311579 sk:2c v6only:0
á€ááá°áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠcapsh ááá¯á¡áá¯á¶ážááŒá¯áááºá ááá¯á·áá±á¬áº áááºááẠlibcap ááá¯á¡áá¯á¶ážááŒá¯á shell ááá¯áá±ážááá¯ááºáááºá ááá¯ááá¯ááááŸáááá¯áá«áá man 3 libcap ááá¯ááŒáá·áºáá«á
áááá¯ááááºááœá±áá±ážáá²á·á¡áá«á áá±á¬á·ááºáá²áá±ážáá¬ážáá°áᬠáááá¯ááááºáááºáááºáá±áá»áááºááŸá¬ ááá¯á¡ááºáá±áá²á· á¡ááºá¹áá«áááºá¡á¬ážáá¯á¶ážááᯠááŒáá¯ááááááºáá«áá°ážá ááá¯á·á¡ááŒááºá á€á¡ááºá¹áá«áááºáá»á¬ážááẠáá¬ážááŸááºážá¡áá áºáá»á¬ážááœáẠááŒá±á¬ááºážáá²ááá¯ááºáááºá
áá»áœááºá¯ááºááá¯á·ááááá¯ááááºáá áœááºážáááºáá»á¬ážááᯠááá¯ááá¯áá±á¬ááºážááœááºá áœá¬áá¬ážáááºáááºá cap_capable kernel áá¯ááºáá±á¬ááºáá»ááºá¡ááœáẠkprobe ááᯠáááºááŸááºáá±ážááá·áº BCC á áœááºážáááºááŸááá±á¬ áááááá¬ááᯠáá»áœááºá¯ááºááá¯á·áá°ááá¯ááºáááº-
/usr/share/bcc/tools/capable
TIME UID PID TID COMM CAP NAME AUDIT
10:12:53 0 424 424 systemd-udevd 12 CAP_NET_ADMIN 1
10:12:57 0 1103 1101 timesync 25 CAP_SYS_TIME 1
10:12:57 0 19545 19545 capabilities 10 CAP_NET_BIND_SERVICE 1
cap_capable kernel áá¯ááºáá±á¬ááºáá»ááºááŸá one-liner kprobe ááŒáá·áº bpftrace ááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áº áá°áá®áá±á¬á¡áá¬ááᯠáááŸáááá¯ááºáá«áááºá
bpftrace -e
'kprobe:cap_capable {
time("%H:%M:%S ");
printf("%-6d %-6d %-16s %-4d %dn", uid, pid, comm, arg2, arg3);
}'
| grep -i capabilities
áá»áœááºá¯ááºááá¯á·á áááá¯ááááºá á áœááºážáá±á¬ááºáááºáá»á¬ážááᯠkprobe ááŒá®ážáá±á¬áẠááœáá·áºáá¬ážáá«áá
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 10 1
ááá¹á ááá±á¬áºáá¶ááẠáá¯ááºáááºážá ááºááá¯á¡ááºááá·áº á áœááºážáááºáá»á¬ážááŒá áºááŒá®ážá á€á¡ááœááºááœáẠá á¬áááºážá á áºááá¯ááºááá·áºááŒá áºáááºáá»á¬ážáá«áááºáá±á¬ááŒá±á¬áá·áºá á á¬áááºážá á áºááá¯ááºááá·áºá á áºáá±ážááŸá¯áá»á¬ážá¡á¬ážáá¯á¶ážááᯠáá»áœááºá¯ááºááá¯á·ááœá±á·ááŒááºáááŒá®áž áá±á¬ááºáá¯á¶ážááœáẠá á¬áááºážá á áºá¡áᶠ(ááœááºááŸááá±á¬ááºáá¯á¶áž) ááœáẠááá¯á¡ááºáá±á¬á áœááºážáááºááᯠ1. á áœááºážáá±á¬ááºáááºáᯠáááºááŸááºáá¬ážáááºá áá»áœááºá¯ááºááá¯á·á áááºáááºá á¬ážááá·áºáá áºáá¯ááŸá¬ CAP_NET_BIND_SERVICE ááŒá áºááŒá®ážá áááºážááᯠááá¯ááºááŸá kernel á¡áááºážá¡ááŒá áºáá¯ááºááœáẠááááºážáá±á¡ááŒá ẠáááºááŸááºáá¬ážáááº-
/* Allows binding to TCP/UDP sockets below 1024 */
/* Allows binding to ATM VCIs below 32 */
#define CAP_NET_BIND_SERVICE 10<source lang="go">
áááºážááá¯á·á¡á¬áž á¡ááœáá·áºáá°ážááá¶áá±á¬áá¯ááºááœáẠáááºáááºááœáá·áºááŒá¯ááẠrunC ááá¯á·ááá¯áẠDocker áá²á·ááá¯á·áá±á¬ ááœááºááááºáá¬áá»á¬ážá¡ááœáẠáá¯ááºáá±á¬ááºááá¯ááºá áœááºážáá»á¬ážááᯠáááŒá¬áá ááœáá·áºáá¬ážáá±á¬áºáááºáž áááºážááá¯á·ááẠá¡ááá®áá±ážááŸááºážá¡áá»á¬ážá á¯ááᯠáá¯ááºáá±á¬ááºááẠááá¯á¡ááºáá±á¬á áœááºážáááºáá»á¬ážááá¯áᬠááœáá·áºááŒá¯áá¬ážáááºá á¡ááá®áá±ážááŸááºážáá áºáá¯ááẠá¡áá»áá¯á·áá±á¬á áœááºážáááºáá»á¬áž ááá¯á¡ááºáá±á¬á¡áá«á Docker ááẠ--cap-add ááᯠá¡áá¯á¶ážááŒá¯á áááºážááá¯á·ááᯠáá¶á·ááá¯ážáá±ážááá¯ááºáááºá
docker run -it --rm --cap-add=NET_ADMIN ubuntu ip link add dummy0 type dummy
á€á¡áááá·áºááẠááœááºááááºáá¬á¡á¬áž CAP_NET_ADMIN á áœááºážáááºááᯠáá±ážá áœááºážáááºááŒá áºááŒá®áž dummy0 á¡ááºáá¬áá±á·á áºááᯠááá·áºááẠááœááºáááºááá·áºááºáá áºáá¯ááᯠá á®á ááºáááºááŸááºááá¯ááºá á±áááºááŒá áºáááºá
áá±á¬ááºá¡ááá¯ááºážááœáẠá á áºáá¯ááºááŒááºážáá²á·ááá¯á·áá±á¬ á¡ááºá¹áá«áááºáá»á¬ážááᯠáááºááá¯á·á¡áá¯á¶ážááŒá¯ááááºááᯠááŒááá¬ážáá±á¬áºáááºáž áá»áœááºá¯ááºááá¯á·áááá¯ááºááá¯áẠfilter áá»á¬ážááᯠáááá¯ááááºá áá áºááá»á¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºá á±ááá·áº ááá°áá®áá±á¬áááºážááá¬ááᯠá¡áá¯á¶ážááŒá¯áá¬ážáááºá
Seccomp
Seccomp ááẠSecure Computing ááᯠááá¯ááºá á¬ážááŒá¯ááŒá®áž á¡áá»áá¯á·áá±á¬ á áá áºáá±á«áºááá¯ááŸá¯áá»á¬ážááᯠdeveloper áá»á¬ážá¡á¬áž á á áºáá¯ááºááœáá·áºááŒá¯ááá·áº Linux kernel ááœáẠá¡áá±á¬ááºá¡áááºáá±á¬áºááá·áº áá¯á¶ááŒá¯á¶áá±ážá¡ááœáŸá¬áá áºáá¯ááŒá áºáááºá Seccomp ááẠLinux ááŸáá·áº ááŸááºááá¯ááºáá±á¬áºáááºážá á¡áá»áá¯á·áá±á¬ á áá áºáá±á«áºááá¯ááŸá¯áá»á¬ážááᯠá á®áá¶ááá·áºááœá²ááá¯ááºá áœááºážááẠáááºážááá¯á·ááŸáá·áº ááŸáá¯ááºážááŸááºáá«á ááá¯ááá¯ááŒá±á¬ááºážááœááºááŒááºááœááºááŸáá á±áááºá
Seccomp ááŸáá·áº Linux á¡ááºá¹áá«áááºáá»á¬ážááẠá¡ááŒááºá¡ááŸááºáá®ážááá·áºááá¯ááºááá·áºá¡ááŒáẠáá»ááºážáááºááŸá¯ááŸá áºáá¯á áá¯á¶ážá០á¡áá»áá¯ážááŸáá á±ááẠáááŒá¬áá á¡áá°áááœá¡áá¯á¶ážááŒá¯ááŒáááºá á¥ááá¬á¡á¬ážááŒáá·áºá áááºááẠCAP_NET_ADMIN á áœááºážáááºááᯠáá¯ááºáááºážá ááºáá áºáᯠáá±ážááá¯áá±á¬áºáááºáž áááºážááᯠsocket áá»áááºáááºááŸá¯áá»á¬ážááᯠáááºáá¶áááºá áááºáá¶ááŒááºážááŸáá·áº áááºáá¶ááŒááºáž 4 á áá áºáá±á«áºááá¯ááŸá¯áá»á¬ážááᯠááááºááá¯á·ááŒááºážá០ááœáá·áºáááŒá¯áá«á
Seccomp á á áºáá¯ááºááŒááºážáááºážáááºážááẠSECOMP_MODE_FILTER áá¯ááºááœáẠáá¯ááºáá±á¬ááºáá±áá±á¬ BPF á á áºáá¯ááºááŸá¯áá»á¬ážá¡áá±á«áº á¡ááŒá±áá¶áá¬ážááŒá®áž á áá áºáá±á«áºááá¯ááŸá¯ á á áºáá¯ááºááŒááºážá¡á¬áž áááºáááºáá»á¬ážá¡ááœááºáá²á·ááá¯á· á¡áá¬ážáá°áááºážáááºážááŒáá·áº áá¯ááºáá±á¬ááºáá«áááºá
PR_SET_SECOMP áááºáááºááŸá¯ááŸáááá·áº prctl ááᯠá¡áá¯á¶ážááŒá¯á Seccomp á á áºáá¯ááºááŸá¯áá»á¬ážááᯠáááºáá¬ážáááºá á€á á áºáá¯ááºááŸá¯áá»á¬ážááẠseccomp_data ááœá²á·á ááºážáá¯á¶ááŒáá·áºááá¯ááºá á¬ážááŒá¯áá±á¬ Seccomp áááºáááºáá áºáá¯á á®á¡ááœáẠáá¯ááºáá±á¬ááºááá·áº BPF áááá¯ááááºááá¯á¶á á¶ááŒá áºáááºá á€ááœá²á·á ááºážáá¯á¶ááœáẠá¡ááá¯ážá¡áá¬ážáááá¯áá¬á á áá áºáá±á«áºááá¯áá»áááºááœáẠáááá¯áááºáá¬áááºážááœáŸááºáá»ááºáá áºáá¯ááŸáá·áº uint64 á¡ááŒá áºáá±á¬áºááŒáá±á¬ á¡áá»á¬ážáá¯á¶ážááŒá±á¬ááºáá¯áá±á¬ á áá áºáá±á«áºááá¯ááŸá¯ááá¯ááºáᬠá¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬áž áá«áááºáá«áááºá
áááºážááẠlinux/seccomp.h ááá¯ááºááŸá kernel á¡áááºážá¡ááŒá áºáá¯ááºá០seccomp_data áááºáá±á¬ááºáá¯á¶ááŸáá·áº áá°áááº-
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
á€ááœá²á·á ááºážáá¯á¶á០áááºááœá±á·ááŒááºáááá·áºá¡ááá¯ááºážá áá»áœááºá¯ááºááá¯á·ááẠá áá áºáá±á«áºááá¯ááŸá¯á áááºážá á¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬ážá ááá¯á·ááá¯áẠááŸá áºáá¯áá¯á¶ážááᯠáá±á«ááºážá ááºááŒááºážááŒáá·áº á á áºáá¯ááºááá¯ááºáá«áááºá
Seccomp packet áá áºáá¯á á®ááᯠáááºáá¶áááŸáááŒá®ážáá±á¬ááºá filter ááẠáá±á¬ááºáá¯á¶ážáá¯á¶ážááŒááºáá»ááºáá áºáá¯áá»áááºááŸáá·áº kernel ááᯠáá¬áááºáá¯ááºááááºáááºážá áá±á¬ááºáá¯á¶ážáá¯á¶ážááŒááºáá»ááºááᯠááŒááºáá±ážáááºááá¯ážáá»á¬áž (á¡ááŒá±á¡áá±áá¯ááºáá»á¬áž) á០áá¯ááºáá±á¬áºáááºá
- SECOMP_RET_KILL_PROCESS - áááºážááŒá±á¬áá·áº ááá¯ááºáá±á¬ááºááá¯ááºáá±á¬ á áá áºáá±á«áºááá¯ááŸá¯ááᯠá á áºáá¯ááºááŒá®ážáá±á¬áẠáá¯ááºáááºážá ááºáá áºáá¯áá¯á¶ážááᯠáá»ááºáá»ááºážáááºáá áºáááºá
- SECOMP_RET_KILL_THREAD - á€á¡áá¬ááŒá±á¬áá·áº ááá¯ááºáá±á¬ááºááá¯ááºáá±á¬ á áá áºáá±á«áºááá¯ááŸá¯áá áºáá¯ááᯠá á áºáá¯ááºááŒá®ážáá±á¬áẠáá»ááºáá»ááºážááẠáááºááŸáá á¬ááœá²ááᯠáááºá á²áááºá
â SECOMP_RET_KILL â SECOMP_RET_KILL_THREAD á¡ááœáẠáá¶áááºá áá±á¬ááºááŒááºááá¯ááºáááºááá¯ááºá á±ááẠáá»ááºáá¬ážáá²á·áááºá
- SECOMP_RET_TRAP - á áá áºáá±á«áºááá¯ááŸá¯ááᯠáá¬ážááŒá áºáá¬ážááŒá®áž SIGSYS (Bad System Call) á¡áá»ááºááŒááŸá¯ááᯠáááºážááá¯áá±á«áºááá¯ááá·áºáá¯ááºáááºážáá¬áááºáᶠáá±ážááá¯á·áááºá
- SECOMP_RET_ERRNO - á áá áºáá±á«áºááá¯ááŸá¯á¡á¬áž áá¯ááºáá±á¬ááºááŒááºážáááŸááá«á ááŸáá·áº SECOMP_RET_DATA á á áºáá¯ááºááŒááºážááá áºá áááºáá áºááá¯ááºážááᯠerrno áááºááá¯ážá¡ááŒá Ạá¡áá¯á¶ážááŒá¯áá°áá±áá¬ááá¯á· ááœáŸá²ááŒá±á¬ááºážáá±ážáá«áááºá á¡ááŸá¬ážáá¡ááŒá±á¬ááºážáááºážáá±á«áºáá°áááºá ááá°áá®áá±á¬ errno áááºááá¯ážáá»á¬ážááᯠááŒááºáá±ážáááºá áá±á¬ááºá¡ááá¯ááºážááœáẠá¡ááŸá¬ážáá¶áá«ááºáá»á¬ážá á¬áááºážááᯠáá±ážáá¬ážáááºá
- SECOMP_RET_TRACE - ááá¯áá¯ááºáááºážá ááºááá¯ááŒáá·áºááŸá¯áááºááŸáá·áº ááááºážáá»á¯ááºáááºá¡ááœáẠá áá áºáá±á«áºááá¯ááŸá¯ááᯠáá¯ááºáá±á¬ááºááá·áºá¡áá« ááŒá¬ážááŒááºááẠ- PTRACE_O_TRACESECCOMP ááᯠââá¡áá¯á¶ážááŒá¯á ptrace ááŒá±áá¬áá¶ááᯠá¡ááŒá±á¬ááºážááŒá¬ážááẠá¡áá¯á¶ážááŒá¯áá«áááºá ááŒá±áá¬áá¶áááááá¬ááᯠááá»áááºáááºáá«á á¡ááŸá¬ážá¡ááœááºážáá áºáᯠááŒááºáá¬áááºá errno ááᯠ-ENOSYS áá¯áááºááŸááºáá¬ážááŒá®áž á áá áºáá±á«áºááá¯ááŸá¯ááᯠáá¯ááºáá±á¬ááºáááºááá¯ááºáá«á
- SECOMP_RET_LOG - á áá áºáá±á«áºááá¯ááŸá¯ááᯠááŒá±ááŸááºážááŒá®áž á¡áá±á¬áá·áºáááºáá¬ážáááºá
- SECOMP_RET_ALLOW - á áá áºáá±á«áºááá¯ááŸá¯ááᯠááá¯ážááŸááºážá áœá¬ ááœáá·áºááŒá¯áá¬ážáááºá
ptrace ááẠtracee áá¯áá±á«áºáá±á¬ áá¯ááºáááºážá ááºáá áºáá¯ááœáẠááŒá±áá¬áá¶ááá¹ááá¬ážáá»á¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááẠá áá áºáá±á«áºááá¯ááŸá¯ááŒá áºááŒá®áž áá¯ááºáááºážá ááºááá¯ááºáá±á¬ááºááŸá¯ááᯠá á±á¬áá·áºááŒáá·áºááááºážáá»á¯ááºááá¯ááºá áœááºážááŸááááºá ááŒá±áá¬áá¶áááá¯ááááºááẠáá¯ááºáá±á¬ááºááŸá¯ááᯠáááááá±á¬ááºáá±á¬áẠááœáŸááºážááá¯ážááá¯ááºááŒá®áž tracee á ááŸááºáá¬ááºá á¬áááºážáá»á¬ážááᯠááœááºážáá¶ááá¯ááºáááºá Seccomp á¡ááŒá±á¬ááºážá¡áá¬ááœáẠSECOMP_RET_TRACE á¡ááŒá±á¡áá±áá¯ááºááŒáá·áº á¡á áá»áá¯ážáá±á¬á¡áá« ptrace ááᯠá¡áá¯á¶ážááŒá¯áááºá ááá¯á·ááŒá±á¬áá·áº tracer ááẠá áá áºáá±á«áºááá¯ááŸá¯ááᯠáá¯ááºáá±á¬ááºááŒááºážá០áá¬ážáá®ážááá¯ááºááŒá®áž áááºážáááá¯ááºááá¯áẠlogic ááᯠá¡áá±á¬ááºá¡áááºáá±á«áºááŒááºážá០áá¬ážáá®ážááá¯ááºáá«áááºá
Seccomp á¡ááŸá¬ážáá»á¬áž
áá¶áááºáá¶áá«á Seccomp ááŸáá·áºá¡áá¯ááºáá¯ááºáá±á ááºá áááºááẠSECOMP_RET_ERRNO á¡áá»áá¯ážá¡á á¬ážááŒááºáááºááá¯ážááŒáá·áºáááºááŸááºáá¬ážáá±á¬ á¡áá»áá¯ážáá»áá¯ážáá±á¬á¡ááŸá¬ážá¡ááœááºážáá»á¬ážááá¯ááŒá¯á¶ááœá±á·ááááá·áºáááºá á¡ááŸá¬ážá¡ááœááºážáá áºáá¯ááᯠááááºážááá¯á·áááºá seccomp á áá áºáá±á«áºááá¯ááŸá¯ááẠ1 á¡á á¬áž -0 ááá¯á· ááŒááºááœá¬ážáá«áááºá
á¡á±á¬ááºáá« á¡ááŸá¬ážáá»á¬áž ááŒá áºááá¯ááºáááº-
- EACCESS - áá±á«áºááá¯áá°á¡á¬áž á áá áºáá±á«áºááá¯ááŸá¯ááŒá¯áá¯ááºááẠááœáá·áºáááŒá¯áá«á áááºážááœáẠCAP_SYS_ADMIN á¡ááœáá·áºáá°ážáá»á¬áž áááŸááá±á¬ááŒá±á¬áá·áº ááá¯á·ááá¯áẠno_new_privs ááᯠprctl ááᯠá¡áá¯á¶ážááŒá¯á ááááºááŸááºáá¬ážáá±á¬ááŒá±á¬áá·áº ááŒá áºáááºááẠ(áá»áœááºá¯ááºááá¯á· á€á¡ááŒá±á¬ááºážááᯠáá±á¬ááºá០ááœá±ážááœá±ážáá«áááº)á
â EFAULT â ááœááºáá²á·áá±á¬ á¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬áž (seccomp_data áááºáá±á¬ááºáá¯á¶ááŸá args) ááœáẠááŸááºáááºáá±á¬ááááºá ᬠáááŸááá«á
â EINVAL â á€áá±áá¬ááœáẠá¡ááŒá±á¬ááºážáááºážáá±ážáá¯ááŸáááá¯ááºáááº-
- áááºááŸáááœá²á·á ááºážáá¯á¶ááœáẠkernel á០áá±á¬ááºážááá¯áá¬ážáá±á¬ áá¯ááºáá±á¬ááºáá»ááºááᯠáááááŸá ááá¯á·ááá¯áẠááá¶á·ááá¯ážáá«á
- áá±á¬ááºážááá¯áá¬ážáá±á¬ áá¯ááºáá±á¬ááºáá»ááºá¡ááœáẠáááºááŸááºáá¬ážáá±á¬ á¡áá¶áá»á¬ážááẠáááŸááºáááºáá«á
-operation ááœáẠBPF_ABS áá«áááºáááºá ááá¯á·áá±á¬áº seccomp_data ááœá²á·á ááºážáá¯á¶á á¡ááœááºá¡á á¬ážááẠáá»á±á¬áºááœááºááá¯ááºáá±á¬ áááºááŸááºáá¬ážáá±á¬ offset ááŸáá·áº ááŒá¿áá¬áá»á¬ážááŸááá«áááºá
- filter ááá¯á·áá±ážááá¯á·áá±á¬ ááœáŸááºááŒá¬ážáá»ááºá¡áá±á¡ááœááºááẠá¡áá»á¬ážáá¯á¶ážááẠáá»á±á¬áºááœááºáá±áá«áááºá
â ENOMEM â áááá¯ááááºááá¯áá¯ááºáá±á¬ááºááẠááá¯á¶áá±á¬ááºáá±á¬ááŸááºáá¬ááºá
- EOPNOTSUPP - áá¯ááºáá±á¬ááºáá»ááºááẠSECCOMP_GET_ACTION_AVAIL ááŒáá·áº áá¯ááºáá±á¬ááºáá»ááºááᯠáááŸáááá¯ááºáááºáᯠááœáŸááºááŒáá±á¬áºáááºáž kernel ááẠá¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬ážááœáẠááŒááºáá¬ááŒááºážááᯠááá¶á·ááá¯ážáá«á
â ESRCH â á¡ááŒá¬ážá á®ážááŒá±á¬ááºážááᯠá áá·áºááºáá¯ááºáá±á¬á¡áá« ááŒá¿áá¬áá áºáᯠááŒá áºááœá¬ážáá²á·áááºá
- ENOSYS - SECOMP_RET_TRACE áá¯ááºáá±á¬ááºáá»ááºááŸáá·áº ááœá²áá¬ážááá·áº ááŒá±áá¬áᶠáááŸááá«á
prctl ááẠá¡áá¯á¶ážááŒá¯áá°-á¡á¬áá¬ááááá¯ááááºá¡á¬áž áá¯ááºáááºážá ááºáá áºáá¯á áá®ážááŒá¬ážááŸá¯áá±á¬áá·áºáá»á¬ážááŒá áºááá·áº byte endiannessá thread namesá secure computation mode (Seccomp)á privilegesá Perf events á áááºááá¯á·áá²á·ááá¯á·áá±á¬ áá¯ááºáááºážá ááºáá áºáá¯á¡á¬áž ááá¯ááºááœááºááẠááœáá·áºááŒá¯ááá·áº á áá áºáá±á«áºááá¯ááŸá¯áá áºáá¯ááŒá áºáááºá
Seccomp ááẠááá·áºá¡ááœáẠsandbox áááºážááá¬áá áºáá¯áá²á·ááá¯á· áááºááá±á¬áºáááºáž áááºážááẠááá¯ááºáá«á Seccomp ááẠá¡áá¯á¶ážááŒá¯áá°áá»á¬ážá¡á¬áž sandbox ááá¹ááá¬ážáá áºáá¯ááᯠáááºáá®ážááá¯ááºá á±ááá·áº á¡áá¯á¶ážáááºááŸá¯áá áºáá¯ááŒá áºáááºá ááᯠSeccomp á áá áºáá±á«áºááá¯ááŸá¯á០ááá¯ááºááá¯ááºáá±á«áºáá±á¬ á á áºáá¯ááºááŸá¯ááᯠá¡áá¯á¶ážááŒá¯á á¡áá¯á¶ážááŒá¯áá° á¡ááŒááºá¡ááŸááºá¡áá»áá¯ážááŒá¯ááá·áº áááá¯ááááºáá»á¬ážááᯠáááºááá¯á·áááºáá®ážáá¬ážáááºááᯠááŒáá·áºááŒáá«á áá¯á·á
BPF Seccomp Filter á¥ááá¬
á€áá±áá¬ááœáẠá á±á¬á á±á¬á ááœá±ážááœá±ážáá²á·ááá·áº áá¯ááºáá±á¬ááºáá»ááºááŸá áºáá¯ááᯠáá±á«ááºážá ááºáááºážááᯠááŒááá«áááºá
â áá»áœááºá¯ááºááá¯á·ááẠSeccomp BPF áááá¯ááááºááᯠáá±ážáá¬ážáááºááŒá áºááŒá®ážá áá¯á¶ážááŒááºáá»ááºáá»á¬ážáá±á«áºáá°áááºá ááá°áá®áá±á¬ááŒááºáá¯ááºáá»á¬ážáá«ááá·áº á á áºáá¯ááºááŸá¯áá áºáá¯á¡ááŒá Ạá¡áá¯á¶ážááŒá¯áááºááŒá áºáááºá
â prctl ááᯠá¡áá¯á¶ážááŒá¯á filter ááᯠáááºáá«á
áŠážá áœá¬ áááºááẠá á¶á á¬ááŒáá·áºááá¯ááºááŸáá·áº Linux kernel ááá¯á·á០áá±á«ááºážá á®ážáá»á¬áž ááá¯á¡ááºáááº-
#include <errno.h>
#include <linux/audit.h>
#include <linux/bpf.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <unistd.h>
á€á¥ááá¬ááᯠáááŒáá¯ážá á¬ážáá®á kernel ááᯠCONFIG_SECCOMP ááŸáá·áº CONFIG_SECOMP_FILTER áá¯áááºááŸááºáá¬ážááŒááºážááŒáá·áº kernel ááᯠá á¯á ááºážáá¬ážááŒá±á¬ááºáž áá±áá»á¬ááá«áááºá á¡áá¯ááºáá¯ááºááá·áºá ááºááœáẠá€áá²á·ááá¯á·á á áºáá±ážááá¯ááºáááº-
cat /proc/config.gz| zcat | grep -i CONFIG_SECCOMP
áá»ááºáá¯ááºááẠááŸá áºááá¯ááºáž install_filter áá¯ááºáá±á¬ááºáá»ááºááŒá áºáááºá áááá¡ááá¯ááºážááœáẠáá»áœááºá¯ááºááá¯á·á BPF á á áºáá¯ááºááŒááºážááá¯ááºáᬠááœáŸááºááŒá¬ážáá»ááºáá»á¬ážá á¬áááºážáá«ááŸááááºá
static int install_filter(int nr, int arch, int error) {
struct sock_filter filter[] = {
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, arch))),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3),
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (error & SECCOMP_RET_DATA)),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
};
áááºážááœáŸááºáá»ááºáá»á¬ážááᯠlinux/filter.h ááá¯ááºááœáẠáááºááŸááºáá¬ážáá±á¬ BPF_STMT ááŸáá·áº BPF_JUMP áááºáááá¯áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á áááºááŸááºáá¬ážáááºá
ááœáŸááºááŒá¬ážáá»ááºáá»á¬ážááŸáááá·áºááœá¬ážááŒáá«á
áá¯á·á
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_dataá arch))) - á áá áºááẠBPF_LD á០BPF_W á áá¬ážáá¯á¶ážáá¯á¶á á¶ááŒáá·áº áá¯ááºááá¯ážááŒá®áž áá¯ááºááá¯ážáá±áá¬ááẠáá¯á¶áá± á¡á±á¬á·ááºááẠBPF_ABS ááœáẠáááºááŸááááºá
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_Ká arch, 0, 3) - BPF_JEQ ááᯠá¡áá¯á¶ážááŒá¯á BPF_K accumulator áááºááá¯ážááẠarch ááŸáá·áº áá®áá»áŸááŒááºážááŸááááŸá á á áºáá±ážáááºá ááá¯á·ááá¯áá»áŸááºá arch ááŸáá·áº áááá¯ááºáá®áá±á¬ááŒá±á¬áá·áº á¡ááŸá¬ážáá áºáá¯ááá¯áá áºááẠoffset 0 (á€ááá á¹á ááœááº) á០áá¯ááºáááºáááºá
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, nr))) - BPF_LD á áá¯á¶áá± á¡á±á¬á·ááºáááºááœááºáá«ááŸááá±á¬ á áá áºáá±á«áºááá¯ááŸá¯áá¶áá«ááºááŒá áºááá·áº BPF_W áá°áá±á¬ á áá¬ážáá¯á¶ážáá¯á¶á á¶ááŒáá·áº BPF_LD á០á á¯á ááºážááá¯ááºáá«áááºá
â BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) â á áá áºáá±á«áºááá¯ááŸá¯áá¶áá«ááºá¡á¬áž nr variable ááááºááá¯ážááŸáá·áº ááŸáá¯ááºážááŸááºáááºá áááºážááá¯á·ááẠáá°áá®áá«áá áá±á¬ááºááœáŸááºááŒá¬ážáá»ááºááá¯á· áááºááœá¬ážáᬠá áá áºáá±á«áºááá¯ááŸá¯ááᯠááááºáá«á ááá¯á·ááá¯ááºáá«á á áá áºáá±á«áºááá¯ááŸá¯ááᯠSECOMP_RET_ALLOW ááŒáá·áº ááœáá·áºááŒá¯áá«áááºá
- BPF_STMT(BPF_RET + BPF_K, SECOMP_RET_ERRNO | (error & SECOMP_RET_DATA)) - BPF_RET ááŒáá·áº áááá¯ááááºááᯠáááºááá¯ááºážááá¯ááºááŒá®áž ááááºá¡áá±ááŒáá·áº SECOMP_RET_ERRNO áá¶áá«ááºááŒáá·áº err variable á¡ááŸá¬ážáá áºáᯠááŒá áºáá±á«áºáá«áááºá
- BPF_STMT(BPF_RET + BPF_Ká SECOMP_RET_ALLOW) - BPF_RET ááŒáá·áº áááá¯ááááºááᯠáááºááá¯ááºážááŒá®áž SECOMP_RET_ALLOW ááᯠá¡áá¯á¶ážááŒá¯á á áá áºáá±á«áºááá¯ááŸá¯ááᯠáá¯ááºáá±á¬ááºááœáá·áºááŒá¯áááºá
SECOMP ááẠCBPF ááŒá áºáááºá
á á¯á ááºážáá¬ážáá±á¬ ELF á¡áá¬ááá¹áᯠááá¯á·ááá¯áẠJIT compiled C áááá¯ááááºá¡á á¬áž ááœáŸááºááŒá¬ážáá»ááºáá»á¬ážá á¬áááºážááᯠá¡áááºááŒá±á¬áá·áº á¡áá¯á¶ážááŒá¯áááŒá±á¬ááºáž áááºá¡á¶á·ááŒáá±áá±áááºááá®á¡ááœáẠá¡ááŒá±á¬ááºážááŒáá»áẠááŸá áºáá¯ááŸááá«áááºá
⢠ááááŠážá áœá¬á Seccomp ááẠcBPF (ááá¹áááẠBPF) ááá¯á¡áá¯á¶ážááŒá¯ááŒá®áž eBPF ááá¯ááºáá²á ááá¯ááá¯áááºááŸá¬- áááºážááœáẠá á¬áááºážááœááºážááŸá¯áá»á¬ážáááŸááá±á¬áºáááºáž ááá°áá¬ááœááºááœá±á·ááá¯ááºááá·áºá¡ááá¯ááºáž áá±á¬ááºáá¯á¶ážááœááºáá»ááºááŸá¯ááááºááᯠááááºážáááºážáááºá¡ááœáẠá á¯á ááºážááŸá¯áá áºáá¯áá¬ááŒá áºáááºá
⢠áá¯áááá Seccomp ááẠBPF ááœáŸááºááŒá¬ážáá»ááºáá»á¬ážá array áá áºáá¯áá®ááá¯á· ááœáŸááºááŒáá»ááºááᯠáááºáá¶ááŒá®áž á¡ááŒá¬ážáá¬áá»áŸáááŸááá«á áá»áœááºá¯ááºááá¯á·á¡áá¯á¶ážááŒá¯áá¬ážáá±á¬ áááºáááá¯áá»á¬ážááẠáááá¯ááááºáá¬áá»á¬ážá¡ááœáẠá¡áááºááŒá±áá±á¬áááºážáááºážááŒáá·áº á€ááœáŸááºááŒá¬ážáá»ááºáá»á¬ážááᯠáááºááŸááºáá¬ááœáẠáá°áá®áá±ážáá«áááºá
á€á ááºážáá±ážááœá²á¡á¬áž áá¬ážáááºááẠáá±á¬ááºáááºá¡áá°á¡áá® ááá¯á¡ááºáá«áá áá°áá®áá±á¬á¡áá¬ááᯠáá¯ááºáá±á¬ááºááá·áº pseudocode ááᯠá ááºážá á¬ážáá«-
if (arch != AUDIT_ARCH_X86_64) {
return SECCOMP_RET_ALLOW;
}
if (nr == __NR_write) {
return SECCOMP_RET_ERRNO;
}
return SECCOMP_RET_ALLOW;
socket_filter ááœá²á·á ááºážáá¯á¶ááŸá filter áá¯ááºááᯠáááºááŸááºááŒá®ážáá±á¬ááºá áá¯ááºááŸáá·áº filter á ááœááºáá»ááºáá¬ážáá±á¬ á¡ááŸááºáá«ááŸááá±á¬ sock_fprog ááᯠáááºááŸááºááẠááá¯á¡ááºáááºá áá±á¬ááºááá¯ááºážááœáẠáá¯ááºáá±á¬ááºááẠáá¯ááºáááºážá ááºááᯠááŒá±áá¬áááºá¡ááœáẠá€áá±áá¬ááœá²á·á ááºážáá¯á¶ááẠááá¯á¡ááºáááº-
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
.filter = filter,
};
install_filter áá¯ááºáá±á¬ááºáá»ááºááœáẠáá¯ááºá áá¬áá áºáá¯áᬠáá»ááºáá±á¬á·ááẠ- áááá¯ááááºááᯠáá°á·áá¬áá¬áá° áááºáá«á áááºážááá¯áá¯ááºáá±á¬ááºáááºá áá»áœááºá¯ááºááá¯á·ááẠPR_SET_SECOMP á¡á¬áž áá¯á¶ááŒá¯á¶áá±á¬ááœááºáá»á°áá¬áá¯ááºááá¯á·áááºáá±á¬ááºááẠááœá±ážáá»ááºááŸá¯áá áºáá¯á¡ááŒá Ạprctl ááá¯á¡áá¯á¶ážááŒá¯áááºá ááá¯á·áá±á¬áẠsock_fprog á¡áá»áá¯ážá¡á á¬ážá prog variable ááœááºáá«ááŸááá±á¬ SECOMP_MODE_FILTER ááá¯á¡áá¯á¶ážááŒá¯á filter ááá¯ááœáá·áºáááºáá¯ááºá¡á¬áž áá»áœááºá¯ááºááá¯á·ááŒá±á¬áááº-
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
perror("prctl(PR_SET_SECCOMP)");
return 1;
}
return 0;
}
áá±á¬ááºáá¯á¶ážááœááºá áá»áœááºá¯ááºááá¯á·ááẠáá»áœááºá¯ááºááá¯á·á install_filter áá¯ááºáá±á¬ááºáá»ááºááᯠá¡áá¯á¶ážááŒá¯ááá¯ááºááŒá®ážá ááá¯á·áá±á¬áº áááºááŸááá¯ááºáá±á¬ááºááŸá¯á¡ááœáẠPR_SET_NO_NEW_PRIVS ááᯠáááºááŸááºááẠprctl ááᯠá¡áá¯á¶ážááŒá¯áááºááá¯á¡ááºááŒá®áž ááá¯á·ááŒá±á¬áá·áº ááá±ážáá¯ááºáááºážá ááºáá»á¬ážááẠáááºážááá¯á·áááááá»á¬ážááẠááá¯ááá¯á¡ááœáá·áºáá°ážáá»á¬ážáááŸáááá·áºá¡ááŒá±á¡áá±ááᯠááŸá±á¬ááºááŸá¬ážááẠááá¯á¡ááºáá«áááºá á€á¡áá¬ááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠroot áá¯ááºááá¯ááºááœáá·áºáááŸááá² á¡á±á¬ááºáá« prctl áá±á«áºááá¯ááŸá¯áá»á¬ážááᯠinstall_filter áá¯ááºáá±á¬ááºáá»ááºááœáẠááŒá¯áá¯ááºááá¯ááºáá«áááºá
ááá¯áá»áœááºá¯ááºááá¯á·ááẠinstall_filter áá¯ááºáá±á¬ááºáá»ááºááá¯áá±á«áºááá¯ááá¯ááºáááºá X86-64 áááá¯áá¬ááŸáá·áºáááºá ááºáá±á¬ á á¬áá±ážá áá áºáá±á«áºááá¯ááŸá¯áá»á¬ážá¡á¬ážáá¯á¶ážááᯠááááºááá¯á·ááŒá®áž ááŒáá¯ážá á¬ážááŸá¯á¡á¬ážáá¯á¶ážááᯠááááºááá¯á·ááá·áº ááœáá·áºááŒá¯áá»ááºáá áºáᯠáá±ážááá¯ááºáá«á á á áºáá¯ááºááŸá¯ááᯠááá·áºááœááºážááŒá®ážáá±á¬ááºá áá»áœááºá¯ááºááá¯á·ááẠáááá¡ááŒááºážá¡áá¯á¶ááᯠá¡áá¯á¶ážááŒá¯á áááºáááºáá¯ááºáá±á¬ááºáááº-
int main(int argc, char const *argv[]) {
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("prctl(NO_NEW_PRIVS)");
return 1;
}
install_filter(__NR_write, AUDIT_ARCH_X86_64, EPERM);
return system(argv[1]);
}
á ááá¯ááºááŒá áá¯á·á áá»áœááºá¯ááºááá¯á·ááááá¯ááááºááᯠá á¯á ááºážáááºá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡áá°ážááœá±ážáá»ááºá áá¬áá»á¬ážááá«áá² main.c ááá¯ááºááᯠááŒá¯á á¯áá¬ááœáẠclang ááá¯á·ááá¯áẠgcc áá áºáá¯áá¯ááᯠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá
clang main.c -o filter-write
ááŸááºáá¬ážáá¬ážááá·áºá¡ááá¯ááºážá áá»áœááºá¯ááºááá¯á·ááẠáááá¯ááááºááŸá ááá·áºááœááºážááŸá¯áá»á¬ážá¡á¬ážáá¯á¶ážááᯠááááºááá¯á·áá¬ážáá«áááºá áááºážááá¯á ááºážáááºáááºá¡ááœáẠáááºááẠáá áºáá¯áá¯ááᯠáá¯ááºáá±ážááá·áº áááá¯ááááºáá áºáᯠááá¯á¡ááºááẠ- ls ááẠáá±á¬ááºážááœááºáá±á¬ ááá¯ááºá á¬ážááŸááºáá áºáŠážááŒá áºáá¯á¶ááááºá á€áááºááŸá¬ áá°á ááŒá¯áá°áá±á·ááŸááááº-
ls -la
total 36
drwxr-xr-x 2 fntlnz users 4096 Apr 28 21:09 .
drwxr-xr-x 4 fntlnz users 4096 Apr 26 13:01 ..
-rwxr-xr-x 1 fntlnz users 16800 Apr 28 21:09 filter-write
-rw-r--r-- 1 fntlnz users 19 Apr 28 21:09 .gitignore
-rw-r--r-- 1 fntlnz users 1282 Apr 28 21:08 main.c
á¡á¶á·ááŒááœááº! á€áááºááŸá¬ áá»áœááºá¯ááºááá¯á·á wrapper áááá¯ááááºááᯠá¡áá¯á¶ážááŒá¯á áá¯á¶ááá¹áá¬ááºáá°áááº- áá»áœááºá¯ááºááá¯á·ááẠáááá¡ááŒááºážá¡áá¯á¶á¡ááŒá Ạáá»áœááºá¯ááºááá¯á· á ááºážáááºááá¯áá±á¬ áááá¯ááááºááᯠááá¯ážááŸááºážá áœá¬ áá»á±á¬áºááŒááºáááº-
./filter-write "ls -la"
ááœááºáá»ááºáá±á¬á¡áá«á á€áááá¯ááááºááẠáá¯á¶ážáá¡áá»ááºážááŸá®ážáá±á¬ output ááá¯áá¯ááºáá±ážáááºá áááºááá¯á·áááºááá¯á á±áá¬áá°á áá»áœááºá¯ááºááá¯á·ááẠá¡áááºá¡áá¬ááŒá áºáá»ááºáá±áááºááá¯ááŒáá·áºááẠááŒá±áá¬ááá¯áá¯á¶ážááá¯ááºáááº-
strace -f ./filter-write "ls -la"
á¡áá¯ááºáááááºááẠá¡ááœááºááá¯áá±á¬ááºážáá±á¬áºáááºáž áááºážááŸáá·áºáááºááá¯ááºáá±á¬á¡ááá¯ááºážááẠáá»áœááºá¯ááºááá¯á·ááŒááºáááºáá¬ážááá·áºá¡ááá¯ááºážááẠEPERM á¡ááŸá¬ážááŒáá·áº ááŸááºáááºážáá»á¬ážááᯠááááºááá¯á·áá¬ážááŒá±á¬ááºáž ááŒááááºá ááá¯ááá¯áááºááŸá¬ program ááẠwrite system call ááá¯áááºáá±á¬ááºááááá±á¬ááŒá±á¬áá·áº áááºááá·áºá¡áá¬ááá¯áá»áŸ output ááá±ážáá«áá
[pid 25099] write(2, "ls: ", 4) = -1 EPERM (Operation not permitted)
[pid 25099] write(2, "write error", 11) = -1 EPERM (Operation not permitted)
[pid 25099] write(2, "n", 1) = -1 EPERM (Operation not permitted)
ááᯠááẠSeccomp BPF áááºáá²á·ááá¯á· á¡áá¯ááºáá¯ááºáááºááᯠáááºáá¬ážáááºááŒá®áž áááºážááŸáá·áº áááºáá¯ááºáá±á¬ááºááá¯ááºáááºáá»á¬ážááᯠáá±á¬ááºážá áœá¬ á¡ááŒá¶á¥á¬ááºáááŸáááŒá®ááŒá áºáááºá ááá¯á·áá±á¬áº áááºážá áá«áá«á¡ááŒáá·áºááᯠá¡áá¯á¶ážáá»ááẠcBPF á¡á á¬áž eBPF ááŒáá·áº áá°áá®áá±á¬á¡áá¬ááᯠáááŸáááá¯áá«ááá¬ážá
eBPF áááá¯ááááºáá»á¬ážá¡ááŒá±á¬ááºážááœá±ážáá±á¬á¡áá«á áá°á¡áá»á¬ážá á¯á áááºážááá¯á·ááᯠááá¯ážááá¯ážááŸááºážááŸááºážáá±ážááŒá®áž á á®áá¶ááá·áºááœá²áá°á¡ááœáá·áºáá°ážáá»á¬ážááŒáá·áº áááºáááºáᯠáááºááŒáááºá á€áá±á¬áºááŒáá»ááºááẠáá±áá°áá»á¡á¬ážááŒáá·áº ááŸááºáá±á¬áºáááºážá kernel ááẠá¡ááá·áºá¡áá»áá¯ážáá»áá¯ážááœáẠeBPF á¡áá¬ááá¹áá¯áá»á¬ážááᯠáá¬ááœááºááẠááá¹ááá¬ážá¡á á¯áá áºáá¯ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá á€ááá¹ááá¬ážáá»á¬ážááᯠBPF LSM áá±á¬ááºáá»á±á¬ááºáá»á¬ážáá¯áá±á«áºáááºá
BPF LSM áá±á¬ááºáá»á±á¬ááºáá»á¬áž
á áá áºááŒá áºáááºáá»á¬ážááᯠáááá¯áá¬-á¡ááŸá®á¡ááá¯áááºážáá±á¬á á±á¬áá·áºááŒáá·áºááŸá¯áá±ážáááºá¡ááœáẠLSM ááẠáá±á¬ááºáá»á±á¬ááºáá»á¬ážáááá±á¬ááá¬ážááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºáááºá áá»áááºáá±á«áºááá¯ááŸá¯áá áºáá¯ááẠá áá áºáá±á«áºááá¯ááŸá¯áá áºáá¯ááŸáá·áº áááºážááá¬á¡á áááºáá°áá±á¬áºáááºáž á áá áºááœááºáááºááŒá®áž á¡ááŒá±áá¶á¡áá±á¬ááºá¡á¡á¯á¶ááŸáá·áº áá±á«ááºážá ááºáá¬ážáááºá LSM ááẠááá°áá®áá±á¬ áááá¯áá¬áá»á¬ážááá¯ááºáᬠá áá áºáá±á«áºááá¯ááŸá¯áá»á¬ážááŸáá·áº ááá¯ááºááœááºáá¬ááœáẠááŒá¯á¶ááœá±á·ááá±á¬ ááŒá¿áá¬áá»á¬ážááᯠááŸá±á¬ááºááŸá¬ážááá¯ááºá á±ááá·áº abstraction layer ááẠá¡áá°á¡áá¡áá áºááᯠáá±ážáá«áááºá
á á¬áá±ážáá»áááºááœááºá kernel ááœáẠBPF áááá¯ááááºáá»á¬ážááŸáá·áºáááºá ááºáá±á¬áá»áááºáá¯áá áºáá¯ááŸáááŒá®áž SELinux ááẠáááºážááá¯á·ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááá·áºáá áºáá¯áááºážáá±á¬ built-in LSM ááŒá áºáááºá
áá±á¬ááºáá»á±á¬ááºáá»á¬ážá¡ááœáẠáááºážááŒá áºáá¯ááºááẠááá¯ááºááŸá kernel áá áºáááºááœáẠáááºááŸáááẠinclude/linux/security.h:
extern int security_bpf(int cmd, union bpf_attr *attr, unsigned int size);
extern int security_bpf_map(struct bpf_map *map, fmode_t fmode);
extern int security_bpf_prog(struct bpf_prog *prog);
extern int security_bpf_map_alloc(struct bpf_map *map);
extern void security_bpf_map_free(struct bpf_map *map);
extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
extern void security_bpf_prog_free(struct bpf_prog_aux *aux);
áááºážááá¯á·ááᯠááœááºáá»ááºááŒááºáž á¡ááá·áºá¡áá®ážáá®ážááœáẠáááºážááá¯á·ááᯠáá±á«áºáá±á«áºáááº-
â security_bpf â ááœááºáá»ááºáá¬ážáá±á¬ BPF á áá áºáá±á«áºááá¯ááŸá¯áá»á¬ážá áááŠážá á áºáá±ážááŸá¯ááᯠáá¯ááºáá±á¬ááºáááºá
- security_bpf_map - kernel ááẠááŒá±áá¯á¶á¡ááœáẠááá¯ááºáá±á¬áºááŒáá»ááºáá áºáá¯ááᯠááŒááºáá±ážááá·áºá¡áá« á á áºáá±ážáááºá
- security_bpf_prog - kernel ááẠeBPF áááá¯ááááºá¡ááœáẠááá¯ááºáá±á¬áºááŒáá»ááºáá áºáá¯ááᯠááŒááºáá±ážááá·áºá¡áá« á á áºáá±ážáááºá
â security_bpf_map_alloc â BPF ááŒá±áá¯á¶áá»á¬ážá¡ááœááºáž áá¯á¶ááŒá¯á¶áá±ážá¡ááœááºááᯠá¡á ááŒá¯áá¬ážááŒááºáž ááŸáááááŸá á á áºáá±ážááẠá
- security_bpf_map_free - áá¯á¶ááŒá¯á¶áá±ážá¡ááœááºááᯠBPF ááŒá±áá¯á¶áá»á¬ážá¡ááœááºáž ááŸááºážáááºážááŒááºážááŸááááŸá á á áºáá±ážááẠá
â security_bpf_prog_alloc â áá¯á¶ááŒá¯á¶áá±ážá¡ááœááºááᯠBPF áááá¯ááááºáá»á¬ážá¡ááœááºáž á¡á ááŒá¯áá¬ážááŒááºáž ááŸáááááŸá á á áºáá±ážáááºá
- security_bpf_prog_free - áá¯á¶ááŒá¯á¶áá±ážá¡ááœááºááᯠBPF áááá¯ááááºáá»á¬ážá¡ááœááºáž ááŸááºážáááºážááŒááºážááŸááááŸá á á áºáá±ážáááºá
ááᯠá€á¡áá¬á¡á¬ážáá¯á¶ážááá¯ááŒááºáá»áŸáẠáá»áœááºá¯ááºááá¯á·áá¬ážáááºáá«áááº- LSM BPF ááŒá¬ážááŒááºáááááá¬áá»á¬ážáá±á¬ááºááœááºááŸá á¡áá°á¡áááŸá¬ áááºážááá¯á·ááẠeBPF á¡áá¬ááá¹áá¯ááá¯ááºážá¡ááœáẠá¡áá¬á¡ááœááºáá±ážááá¯ááºááŒá®áž ááá·áºáá»á±á¬áºáá±á¬á¡ááœáá·áºáá°ážáá»á¬ážáááŸááá°áá»á¬ážáᬠáááºáá»á¬ážááŸáá·áº áááá¯ááááºáá»á¬ážááœáẠáá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠáá¯ááºáá±á¬ááºááá¯ááºááŒá±á¬ááºáž áá±áá»á¬á á±áá«áááºá
á¡áá»ááºážáá»á¯ááº
áá¯á¶ááŒá¯á¶áá±ážááẠáááºáá¬ááœááºááá¯ááá·áºá¡áá¬á¡á¬ážáá¯á¶ážá¡ááœáẠá¡ááœááºá¡á á¬áž-á¡á¶áááºááœááºáá»ááŒá áºá á±ááá·áºáááºážáááºážááŒáá·áº áááºá¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáá±á¬ á¡áá¬ááá¯ááºáá«á ááá°áá®áá±á¬á¡ááá·áºáá»á¬ážááŸáá·áº ááá°áá®áá±á¬áááºážáááºážáá»á¬ážááŒáá·áº á áá áºáá»á¬ážááᯠáá¬ááœááºááá¯ááºá á±ááẠá¡áá±ážááŒá®ážáá«áááºá áá¯á¶áááºááŒá áºá á±á ááá¯á¶áááºááŒá áºá á±á á áá áºáá áºáá¯ááᯠáá¯á¶ááŒá¯á¶á¡á±á¬ááºááŒá¯áá¯ááºááẠá¡áá±á¬ááºážáá¯á¶ážáááºážáááºážááŸá¬ ááá°áá®áá±á¬áá¬áá°ážáá»á¬ážá០áá¬ááœááºááŸá¯á¡ááá·áºáá»á¬ážááᯠá á¯á ááºážáá¬ážááŒááºážááŒá áºáááºá ááá¯á·ááŸáᬠá¡ááá·áºáá áºáá¯ááá¯á¶ááŒá¯á¶áá±ážááᯠáá»áŸá±á¬á·áá»ááŒááºážááŒáá·áº á áá áºáá áºáá¯áá¯á¶ážááᯠáááºáá±á¬ááºááœáá·áºáááŒá¯ááá¯ááºáá±á áááºá developer áá»á¬ážááẠááá°áá®áá±á¬ á¡ááœáŸá¬áá»á¬ážááŸáá·áº ááááœá±á·ááŸá¯áá±áá¬áá»á¬ážááᯠáá±ážáá±á¬ááºááẠáá±á¬ááºážááœááºáá±á¬á¡áá¯ááºáá»á¬áž áá¯ááºáá±á¬ááºáá²á·áááºá á¡ááœáŸá¬áá»á¬ážááẠá¡áááºá¡ááœáŸá¬áá»á¬ážááŒá áºááŒá®áž áááºážááá¯á·ááŸáá·áºáá¯ááºáá±á¬ááºááẠBPF áááá¯ááááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯áá¯á¶ááá¯á·ááᯠáá±á¬ááºážá áœá¬áá¬ážáááºááá±á¬áá±á«ááºááá¯ááºáááºáᯠáá»áŸá±á¬áºááá·áºáá«áááºá
á á¬áá±ážááá¬áá»á¬ážá¡ááŒá±á¬ááºáž
David Calavera Netlify ááœáẠCTO ááŒá áºáááºá áá°ááẠDocker áá¶á·ááá¯ážáá°áá®ááŸá¯ááœáẠá¡áá¯ááºáá¯ááºáá²á·ááŒá®áž Runcá Go ááŸáá·áº BCC áááááá¬áá»á¬ážá¡ááŒáẠá¡ááŒá¬ážáá±á¬ open source ááá±á¬áá»ááºáá»á¬ážááᯠáá¶á·ááá¯ážáá°áá®áá²á·áááºá Docker ááá±á¬áá»ááºáá»á¬ážááŸáá·áº Docker ááááºá¡ááºáá±áá áá áºá ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯á¡ááœáẠáá°ááá¯ááºáá±á¬ááºááŸá¯ááŒá±á¬áá·áº áá°áááá»á¬ážáááºá David ááẠáá®ážáá±á¬ááºááááºáá áºáá»á¬ážááᯠá¡ááœááºá áááºá¡á¬ážáááºáááºááŒá®áž á áœááºážáá±á¬ááºáááºááᯠá¡áá±á¬ááºážáá¯á¶ážááŒá áºá¡á±á¬áẠá¡ááŒá²ááŸá¬ááœá±áá±áá«áááºá
Lorenzo Fontana Kernel module ááŸáá·áº eBPF ááŸáááá·áº ááœááºááááºáᬠruntime áá¯á¶ááŒá¯á¶áá±ážááŸáá·áº ááœá²ááœá²áá»ááºáá»á¬ážááᯠááááŸáááá¯ááºá á±ááẠáá¶á·ááá¯ážáá±ážáá±á¬ Cloud Native Computing Foundation ááá±á¬áá»áẠFalco ááᯠá¡áááá¡á¬áá¯á¶á áá¯ááºáá¬ážááá·áº Sysdig ááŸá open source á¡ááœá²á·ááœáẠá¡áá¯ááºáá¯ááºáá«áááºá áá°ááẠááŒáá·áºáá±ááá·áºá áá áºáá»á¬ážá áá±á¬á·ááºáá²ááºáááºááŸááºáá¬ážáá±á¬ ááœááºáááºáá»áááºáááºááŸá¯á Linux kernel ááŸáá·áº á áœááºážáá±á¬ááºáááºááá¯ááºážááœá²ááŒááºážá áááºááŒá¬ááŸá¯áá»á¬ážááᯠá áááºá¡á¬ážáááºáááºáá°ááŒá áºáááºá
» á
á¬á¡á¯ááºááŸáá·áºáááºáááºáá±á¬ á¡áá±ážá
áááºá¡áá»ááºá¡áááºáá»á¬ážááᯠá¡á±á¬ááºáá«ááá·áºááœáẠááŒáá·áºááŸá¯ááá¯ááºáá«áááºá
»
»
Khabrozhiteley áá°ááœááºááá¯á¡áá¯á¶ážááŒá¯á 25% áá»áŸá±á¬á·á á»á±ážá¡ááœáẠ- Linux ááá¯
á
á¬á¡á¯ááºá á
áá¹áá°áá¬ážááŸááºážááᯠááœá±áá±ážáá»á±ááŒá®ážáá«á á¡á®áááºáááœááºáá
áºá
á¬á¡á¯ááºááᯠá¡á®ážáá±ážááºááŒáá·áº áá±ážááá¯á·áááºááŒá
áºáááºá
source: www.habr.com