Puke "BPF no ka nānā ʻana iā Linux"

Puke "BPF no ka nānā ʻana iā Linux"Aloha mai e nā kamaʻāina ʻo Khabro! ʻO ka mīkini virtual BPF kekahi o nā mea nui o ka kernel Linux. ʻO kāna hoʻohana kūpono e ʻae i nā ʻenekini pūnaewele e ʻimi i nā hewa a hoʻoponopono i nā pilikia paʻakikī loa. E aʻo ʻoe pehea e kākau ai i nā papahana e nānā a hoʻololi i ke ʻano o ka kernel, pehea e hoʻokō pono ai i ke code e nānā i nā hanana i ka kernel, a ʻoi aku ka nui. E kōkua ʻo David Calavera lāua ʻo Lorenzo Fontana iā ʻoe e wehe i ka mana o BPF. E hoʻonui i kou ʻike e pili ana i ka loiloi hana, ka pūnaewele, ka palekana. - E hoʻohana i ka BPF e nānā a hoʻololi i ke ʻano o ka kernel Linux. - Inject code no ka nānā pono ʻana i nā hanana kernel me ka ʻole e hoʻopili hou i ka kernel a hoʻomaka hou i ka ʻōnaehana. - E hoʻohana i nā hiʻohiʻona code kūpono ma C, Go a i ʻole Python. - E hoʻomalu ma o ka loaʻa ʻana o ke ola o ka papahana BPF.

ʻO Linux Kernel Security, kāna mau hiʻohiʻona a me Seccomp

Hāʻawi ʻo BPF i kahi ala ikaika e hoʻonui ai i ka kernel me ka ʻole o ka hoʻopaʻa ʻana, palekana, a i ʻole ka wikiwiki. No kēia kumu, ua manaʻo nā mea hoʻomohala kernel he manaʻo maikaʻi ia e hoʻohana i kāna versatility e hoʻomaikaʻi i ke kaʻina kaʻawale ma Seccomp ma o ka hoʻokō ʻana i nā kānana Seccomp i kākoʻo ʻia e nā polokalamu BPF, i kapa ʻia ʻo Seccomp BPF. Ma kēia mokuna e wehewehe mākou i ke ʻano o Seccomp a pehea e hoʻohana ʻia ai. A laila e aʻo ʻoe pehea e kākau ai i nā kānana Seccom me ka hoʻohana ʻana i nā polokalamu BPF. Ma hope o kēlā, e nānā mākou i nā makau BPF i hoʻokomo ʻia i loko o ka kernel no nā modula palekana Linux.

ʻO Linux Security Modules (LSM) kahi papa hana e hāʻawi i kahi pūʻulu o nā hana i hiki ke hoʻohana ʻia no ka hoʻokō ʻana i nā hiʻohiʻona palekana like ʻole ma ke ʻano maʻamau. Hiki ke hoʻohana pololei ʻia ʻo LSM i ka kumu kumu kumu kumu, e like me Apparmor, SELinux a me Tomoyo.

E hoʻomaka kākou ma ke kūkākūkā ʻana i nā hiki o Linux.

Nā Kūlana

ʻO ke kumu o ka mana o Linux he pono ʻoe e hāʻawi i kahi kaʻina hana pono ʻole e hana i kekahi hana, akā me ka ʻole o ka hoʻohana ʻana i ka suid no ia kumu, a i ʻole e hana pono i ke kaʻina hana, e hōʻemi i ka hiki ke hoʻouka a ʻae i ke kaʻina hana e hana i kekahi mau hana. No ka laʻana, inā pono kāu noi e wehe i kahi awa pono, e ʻōlelo ʻo 80, ma kahi o ka holo ʻana i ke kaʻina hana ma ke ʻano he kumu, hiki iā ʻoe ke hāʻawi iā ia i ka mana CAP_NET_BIND_SERVICE.

E noʻonoʻo i kahi papahana Go i kapa ʻia ʻo main.go:

package main
import (
            "net/http"
            "log"
)
func main() {
     log.Fatalf("%v", http.ListenAndServe(":80", nil))
}

Hāʻawi kēia polokalamu i kahi kikowaena HTTP ma ke awa 80 (he awa pono kēia). Hoʻohana maʻamau mākou ma hope koke o ka hōʻuluʻulu ʻana:

$ go build -o capabilities main.go
$ ./capabilities

