Libseccomp: RFE: perluas dukungan SCMP_FLTATR_API_SYSRAWRC ke API notifikasi

Dibuat pada 13 Nov 2020  ·  5Komentar  ·  Sumber: seccomp/libseccomp

Implementasi seccomp_notify_receive() hanya menggunakan:

        if (ioctl(fd, SECCOMP_IOCTL_NOTIF_RECV, req) < 0)
                return -ECANCELED;

Terlepas dari kesalahan dalam errno , ia mengembalikan -ECANCELED .

Saat men-debug dengan strace, saya menemukan bahwa ioctl mengembalikan EINTR karena sinyal SIGURG:

1448850 ioctl(7, SECCOMP_IOCTL_NOTIF_RECV <unfinished ...>
1448230 getpid()                        = 1448217
1448230 tgkill(1448217, 1448850, SIGURG) = 0
1448850 <... ioctl resumed>, 0x7fc65d49ecd0) = -1 EINTR (Interrupted system call)

Sinyal SIGURL dihasilkan oleh runtime Golang, lihat detailnya di https://go-review.googlesource.com/c/go/+/232862/
Menurut laporan itu, syscall seharusnya diterbitkan kembali saat mendapatkan EINTR.
Idealnya libseccomp harus menanganinya, sehingga transparan bagi pengguna.

Sebagai solusinya, saya mencoba mengeluarkan ulang panggilan sys dengan memanggil seccomp_notify_receive() di program saya, dan melakukan hal yang sama di seccomp_notify_respond() karena memiliki pola yang sama:

        if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0)
                return -ECANCELED;

Tetapi terkadang saya mendapatkan nilai pengembalian errno = ENOENT:

1497880 ioctl(12, SECCOMP_IOCTL_NOTIF_SEND, 0x7f718fd28e10) = -1 ENOENT (No such file or directory)

libseccomp tidak mengizinkan saya untuk membedakan antara ENOENT (proses target telah terputus sebelum memanggil SECCOMP_IOCTL_NOTIF_SEND ) dan EINTR (agen seccomp terganggu oleh sinyal SIGURG).

Selain itu, saya tidak dapat membaca errno dari Golang, jadi saya tidak dapat menemukan solusinya.

enhancement prioritmedium

Komentar yang paling membantu

Tetapi fungsi baru ... menggunakan _rc_filter() dan bukan _rc_filter_sys() ...

Ah... maaf soal itu. Sebenarnya, ini lebih dalam dari level API, lihat di "system.c" dan Anda akan melihat bahwa panggilan level sistem libseccomp tidak menyebarkannya ke fungsi level API. Melihat halaman manual, tampaknya kami tidak membuat klaim apa pun tentang SCMP_FLTATR_API_SYSRAWRC untuk API notifikasi (lihat seccomp_load(3) untuk contoh penghitung).

Saya akan melanjutkan dan membuka kembali ini sebagai RFE karena saat ini kami tidak membuat klaim apa pun tentang pekerjaan ini.

@drakenclimber Saya pikir ini adalah materi v2.6.x (mungkin v2.5.2) karena saya tidak ingin memperlambat rilis v2.5.1. Jika Anda berpikir sebaliknya, beri tahu saya.

Semua 5 komentar

Halo @alban.

Lihat SCMP_FLTATR_API_SYSRAWRC di halaman manual seccomp_attr_set(3) :

Bendera untuk menentukan apakah libseccomp harus meneruskan kode kesalahan sistem kembali ke pemanggil alih-alih -ECANCELED default. Default ke off (nilai == 0).

Kami memaksa -ECANCELED dalam hal ini untuk memastikan janji kode pengembalian yang stabil di libseccomp API di berbagai versi kernel/libc. Kami menawarkan SCMP_FLTATR_API_SYSRAWRC untuk penelepon yang masih ingin melihat kode pengembalian kernel/libc yang sebenarnya, harap diingat bahwa kami tidak menjamin kode pengembalian yang stabil jika Anda mengaktifkan atribut tersebut.

Saya akan menutup masalah ini sebagai NOTABUG, tetapi jangan ragu untuk terus mendiskusikannya di sini jika Anda memiliki pertanyaan tambahan. Kami dapat membuka kembali jika sepertinya ada masalah nyata yang perlu ditangani.

Hai @pcmoore , terima kasih atas balasan cepatnya.

Kami menawarkan SCMP_FLTATR_API_SYSRAWRC untuk penelepon yang masih ingin melihat kode pengembalian kernel/libc yang sebenarnya

Tapi fungsi baru

  • seccomp_notify_receive
  • seccomp_notify_respond
  • seccomp_notify_id_valid

menggunakan _rc_filter() dan bukan _rc_filter_sys() , jadi SCMP_FLTATR_API_SYSRAWRC seharusnya tidak berpengaruh, jika saya tidak salah.

Tetapi fungsi baru ... menggunakan _rc_filter() dan bukan _rc_filter_sys() ...

Ah... maaf soal itu. Sebenarnya, ini lebih dalam dari level API, lihat di "system.c" dan Anda akan melihat bahwa panggilan level sistem libseccomp tidak menyebarkannya ke fungsi level API. Melihat halaman manual, tampaknya kami tidak membuat klaim apa pun tentang SCMP_FLTATR_API_SYSRAWRC untuk API notifikasi (lihat seccomp_load(3) untuk contoh penghitung).

Saya akan melanjutkan dan membuka kembali ini sebagai RFE karena saat ini kami tidak membuat klaim apa pun tentang pekerjaan ini.

@drakenclimber Saya pikir ini adalah materi v2.6.x (mungkin v2.5.2) karena saya tidak ingin memperlambat rilis v2.5.1. Jika Anda berpikir sebaliknya, beri tahu saya.

Terima kasih!

Sebagai catatan, saya menemukan solusi di sisi Golang untuk dapat membedakan ENOENT dan EINTR, dengan pola kode ini:

-   if retCode := C.seccomp_notify_respond(C.int(fd), resp); retCode != 0 {
-       return errRc(retCode)
+   for {
+       retCode, errno := C.seccomp_notify_respond(C.int(fd), resp)
+       if errno == syscall.EINTR {
+           continue
+       }
+       if errno == syscall.ENOENT {
+           return errno
+       }
+       if retCode != 0 {
+           return errRc(retCode)
+       }
+       break
    }

Dengan ini, tampaknya berfungsi dengan baik dengan libseccomp-2.5.0,

Apakah halaman ini membantu?
0 / 5 - 0 peringkat