Untuk menguji peningkatan kinerja pohon biner yang saya usulkan, saya menulis seperangkat aturan yang tidak realistis untuk read() dan argumen ukuran buffernya (A2). Tetapi tampaknya komit pengerjaan ulang src/db.c (ce3dda9a1) merusak pemrosesan A2 - setidaknya untuk kasus uji ini.
Sebelum komit pengerjaan ulang db, baca seperti berikut - read(devzero_fd, buf, 8000)
- dikembalikan -10
. Setelah komit ini, sekarang mengembalikan -5
.
Inilah kode C yang saya gunakan untuk membuat aturan read() konyol saya:
/* read */
for (i = 5; i <= 12; i++) {
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), SCMP_SYS(read), 1,
SCMP_A2(SCMP_CMP_GT, 4 << i));
if (rc < 0) {
fprintf(stdout, "%s:%d Failed to add read rule %d : rc = %d\n",
__FUNCTION__, __LINE__, i, rc);
goto error;
}
}
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1,
SCMP_A2(SCMP_CMP_LE, 64));
if (rc < 0) {
fprintf(stdout, "%s:%d Failed to add read allow rule : rc = %d\n",
__FUNCTION__, __LINE__, rc);
goto error;
}
Dan inilah PFC yang dihasilkannya:
# filter for syscall "read" (0) [priority: 65525]
if ($syscall == 0)
if ($a2.hi32 >= 0)
if ($a2.lo32 > 64)
else
action ALLOW;
if ($a2.lo32 > 16384)
action ERRNO(12);
if ($a2.lo32 > 8192)
action ERRNO(11);
if ($a2.lo32 > 4096)
action ERRNO(10);
if ($a2.lo32 > 2048)
action ERRNO(9);
if ($a2.lo32 > 1024)
action ERRNO(8);
if ($a2.lo32 > 512)
action ERRNO(7);
if ($a2.lo32 > 256)
action ERRNO(6);
if ($a2.lo32 > 128)
action ERRNO(5);
else
action ALLOW;
# default action
action ERRNO(34);
Omong-omong, saya akan melakukan apa yang saya bisa untuk membantu akar penyebabnya
Menggunakan scmp_bpf_disasm, libseccomp terbaru menempatkan lompatan dalam urutan yang salah
KEPALA
0014: 0x25 0x11 0x00 0x00000080 jgt 128 true:0032 false:0015
0015: 0x25 0x0f 0x00 0x00000100 jgt 256 true:0031 false:0016
0016: 0x25 0x0d 0x00 0x00000200 jgt 512 true:0030 false:0017
0017: 0x25 0x0b 0x00 0x00000400 jgt 1024 true:0029 false:0018
0018: 0x25 0x09 0x00 0x00000800 jgt 2048 true:0028 false:0019
0019: 0x25 0x07 0x00 0x00001000 jgt 4096 true:0027 false:0020
0020: 0x25 0x05 0x00 0x00002000 jgt 8192 true:0026 false:0021
0021: 0x25 0x03 0x00 0x00004000 jgt 16384 true:0025 false:0022
0022: 0x25 0x01 0x00 0x00000040 jgt 64 true:0024 false:0023
0023: 0x06 0x00 0x00 0x7fff0000 ret ALLOW
pra-pengerjaan ulang
0014: 0x25 0x01 0x00 0x00000040 jgt 64 true:0016 false:0015
0015: 0x06 0x00 0x00 0x7fff0000 ret ALLOW
0016: 0x25 0x0f 0x00 0x00004000 jgt 16384 true:0032 false:0017
0017: 0x25 0x0d 0x00 0x00002000 jgt 8192 true:0031 false:0018
0018: 0x25 0x0b 0x00 0x00001000 jgt 4096 true:0030 false:0019
0019: 0x25 0x09 0x00 0x00000800 jgt 2048 true:0029 false:0020
0020: 0x25 0x07 0x00 0x00000400 jgt 1024 true:0028 false:0021
0021: 0x25 0x05 0x00 0x00000200 jgt 512 true:0027 false:0022
0022: 0x25 0x03 0x00 0x00000100 jgt 256 true:0026 false:0023
0023: 0x25 0x01 0x00 0x00000080 jgt 128 true:0025 false:0024
0024: 0x06 0x00 0x00 0x00050022 ret ERRNO(34)
Menarik. Jadi PFC tampaknya "benar", tetapi BPF yang dihasilkan adalah ... mundur. Aneh. Terutama mengingat bahwa komit tidak mengubah kode pembuatan BPF.
Saya ingin tahu apakah nilai prioritas entah bagaimana menjadi kacau?
Maaf atas ambiguitasnya. PFC (posting perubahan pengerjaan ulang) juga dalam urutan yang salah. PFC yang saya posting di atas adalah urutannya sebelum pengerjaan ulang db.c.
Inilah PFC yang saat ini dihasilkan oleh HEAD
# filter for syscall "read" (0) [priority: 65525]
if ($syscall == 0)
if ($a2.hi32 >= 0)
if ($a2.lo32 > 128)
action ERRNO(5);
if ($a2.lo32 > 256)
action ERRNO(6);
if ($a2.lo32 > 512)
action ERRNO(7);
if ($a2.lo32 > 1024)
action ERRNO(8);
if ($a2.lo32 > 2048)
action ERRNO(9);
if ($a2.lo32 > 4096)
action ERRNO(10);
if ($a2.lo32 > 8192)
action ERRNO(11);
if ($a2.lo32 > 16384)
action ERRNO(12);
if ($a2.lo32 > 64)
else
action ALLOW;
else
action ALLOW;
# default action
action ERRNO(34);
Oke, itu sedikit lebih masuk akal. Masalahnya pasti ada di suatu tempat di lapisan db.
Agak lucu bagaimana persisnya terbalik.
Saya menemukan masalahnya. Dalam manajemen argumen rantai, perilaku lvl_nxt dan lvl_prv bertukar setelah pengerjaan ulang db.c besar-besaran. Beberapa perubahan kecil pada _db_tree_add() membuatnya cocok dengan perilaku libseccomp sebelumnya.
Inilah cabang dengan perbaikannya
https://github.com/drakenclimber/libseccomp/tree/issues/112
Saya akan membersihkan perubahan, menambahkan satu atau dua tes, dan memastikan cakupan kode sudah habis.
Saya menemukan waktu pagi ini, mungkin tepat sebelum Anda memposting hal di atas, dan memutuskan untuk melihat ini sedikit. Sepertinya kami sampai pada kesimpulan yang hampir sama, meskipun perbaikannya sedikit berbeda. Ini adalah perbaikan saya saat ini, meskipun seperti milik Anda, perlu beberapa pekerjaan/pembersihan tambahan:
Saya tidak yakin pendekatan mana yang lebih saya sukai saat ini, saya perlu memikirkan ini sedikit, pikiran?
Hmmm... Saya tidak akan berbohong; Saya tidak terpikat dengan salah satu perbaikan pada saat ini.
Milik saya sederhana, tetapi sepenuhnya mengabaikan _db_tree_prune() yang - seperti yang Anda katakan di Intisari Anda - mungkin memiliki masalah serupa.
Saya suka ide Anda untuk mengerjakan ulang makro gt() untuk memanfaatkan makro lt() dan eq(), tetapi mereka semakin berat - terutama lt(). Apakah ada alasan untuk tidak mengonversi lt() ke fungsi sebaris?
EDIT - Saya baru tahu Anda membuat komentar serupa di intinya.
Saya menjalankan gdb terhadap libseccomp dan HEAD lama, dan perilaku lvl_prv dan lvl_nxt memang berubah, tetapi mungkin itu bukan masalah besar karena ini adalah variabel internal yang tidak boleh dilihat siapa pun kecuali kita.
Saya kira setelah semua bertele-tele ini ... Saya tidak tahu. Saya setuju, saya harus memikirkannya;)
Hmmm... Saya tidak akan berbohong; Saya tidak terpikat dengan salah satu perbaikan pada saat ini.
Saya khawatir bahwa ada beberapa bug halus dengan menyusun ulang level pohon seperti ini, meskipun sepertinya level tersebut disusun ulang oleh komit sebelumnya dan ini adalah salah satu bug halus.
Apa pun itu, saya ingin memahami seperti apa urutan yang diinginkan untuk suatu level: "terbesar" terlebih dahulu, atau "terbesar" terakhir? Setelah kami memahaminya, kami dapat melanjutkan dengan pengujian/perbaikan. Saya pikir jawabannya, jika tidak ada alasan lain selain kompatibilitas dengan rilis 2.x sebelumnya, adalah yang "terbesar" terlebih dahulu, tetapi saya tidak dapat mengatakannya dengan pasti saat ini.
Milik saya sederhana, tetapi sepenuhnya mengabaikan _db_tree_prune() yang - seperti yang Anda katakan di Intisari Anda - mungkin memiliki masalah serupa.
Mereka berdua pada dasarnya melakukan hal yang sama pada prinsipnya, milik saya melangkah lebih jauh dengan menambahkan beberapa kondisi tambahan dan membersihkan makro db_chain_lt(x,y).
Saya suka ide Anda untuk mengerjakan ulang makro gt() untuk memanfaatkan makro lt() dan eq(), tetapi mereka semakin berat - terutama lt(). Apakah ada alasan untuk tidak mengonversi lt() ke fungsi sebaris?
Sebagian besar alasan historis. Mereka memulai hidup sebagai makro yang jauh lebih sederhana, tetapi mereka telah tumbuh sedikit ke titik di mana saya pikir mereka mungkin seharusnya menjadi fungsi. Saya pikir itu juga akan baik untuk mengevaluasi apakah mereka benar-benar perlu ada di file header, saya yakin mereka hanya digunakan oleh src/db.c.
Saya menjalankan gdb terhadap libseccomp dan HEAD lama, dan perilaku lvl_prv dan lvl_nxt memang berubah, tetapi mungkin itu bukan masalah besar karena ini adalah variabel internal yang tidak boleh dilihat siapa pun kecuali kita.
Ya, ini adalah status/pohon internal, saya tidak terlalu khawatir tentang itu. Yang penting adalah kebenaran filter yang dihasilkan.
Saya kira setelah semua bertele-tele ini ... Saya tidak tahu. Saya setuju, saya harus memikirkannya;)
Heh. Mari kita beri ini satu atau dua hari dan berkumpul kembali :) Saat ini ini tidak memengaruhi versi yang dirilis, itu hanya di cabang master, jadi kami punya waktu untuk memperbaikinya.
Saat ini, ini tidak memengaruhi versi yang dirilis, itu hanya di cabang master, jadi kami punya waktu untuk memperbaikinya.
Kedengarannya bagus. Saya akan membuat beberapa tes sementara kita memikirkan rencana
Saya menulis sebuah program untuk mengevaluasi penanganan seccomp A2 saat ini. Seluruh program tersedia di sini:
https://Gist.github.com/drakenclimber/3c6b45ecd973ee495281ef225fa5e54a
Singkatnya, lebih besar dari aturan dihasilkan dalam urutan "terakhir dibuat" "diproses pertama".
>
dibuat dalam urutan menaik , misseccomp_rule_add(ctx, action1, syscall, 1, SCMP(SCMP_CMP_GT, 10)
seccomp_rule_add(ctx, action2, syscall, 1, SCMP(SCMP_CMP_GT, 20)
seccomp_rule_add(ctx, action3, syscall, 1, SCMP(SCMP_CMP_GT. 30)
if (A2 > 30)
do action3
if (A2 > 20)
do action2
if (A2 > 10)
do action1
>
dibuat dalam urutan menurun , misseccomp_rule_add(ctx, action3, syscall, 1, SCMP(SCMP_CMP_GT, 30)
seccomp_rule_add(ctx, action2, syscall, 1, SCMP(SCMP_CMP_GT, 20)
seccomp_rule_add(ctx, action1, syscall, 1, SCMP(SCMP_CMP_GT. 10)
if
tidak dapat dijangkauif (A2 > 10)
do action1
if (A2 > 20)
do action2
if (A2 > 30)
do action1
<
A2 saat ini tidak diizinkan oleh seccomp. Ini tampak aneh karena saya tidak dapat menemukan cara untuk membuat <=
setara dengan >
filter di atastom<strong i="43">@OracleDesktop</strong> $ ./a2test 3
Failed to add rule
action = 0x5000e op = 0x3 datum = 18000 rc = -17
Mode 3 (LE descending) test failed. rc = -17
tom<strong i="46">@OracleDesktop</strong> $ ./a2test 4
Failed to add rule
action = 0x50006 op = 0x3 datum = 250 rc = -17
Mode 4 (LE ascending) test failed. rc = -17
Saya menduga logika else if
terkubur jauh di src/db.c
menyebabkan <
gagal, mis. Saya tidak yakin apakah itu layak diubah/diperbaiki.
Saya akan mencoba dan mengubah beberapa kode ini menjadi pengujian otomatis sehingga kami dapat menangkap perilaku saat ini.
Seperti yang tertulis, intinya di sini gagal dalam tes otomatis yang saya tambahkan minggu lalu. Saya akan menggali dan mencoba mencari tahu mengapa.
batch name: 43-sim-a2_order
test mode: c
test type: bpf-sim
Test 43-sim-a2_order%%001-00001 result: SUCCESS
Test 43-sim-a2_order%%002-00001 result: SUCCESS
Test 43-sim-a2_order%%003-00001 result: SUCCESS
Test 43-sim-a2_order%%004-00001 result: SUCCESS
Test 43-sim-a2_order%%005-00001 result: SUCCESS
Test 43-sim-a2_order%%006-00001 result: SUCCESS
Test 43-sim-a2_order%%007-00001 result: SUCCESS
Test 43-sim-a2_order%%008-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%009-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%010-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%011-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%012-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%013-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%014-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%015-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%016-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%017-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%018-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%019-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%020-00001 result: FAILURE bpf_sim resulted in ERRNO(5)
Buruk saya - saya salah menerapkan intinya. Ujian sedang berlalu. Fiuh :)
Ha! :)
Saya pikir saya menjalankan tes terhadapnya, tetapi saya bermain dengan banyak hal pada waktu itu, jadi saya pikir saya hanya salah mengingat. Terima kasih untuk terus melihat ini, saya masih sedikit macet dengan SELinux dan audit, tetapi karena kernel berada di -rc5 sekarang, saya berharap untuk segera tenang setelah saya meletakkan istirahat pada kode baru sebelum penggabungan jendela...
Jangan khawatir. Itu pasti prioritas yang lebih tinggi.
Saya telah menjalankan Intisari Anda melalui berbagai tes yang tidak realistis. Saya belum memecahkannya, tetapi saya juga hanya melatih sedikit demi sedikit _db_tree_prune() sejauh ini. Saya mulai merasa lebih nyaman dengan perubahan, tetapi saya ingin mendapatkan sedikit lebih banyak waktu untuk itu.
Saya menyodok dan mendorong kode _db_tree_prune() dan saya tidak dapat memecahkannya. Test 08-sim-subtree_checks benar-benar melakukan pekerjaan yang baik untuk menguji sebagian besar jalur kode dalam Prune().
Saya pikir perubahan dari inti Anda bagus untuk dilakukan.
Saya mengirimkan permintaan tarik #115. Saya pikir ini siap untuk bergulir
Penutupan karena ini sekarang harus diselesaikan (lihat riwayat di atas).