Eia naʻe, no ka mea ʻaʻole mākou e hāʻawi i nā pono kumu, e hoʻolei kēia code i kahi hewa i ka wā e hoʻopaʻa ai i ke awa:

2019/04/25 23:17:06 listen tcp :80: bind: permission denied
exit status 1

capsh (shell manager) he mea paahana ia e holo ana i ka pūpū me kekahi mau mana kiko'ī.

I kēia hihia, e like me ka mea i haʻi mua ʻia, ma kahi o ka hāʻawi ʻana i nā kuleana kumu piha, hiki iā ʻoe ke hiki ke hoʻopaʻa i ka port privileged i ka hoʻolako ʻana i ka cap_net_bind_service me nā mea ʻē aʻe a pau i loko o ka papahana. No ka hana ʻana i kēia, hiki iā mākou ke hoʻopili i kā mākou papahana i ka 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"

E hoʻomaopopo iki kākou i kēia hui.

  • capsh - hoʻohana i ka capsh ma ke ʻano he pūpū.
  • —caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' - no ka mea pono mākou e hoʻololi i ka mea hoʻohana (ʻaʻole makemake mākou e holo ma ke ʻano he kumu), e kuhikuhi mākou i ka cap_net_bind_service a me ka hiki ke hoʻololi maoli i ka ID mea hoʻohana mai ʻaʻohe kumu i kekahi, ʻo ia ka cap_setuid a me ka cap_setgid.
  • —keep=1 — makemake mākou e mālama i nā mana i hoʻokomo ʻia i ka wā e hoʻololi ai mai ka mooolelo kumu.
  • —user=“nobody” — ʻaʻohe kanaka ka mea hoʻohana hope e holo ana i ka papahana.
  • —addamb=cap_net_bind_service - hoʻonohonoho i ka hoʻomaʻemaʻe ʻana i nā mana pili ma hope o ka hoʻololi ʻana mai ke ʻano kumu.
  • - -c "./capabilities" - holo wale i ka papahana.

ʻO nā mana i hoʻohui ʻia he ʻano mana kūikawā i hoʻoili ʻia e nā polokalamu keiki ke hoʻokō ka papahana o kēia manawa iā lākou me ka execve(). Hiki ke hoʻoili ʻia nā mana i ʻae ʻia e hoʻopili ʻia, a i ʻole, ma ke ʻano he hiki i ke kaiapuni.

Ke noʻonoʻo nei paha ʻoe i ke ʻano o +eip ma hope o ka wehewehe ʻana i ka hiki i ke koho --caps. Hoʻohana ʻia kēia mau hae e hoʻoholo i ka hiki ke:

-pono e ho'ā (p);

- hiki ke hoʻohana (e);

-hiki ke hoʻoili ʻia e nā kaʻina keiki (i).

No ka mea makemake mākou e hoʻohana i ka cap_net_bind_service, pono mākou e hana i kēia me ka hae e. A laila e hoʻomaka mākou i ka pūpū ma ke kauoha. E holo ana kēia i nā kaha binary a pono mākou e kaha me ka hae i. ʻO ka mea hope loa, makemake mākou e hoʻohana ʻia ka hiʻohiʻona (ua hana mākou me ka hoʻololi ʻole i ka UID) me ka p. Me he cap_net_bind_service+eip.

Hiki iā ʻoe ke nānā i ka hopena me ka hoʻohana ʻana iā ss. E hoʻopōkole kākou i ka mea hoʻopuka e kūpono i ka ʻaoʻao, akā e hōʻike ʻia ke awa pili a me ka ID mea hoʻohana ʻē aʻe ma mua o 0, i kēia hihia 65:

# ss -tulpn -e -H | cut -d' ' -f17-
128 *:80 *:*
users:(("capabilities",pid=30040,fd=3)) uid:65534 ino:11311579 sk:2c v6only:0

Ma kēia hiʻohiʻona ua hoʻohana mākou i ka capsh, akā hiki iā ʻoe ke kākau i kahi pūpū me ka hoʻohana ʻana i ka libcap. No ka ʻike hou aku, e ʻike iā man 3 libcap.

Ke kākau nei i nā polokalamu, ʻaʻole ʻike mua ka mea hoʻomohala i nā hiʻohiʻona āpau e pono ai ka papahana i ka manawa holo; Eia kekahi, hiki ke loli kēia mau hiʻohiʻona i nā mana hou.

No ka hoʻomaopopo maikaʻi ʻana i nā hiki o kā mākou papahana, hiki iā mākou ke lawe i ka mea hana hiki i ka BCC, kahi e hoʻonohonoho ai i ka kprobe no ka hana kernel cap_capable:

/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

Hiki iā mākou ke hoʻokō i ka mea like me ka hoʻohana ʻana i ka bpftrace me kahi kprobe one-liner i ka hana kernel cap_capable:

bpftrace -e 
   'kprobe:cap_capable {
      time("%H:%M:%S ");
      printf("%-6d %-6d %-16s %-4d %dn", uid, pid, comm, arg2, arg3);
    }' 
    | grep -i capabilities

E hoʻopuka kēia i kahi mea e like me kēia inā hiki ke hoʻohana ʻia kā mākou papahana ma hope o 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

ʻO ka kolamu ʻelima nā mana e pono ai ke kaʻina hana, a no ka mea e komo ana kēia hoʻopuka i nā hanana hōʻoia ʻole, ʻike mākou i nā hōʻoia hōʻoia ʻole a hope loa i ka mana i koi ʻia me ka hae loiloi (hope i ka pukana) i hoʻonohonoho ʻia i 1. Capability. ʻO kahi a mākou e makemake ai ʻo CAP_NET_BIND_SERVICE, ua wehewehe ʻia ma ke ʻano he mea mau i ka kernel source code i ka faila me/uapi/linux/ability.h me ka mea ʻike 10:

/* Allows binding to TCP/UDP sockets below 1024 */
/* Allows binding to ATM VCIs below 32 */
#define CAP_NET_BIND_SERVICE 10<source lang="go">

Hoʻohana pinepine ʻia nā mana i ka wā holo no nā pahu e like me runC a i ʻole Docker e ʻae iā lākou e holo i ke ʻano ʻike ʻole, akā ʻae ʻia lākou i nā mana e pono ai e holo i ka hapa nui o nā noi. Ke koi ʻia kahi noi i kekahi mau mana, hiki iā Docker ke hāʻawi iā lākou me ka hoʻohana ʻana --cap-add:

docker run -it --rm --cap-add=NET_ADMIN ubuntu ip link add dummy0 type dummy

Hāʻawi kēia kauoha i ka pahu i ka mana CAP_NET_ADMIN, e ʻae iā ia e hoʻonohonoho i kahi loulou pūnaewele e hoʻohui i ka interface dummy0.

Hōʻike ka ʻāpana aʻe i ka hoʻohana ʻana i nā hiʻohiʻona e like me ke kānana, akā me ka hoʻohana ʻana i kahi ʻenehana ʻokoʻa e hiki ai iā mākou ke hoʻokō i kā mākou mau kānana ponoʻī.

Seccomp

Ke kū nei ʻo Seccomp no Secure Computing a he papa palekana i hoʻokō ʻia ma ka kernel Linux e hiki ai i nā mea hoʻomohala ke kānana i kekahi mau kelepona ʻōnaehana. ʻOiai ua hoʻohālikelike ʻia ʻo Seccomp i nā mana me Linux, ʻo kona hiki ke hoʻokele i kekahi mau kelepona ʻōnaehana e ʻoi aku ka maʻalahi o ka hoʻohālikelike ʻana iā lākou.

ʻAʻole kūʻokoʻa nā hiʻohiʻona Seccom a me Linux a hoʻohana pinepine ʻia e pōmaikaʻi mai nā ala ʻelua. No ka laʻana, makemake paha ʻoe e hāʻawi i kahi kaʻina hana i ka hiki CAP_NET_ADMIN akā ʻaʻole e ʻae iā ia e ʻae i nā loulou socket, e ālai ana i ka ʻae a me ka ʻae ʻana i nā kelepona ʻōnaehana.

Hoʻokumu ʻia ke ʻano kānana Seccomp ma luna o nā kānana BPF e hana ana ma ke ʻano SECCOMP_MODE_FILTER, a hana ʻia ka kānana kelepona ʻōnaehana ma ke ʻano like me nā ʻeke.

Hoʻouka ʻia nā kānana Seccomp me ka prctl ma o ka hana PR_SET_SECCOMP. Lawe kēia mau kānana i ke ʻano o kahi papahana BPF i hoʻokō ʻia no kēlā me kēia ʻeke Seccom i hōʻike ʻia e ka hoʻolālā seccomp_data. Aia i loko o kēia hale ka papa kuhikuhi kuhikuhi, kahi kuhikuhi i nā ʻōlelo aʻoaʻo i ka manawa o ke kelepona ʻōnaehana, a me ka nui o nā ʻōlelo hoʻopaʻapaʻa kelepona ʻeono, i hōʻike ʻia ma ke ʻano he uint64.

ʻO kēia ke ʻano o ka hoʻolālā seccomp_data mai ke kumu kumu kernel ma ka faila linux/seccomp.h:

struct seccomp_data {
int nr;
      __u32 arch;
      __u64 instruction_pointer;
      __u64 args[6];
};

E like me kāu e ʻike ai mai kēia hoʻolālā, hiki iā mākou ke kānana ma ke kelepona ʻōnaehana, kāna mau hoʻopaʻapaʻa, a i ʻole ka hui pū ʻana o nā mea ʻelua.

Ma hope o ka loaʻa ʻana o kēlā me kēia ʻeke Seccomp, pono ka kānana e hana i ka hana e hoʻoholo hope loa a haʻi i ka kernel i ka mea e hana ai. Hōʻike ʻia ka hoʻoholo hope e kekahi o nā waiwai hoʻihoʻi (status code).

- SECCOMP_RET_KILL_PROCESS - pepehi i ke kaʻina holoʻokoʻa ma hope koke o ke kānana ʻana i kahi kelepona ʻōnaehana ʻaʻole i hoʻokō ʻia ma muli o kēia.

- SECCOMP_RET_KILL_THREAD - hoʻopau i ke kaula i kēia manawa ma hope koke o ke kānana ʻana i kahi kelepona ʻōnaehana ʻaʻole i hoʻokō ʻia ma muli o kēia.

— SECCOMP_RET_KILL — inoa inoa no SECCOMP_RET_KILL_THREAD, waiho ʻia no ka hoʻokō ʻana i hope.

- SECCOMP_RET_TRAP - pāpā ʻia ke kelepona ʻōnaehana, a hoʻouna ʻia ka hōʻailona SIGSYS (Bad System Call) i ka hana e kāhea ai.

- SECCOMP_RET_ERRNO - ʻAʻole i hoʻokō ʻia ke kelepona ʻōnaehana, a hāʻawi ʻia kahi hapa o ka SECCOMP_RET_DATA kānana hoʻihoʻi waiwai i ka mea hoʻohana ma ke ʻano he errno waiwai. Ma muli o ke kumu o ka hewa, hoʻihoʻi ʻia nā waiwai errno like ʻole. Hāʻawi ʻia kahi papa inoa o nā helu hewa ma ka ʻāpana aʻe.

- SECCOMP_RET_TRACE - Hoʻohana ʻia no ka hoʻomaopopo ʻana i ka ptrace tracer me ka hoʻohana ʻana - PTRACE_O_TRACESECCOMP e keakea i ka wā e hoʻokō ʻia ai kahi kelepona pūnaewele e ʻike a mālama i kēlā kaʻina hana. Inā ʻaʻole pili kahi tracer, hoʻihoʻi ʻia kahi hewa, hoʻonohonoho ʻia ʻo errno i -ENOSYS, a ʻaʻole i hoʻokō ʻia ke kelepona ʻōnaehana.

- SECCOMP_RET_LOG - ua hoʻoholo ʻia ka ʻōnaehana kelepona a hoʻopaʻa ʻia.

- SECCOMP_RET_ALLOW - ʻae wale ʻia ke kelepona ʻōnaehana.

ʻO ka ptrace kahi ʻōnaehana kelepona e hoʻokō i nā mīkini ʻimi i kahi kaʻina i kapa ʻia ʻo tracee, me ka hiki ke nānā a mālama i ka hoʻokō ʻana o ke kaʻina hana. Hiki i ka papahana trace ke hoʻoikaika pono i ka hoʻokō a hoʻololi i nā papa inoa hoʻomanaʻo o ka tracee. Ma ka pōʻaiapili Seccomp, hoʻohana ʻia ka ptrace i ka wā i hoʻoulu ʻia e ke code status SECCOMP_RET_TRACE, no laila hiki i ka tracer ke pale i ke kelepona ʻōnaehana mai ka hoʻokō ʻana a hoʻokō i kāna loiloi ponoʻī.

Nā hewa Seccom

I kēlā me kēia manawa, i ka hana ʻana me Seccomp, e ʻike ʻoe i nā hewa like ʻole, i ʻike ʻia e ka waiwai hoʻihoʻi o ke ʻano SECCOMP_RET_ERRNO. No ka hōʻike ʻana i kahi hewa, e hoʻi ka kelepona ʻōnaehana seccomp -1 ma kahi o 0.

Hiki i kēia mau hewa:

- EACCESS - ʻAʻole ʻae ʻia ka mea kelepona e hana i kahi kelepona ʻōnaehana. ʻO ka mea maʻamau kēia no ka mea ʻaʻohe ona kuleana CAP_SYS_ADMIN a i ʻole no_new_privs i hoʻonohonoho ʻia me ka prctl (e kamaʻilio mākou e pili ana i kēia ma hope);

— EFAULT — ʻaʻohe helu kūpono o nā manaʻo i hala (args ma ka seccomp_data structure);

— EINVAL — ʻehā mau kumu ma aneʻi:

-ʻaʻole ʻike ʻia ka hana i noi ʻia a ʻaʻole i kākoʻo ʻia e ka kernel i ka hoʻonohonoho o kēia manawa;

-ʻaʻole kūpono nā hae i kuhikuhi ʻia no ka hana i noi ʻia;

-ʻO ka hana me BPF_ABS, akā aia nā pilikia me ka offset i ʻōlelo ʻia, hiki ke ʻoi aku ma mua o ka nui o ka hoʻolālā seccomp_data;

-ʻoi aku ka nui o nā ʻōlelo aʻo i hāʻawi ʻia i ka kānana;

— ENOMEM — ʻaʻole lawa ka hoʻomanaʻo e hoʻokō ai i ka papahana;

- EOPNOTSUPP - ua hōʻike ʻia ka hana me SECCOMP_GET_ACTION_AVAIL ua loaʻa ka hana, akā ʻaʻole kākoʻo ka kernel i ka hoʻihoʻi ʻana i nā hoʻopaʻapaʻa;

- ESRCH - ua hiki mai kahi pilikia i ka hoʻonohonoho ʻana i kahi kahawai ʻē aʻe;

- ENOSYS - ʻAʻohe tracer i hoʻopili ʻia i ka hana SECCOMP_RET_TRACE.

ʻO ka prctl kahi kelepona ʻōnaehana e hiki ai i kahi polokalamu hoʻohana-space ke hoʻoponopono (hoʻonohonoho a loaʻa) i nā ʻano kikoʻī o kahi kaʻina hana, e like me ka endianness byte, nā inoa thread, ke ʻano helu helu palekana (Seccomp), nā pono, nā hanana Perf, etc.

Ua like paha ʻo Seccom me kahi ʻenehana pahu one iā ʻoe, akā ʻaʻole. He mea hoʻohana ʻo Seccomp e hiki ai i nā mea hoʻohana ke hoʻomohala i kahi mīkini sandbox. I kēia manawa, e nānā kākou i ke ʻano o ka hana ʻana o nā polokalamu hoʻohana me ka hoʻohana ʻana i kahi kānana i kapa pololei ʻia e ke kelepona ʻōnaehana Seccomp.

BPF Seccom kānana Laana

Ma ʻaneʻi mākou e hōʻike ai pehea e hoʻohui ai i nā hana ʻelua i kūkākūkā mua ʻia, ʻo ia hoʻi:

- e kākau mākou i kahi papahana Seccom BPF, e hoʻohana ʻia ma ke ʻano he kānana me nā code hoʻihoʻi like ʻole ma muli o nā hoʻoholo i hana ʻia;

- hoʻouka i ka kānana me ka hoʻohana ʻana i ka prctl.

Pono mua ʻoe i nā poʻomanaʻo mai ka waihona maʻamau a me ka 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>

Ma mua o ka hoʻāʻo ʻana i kēia laʻana, pono mākou e hōʻoia i ka hui ʻana o ka kernel me CONFIG_SECCOMP a me CONFIG_SECCOMP_FILTER i hoʻonohonoho ʻia i y. Ma ka mīkini hana hiki iā ʻoe ke nānā i kēia e like me kēia:

cat /proc/config.gz| zcat | grep -i CONFIG_SECCOMP

ʻO ke koena o ke code he hana install_filter ʻelua ʻāpana. Aia ka ʻāpana mua i kā mākou papa inoa o nā kuhikuhi kānana 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),
  };

Hoʻonohonoho ʻia nā ʻōkuhi me ka hoʻohana ʻana i nā macros BPF_STMT a me BPF_JUMP i wehewehe ʻia ma ka faila linux/filter.h.
E hele kāua i nā kuhikuhi.

- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, arch))) - hoʻouka ka ʻōnaehana a hōʻiliʻili mai BPF_LD ma ke ʻano o ka huaʻōlelo BPF_W, aia ka ʻikepili paʻa ma kahi hoʻopaʻa paʻa BPF_ABS.

- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3) - nānā me ka hoʻohana ʻana i ka BPF_JEQ inā like ka waiwai hoʻolālā i loko o ka BPF_K accumulator mau me ka arch. Inā pēlā, lele i ka offset 0 i ke aʻo aʻe, a i ʻole e lele i ka offset 3 (ma kēia hihia) e hoʻolei i kahi hewa no ka mea ʻaʻole kūlike ke arch.

- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, nr))) - Hoʻouka a hōʻiliʻili mai BPF_LD ma ke ʻano o ka huaʻōlelo BPF_W, ʻo ia ka helu kelepona pūnaewele i loko o ka offset paʻa o BPF_ABS.

— BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) — hoʻohālikelike i ka helu kelepona ʻōnaehana me ka waiwai o ka helu nr. Inā like lākou, e neʻe i ke aʻo aʻe a hoʻopau i ke kelepona ʻōnaehana, i ʻole e ʻae i ke kelepona pūnaewele me SECCOMP_RET_ALLOW.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (hewa & SECCOMP_RET_DATA)) - hoʻopau i ka papahana me BPF_RET a ma muli o ka hoʻopuka ʻana i kahi hewa SECCOMP_RET_ERRNO me ka helu mai ka hoʻololi hewa.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW) - hoʻopau i ka papahana me BPF_RET a hiki ke hoʻokō ʻia ke kelepona pūnaewele me ka hoʻohana ʻana i SECCOMP_RET_ALLOW.

SECCOMP IS CBPF
Ke noʻonoʻo nei paha ʻoe no ke aha i hoʻohana ʻia ai kahi papa inoa o nā ʻōlelo aʻo ma kahi o kahi mea ELF i hoʻohui ʻia a i ʻole kahi papahana C i hōʻuluʻulu ʻia e JIT.

ʻElua kumu no kēia.

• ʻO ka mea mua, hoʻohana ʻo Seccomp i ka cBPF (BPF maʻamau) ʻaʻole eBPF, ʻo ia hoʻi: ʻaʻohe ona papa inoa, akā he accumulator wale nō e mālama i ka hopena helu hope, e like me ka mea i ʻike ʻia ma ka laʻana.

• ʻO ka lua, ʻae ʻo Seccomp i kahi kuhikuhi i kahi ʻano o nā kuhikuhi BPF pololei a ʻaʻohe mea ʻē aʻe. ʻO nā macros a mākou i hoʻohana ai e kōkua maʻalahi i ka wehewehe ʻana i kēia mau ʻōlelo aʻoaʻo ma ke ʻano hoʻohana polokalamu.

Inā makemake ʻoe i kōkua hou aku e hoʻomaopopo i kēia hui, e noʻonoʻo i ka pseudocode e hana like ana:

if (arch != AUDIT_ARCH_X86_64) {
    return SECCOMP_RET_ALLOW;
}
if (nr == __NR_write) {
    return SECCOMP_RET_ERRNO;
}
return SECCOMP_RET_ALLOW;

Ma hope o ka wehewehe ʻana i ke code kānana ma ke ʻano socket_filter, pono ʻoe e wehewehe i kahi sock_fprog i loaʻa ke code a me ka lōʻihi i helu ʻia o ka kānana. Pono kēia ʻano ʻikepili i kumu hoʻopaʻapaʻa no ka haʻi ʻana i ke kaʻina hana e holo ma hope:

struct sock_fprog prog = {
   .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
   .filter = filter,
};

Hoʻokahi wale nō mea i koe e hana ai i ka hana install_filter - hoʻouka i ka polokalamu ponoʻī! No ka hana ʻana i kēia, hoʻohana mākou i ka prctl, e lawe ana iā PR_SET_SECCOMP ma ke ʻano he koho no ke komo ʻana i ke ʻano hoʻopili paʻa. A laila haʻi mākou i ke ʻano e hoʻouka i ka kānana me ka hoʻohana ʻana i SECCOMP_MODE_FILTER, aia i loko o ka prog variable o ke ʻano sock_fprog:

  if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
    perror("prctl(PR_SET_SECCOMP)");
    return 1;
  }
  return 0;
}

ʻO ka hope, hiki iā mākou ke hoʻohana i kā mākou hana install_filter, akā ma mua o kēlā pono mākou e hoʻohana i ka prctl e hoʻonohonoho iā PR_SET_NO_NEW_PRIVS no ka hoʻokō ʻana i kēia manawa a no laila e pale aku i ke kūlana kahi e loaʻa ai i nā kaʻina keiki nā kuleana ʻoi aku ma mua o ko lākou mau mākua. Me kēia, hiki iā mākou ke hana i nā kelepona prctl ma ka hana install_filter me ka loaʻa ʻole o nā kuleana kumu.

I kēia manawa hiki iā mākou ke kāhea i ka hana install_filter. E ālai kākou i nā kelepona ʻōnaehana kākau a pau e pili ana i ka hoʻolālā X86-64 a hāʻawi wale i ka ʻae e ālai i nā hoʻāʻo a pau. Ma hope o ka hoʻokomo ʻana i ka kānana, hoʻomau mākou i ka hoʻokō me ka hoʻopaʻapaʻa mua:

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]);
 }

E hoʻomaka kākou. No ka hōʻuluʻulu ʻana i kā mākou papahana hiki iā mākou ke hoʻohana i ka clang a i ʻole gcc, ʻo ia wale nō ka hoʻopili ʻana i ka faila main.c me nā koho kūikawā:

clang main.c -o filter-write

E like me ka mea i hōʻike ʻia, ua pāpā mākou i nā mea komo āpau i ka papahana. No ka hoʻāʻo ʻana i kēia, pono ʻoe i kahi papahana e hoʻopuka i kahi mea - ls me he mea lā he moho maikaʻi. Penei kāna hana maʻamau:

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

Kupaianaha! Eia ke ʻano o ka hoʻohana ʻana i kā mākou polokalamu wrapper: Hoʻohele wale mākou i ka papahana a mākou e makemake ai e hoʻāʻo ma ke ʻano he hoʻopaʻapaʻa mua.

./filter-write "ls -la"

Ke hoʻokō ʻia, hoʻopuka kēia polokalamu i ka puka piha ʻole. Eia naʻe, hiki iā mākou ke hoʻohana i ka strace e ʻike i ka mea e hana nei:

strace -f ./filter-write "ls -la"

Hoʻopōkole loa ʻia ka hopena o ka hana, akā ʻo ka ʻāpana pili o ia mea e hōʻike ana ua kāohi ʻia nā moʻolelo me ka hewa EPERM - ʻo ia ka mea a mākou i hoʻonohonoho ai. 'O ia ho'i, 'a'ole ho'opuka ka polokalamu i kekahi mea no ka mea 'a'ole hiki iā ia ke komo i ke kelepona pūnaewele kākau:

[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)

I kēia manawa ʻike ʻoe pehea e hana ai ʻo Seccom BPF a loaʻa iā ʻoe kahi manaʻo maikaʻi i kāu mea e hana ai me ia. Akā ʻaʻole makemake ʻoe e hoʻokō i ka mea like me eBPF ma kahi o cBPF e hoʻohana i kona mana piha?

Ke noʻonoʻo nei e pili ana i nā polokalamu eBPF, manaʻo ka hapa nui o ka poʻe e kākau wale lākou a hoʻouka iā lākou me nā kuleana luna. ʻOiai he ʻoiaʻiʻo kēia ʻōlelo, hoʻokō ka kernel i kahi ʻano hana e pale ai i nā mea eBPF ma nā pae like ʻole. Ua kapa ʻia kēia mau hana he mau pahele BPF LSM.

BPF LSM pahele

No ka hāʻawiʻana i ka nānāʻana i ka nānāʻana i nā hanana pūnaewele, ua hoʻokōʻo LSM i ka manaʻo o nā pahele. ʻO ke kelepona hook ua like ia me ke kelepona ʻōnaehana, akā he ʻōnaehana kūʻokoʻa a hoʻohui pū ʻia me ka ʻōnaehana. Hāʻawi ʻo LSM i kahi manaʻo hou kahi e hiki ai i kahi papa abstraction ke kōkua i ka pale ʻana i nā pilikia i loaʻa i ka wā e pili ana i nā kelepona ʻōnaehana ma nā hale hana like ʻole.

I ka manawa e kākau ai, ʻehiku mau makau e pili ana me nā polokalamu BPF, a ʻo SELinux wale nō ka LSM i kūkulu ʻia e hoʻokō iā lākou.

Aia ke kumu kumu no nā pahele ma ka lāʻau kernel i loko o ka faila i komo/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);

E kāhea ʻia kēlā me kēia o lākou i nā pae like ʻole o ka hoʻokō:

- security_bpf - hana i kahi nānā mua o nā kelepona ʻōnaehana BPF i hoʻokō ʻia;

- security_bpf_map - nānā i ka wā e hoʻihoʻi ai ka kernel i kahi wehewehe faila no ka palapala ʻāina;

- security_bpf_prog - nānā i ka wā e hoʻihoʻi ai ka kernel i kahi wehewehe faila no ka papahana eBPF;

— security_bpf_map_alloc — nānā inā hoʻomaka ʻia ke kahua palekana i loko o nā palapala BPF;

- security_bpf_map_free - nānā inā ua holoi ʻia ke kahua palekana i loko o nā palapala BPF;

— security_bpf_prog_alloc — nānā inā hoʻomaka ka kahua palekana i loko o nā polokalamu BPF;

- security_bpf_prog_free - nānā inā hoʻomaʻemaʻe ʻia ke kahua palekana i loko o nā polokalamu BPF.

I kēia manawa, ʻike mākou i kēia mau mea a pau: ʻo ka manaʻo ma hope o nā interceptors LSM BPF hiki iā lākou ke hāʻawi i ka pale i kēlā me kēia mea eBPF, e hōʻoiaʻiʻo ana ʻo ka poʻe me nā pono kūpono e hiki ke hana i nā hana ma nā kāleka a me nā papahana.

Hōʻuluʻulu

ʻAʻole ʻo ka palekana kahi mea hiki iā ʻoe ke hoʻokō i kahi ala hoʻokahi no nā mea āpau āu e makemake ai e pale. He mea nui ka hiki ke pale i nā ʻōnaehana ma nā pae like ʻole a ma nā ʻano like ʻole. E manaʻoʻiʻo a ʻaʻole paha, ʻo ke ala maikaʻi loa e hoʻopaʻa ai i kahi ʻōnaehana ʻo ia ka hoʻonohonoho ʻana i nā pae like ʻole o ka pale mai nā kūlana like ʻole, i hiki ʻole ai i ka hōʻemi ʻana i ka palekana o kahi pae ke komo i ka ʻōnaehana holoʻokoʻa. Ua hana nui nā mea hoʻomohala kumu i ka hāʻawi ʻana iā mākou i kahi hoʻonohonoho o nā papa like ʻole a me nā pā. Manaʻo mākou ua hāʻawi mākou iā ʻoe i ka ʻike maikaʻi i ke ʻano o nā papa a pehea e hoʻohana ai i nā polokalamu BPF e hana pū me lākou.

No nā mea kākau

David Calavera ʻO ia ka CTO ma Netlify. Ua hana ʻo ia ma ke kākoʻo Docker a kōkua i ka hoʻomohala ʻana i nā mea hana Runc, Go a me BCC, a me nā papahana open source ʻē aʻe. ʻIke ʻia no kāna hana ma nā papahana Docker a me ka hoʻomohala ʻana o ka Docker plugin ecosystem. Ua makemake nui ʻo David e pili ana i nā kiʻi lapalapa a ke ʻimi mau nei ʻo ia e hoʻomaikaʻi i ka hana.

ʻO Lorenzo Fontana hana ʻo ia ma ka hui open source ma Sysdig, kahi i kālele nui ʻia ai ʻo Falco, kahi papahana Cloud Native Computing Foundation e hāʻawi ana i ka palekana runtime pahu a me ka ʻike anomaly ma o ka kernel module a me ka eBPF. Makemake ʻo ia e pili ana i nā ʻōnaehana puʻupuʻu, ka ʻoihana pūnaewele i wehewehe ʻia, ka kernel Linux, a me ka nānā ʻana i ka hana.

» Hiki ke loaʻa nā kikoʻī hou aku e pili ana i ka puke ma punaewele o ka mea hoʻopuka
» Ka papa o nā mea
» ʻĀpana ʻlelo

No Khabrozhiteley 25% ho'ēmi me ka hoʻohana coupon - Linux

Ma ka uku ʻana i ka mana pepa o ka puke, e hoʻouna ʻia kahi puke uila ma ka leka uila.

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka