Libseccomp: BUG: SCMP_CMP_GT/GE/LT/LE tidak berfungsi seperti yang diharapkan untuk argumen syscall negatif

Dibuat pada 18 Jan 2017  ·  20Komentar  ·  Sumber: seccomp/libseccomp

Hai!

Saya tidak yakin apakah perilaku SCMP_CMP_GT/GE/LT/LE saat ini berfungsi sebagaimana mestinya atau apakah ada bug dalam implementasinya. Halaman manual untuk seccomp_rule_add hanya mengatakan ini tentang SCMP_CMP_GT:

SCMP_CMP_GT:
        Matches when the argument value is greater than the datum value,
        example:

        SCMP_CMP( arg , SCMP_CMP_GT , datum )

Halaman manual tidak menentukan jenis untuk datum dan memiliki contoh untuk berbagai jenis (tersirat) (dan satu dilemparkan ke scmp_datum_t).

Berdasarkan halaman manual, saya mengharapkan sesuatu seperti ini berfungsi untuk nilai apa pun yang diberikan pada argumen ke-3 setpriority (anggap kebijakan default SCMP_ACT_ALLOW untuk ini):

rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM),
        SCMP_SYS(setpriority),
        3,
        SCMP_A0(SCMP_CMP_EQ, PRIO_PROCESS),
        SCMP_A1(SCMP_CMP_EQ, 0),
        SCMP_A2(SCMP_CMP_GT, 0));

Sebaliknya, setpriority(PRIO_PROCESS, 0, -1) mengakibatkan syscall diblokir ketika '-1' jelas kurang dari '0'. setpriority(PRIO_PROCESS, 0, 0) dan setpriority(PRIO_PROCESS, 0, 1) bekerja seperti yang diharapkan. Apa yang terjadi adalah bahwa '-1' sedang dikonversi ke scmp_datum_t (uint64_t dari secomp.h.in) yang tentu saja membuatnya positif, tetapi SCMP_CMP_GT dan teman-teman tidak menangani konversi ini. SCMP_CMP_EQ berfungsi dengan baik dengan datum negatif (menebak datum masih positif (saya tidak memverifikasi), tetapi perbandingannya adalah antara scmp_datum_t yang dikonversi).

Perilaku ini dikonfirmasi dengan 2.1.0+dfsg-1 (Ubuntu 14.04 LTS, 3.13 kernel), 2.2.3-3ubuntu3 (Ubuntu 16.04 LTS, 4.9 kernel), 2.3.1-2ubuntu2 (Ubuntu 17.04 dev rilis, 4.9 kernel) dan master dari beberapa saat yang lalu (pada rilis dev Ubuntu 17.04, kernel 4.9), semuanya di amd64.

AFAICT, tidak ada tes untuk SCMP_CMP_GT dan SCMP_CMP_LE. Beberapa tes untuk SCMP_CMP_LT tampaknya tidak memperhitungkan nilai negatif dan juga tidak untuk SCMP_CMP_GE (mohon koreksi saya jika saya salah).

Pertanyaannya kemudian: apakah perilaku ini disengaja? Jika demikian, sementara saya mengakui bahwa dapat dikatakan bahwa halaman manual akurat karena ini berfungsi dengan benar ketika memahami scmp_datum_t adalah tipe data, situasi ini tidak segera jelas dan halaman manual mungkin harus mengatakan bahwa aplikasi perlu memperhitungkan ini. Jika tidak, ini tampaknya merupakan bug dalam implementasi untuk SCMP_CMP_GT/GE/LT/LE.

Berikut adalah program kecil yang menunjukkan masalah ini dengan SCMP_CMP_GT, meskipun GE, LT dan LE semuanya dapat diamati memiliki perilaku yang sama:

/*
 * gcc -o test-nice test-nice.c -lseccomp
 * sudo ./test-nice 0 1  # should be denied
 * sudo ./test-nice 0 0  # should be allowed
 * sudo ./test-nice 0 -1 # should be allowed?
 */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <stdarg.h>
#include <seccomp.h>
#include <sys/resource.h>

int main(int argc, char **argv)
{
    if (argc < 3) {
        fprintf(stderr, "test-nice N N\n");
        return 1;
    }

    int rc = 0;
    scmp_filter_ctx ctx = NULL;
    int filter_n = atoi(argv[1]);
    int n = atoi(argv[2]);

    // Allow everything by default for this test
    ctx = seccomp_init(SCMP_ACT_ALLOW);
    if (ctx == NULL)
        return ENOMEM;

    printf("set EPERM for nice(>%d)\n", filter_n);
    rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM),
            SCMP_SYS(setpriority),
            3,
            SCMP_A0(SCMP_CMP_EQ, PRIO_PROCESS),
            SCMP_A1(SCMP_CMP_EQ, 0),
            SCMP_A2(SCMP_CMP_GT, filter_n));

    if (rc != 0) {
        perror("seccomp_rule_add failed");
        goto out;
    }

    rc = seccomp_load(ctx);
    if (rc != 0) {
        perror("seccomp_load failed");
        goto out;
    }

    // try to use the filtered syscall
    errno = 0;
    printf("Attempting nice(%d)\n", n);
    nice(n);
    if (errno != 0) {
        perror("could not nice");
        if (filter_n > n)
            fprintf(stderr, "nice(%d) unsuccessful. bug?\n", n);
        rc = 1;
        goto out;
    } else
        printf("nice(%d) successful\n", n);

out:
    seccomp_release(ctx);

    return rc;
}
bug prioritmedium

Semua 20 komentar

Terima kasih atas laporan masalah; itu bagus.

Kebetulan, sudahkah Anda mencoba menulis reproduksi menggunakan header/makro di direktori

Saya mendapat kesan bahwa kode BPF di kernel memperlakukan nilai langsung sebagai ditandatangani; itu mungkin tidak terjadi, atau saya mungkin telah mengacaukan sesuatu dalam kode libseccomp.

FWIW, BPF sendiri menggunakan u32 untuk argumennya. Apakah libseccomp melakukan ekstensi tanda pada argumen compat? (Mungkin seharusnya tidak, tetapi kemudian aturan untuk mencocokkan "-1" harus berbeda antara 32-bit dan 64-bit...)

Masalah yang mengkhawatirkan saya saat ini adalah perbandingan BPF GT/GE di operator lompat, terutama karena saya menduga sebagian besar orang telah memperlakukan BPF langsung sebagai nilai yang ditandatangani untuk perbandingan ini.

@kees apa pendekatan yang disarankan untuk melakukan perbandingan argumen syscall yang ditandatangani dengan mesin seccomp-bpf kernel? Saya berharap itu bukan sesuatu di sepanjang baris "periksa bit tinggi terlebih dahulu dan kemudian lakukan konversi pujian dua yang diperlukan sebelum membandingkan angka negatif". Meskipun menjengkelkan, kami selalu dapat mengubah libseccomp untuk menghasilkan BPF yang diperlukan (walaupun filter yang dihasilkan sekarang akan jauh lebih besar dalam beberapa kasus), tetapi saya khawatir tentang aplikasi yang membuat filter BPF mereka sendiri; kemungkinan mereka menangani ini dengan benar mungkin tidak terlalu bagus.

Sayangnya, karena argumen syscall adalah "unsigned long" (lihat syscall_get_arguments() dan struct seccomp_data), tidak ada kasus umum tentang bagaimana syscall menangani konversi tanda. Beberapa syscalls ketika melintasi penghalang compat akan melakukan perpanjangan tanda, yang lain (prctl) tidak. Apakah ada banyak argumen syscall negatif-tapi-tidak-kurang-satu?

Kembali ke hari ini, dan setelah bermain-main dengan hal-hal sedikit lebih pagi ini, saya pikir ini akan berakhir dengan dokumentasi/"hati-hati!" masalah karena tidak ada solusi yang baik, terutama ketika kita berbicara tentang pengguna yang ada. Izinkan saya mencoba memberikan beberapa latar belakang/penjelasan libseccomp untuk mengikuti komentar bermanfaat @kees dari sisi kernel.

FWIW, BPF sendiri menggunakan u32 untuk argumennya. Apakah libseccomp melakukan ekstensi tanda pada argumen compat? (Mungkin seharusnya tidak, tetapi kemudian aturan untuk mencocokkan "-1" harus berbeda antara 32[-bit dan 64-bit...)

Fungsi aturan API libseccomp menafsirkan semua mengambil nilai langsung sebagai _uint64_t_ jadi jika Anda ceroboh dengan tipe/casting Anda, Anda mungkin mengalami masalah. Contoh:

$ cat 00-test.c
    /* ... */
    seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
                           SCMP_A0(SCMP_CMP_GT, -1));
    seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1001, 1,
                           SCMP_A0(SCMP_CMP_GT, (uint32_t)-1));
    seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1002, 1,
                           SCMP_A0(SCMP_CMP_GT, 0xffffffff));
    /* ... */
$ make 00-test
  CC       00-test.o
  CCLD     00-test
$ ./00-test -p
  #
  # pseudo filter code start
  #
  # filter for arch x86_64 (3221225534)
  if ($arch == 3221225534)
    # filter for syscall "UNKNOWN" (1002) [priority: 65533]
    if ($syscall == 1002)
      if ($a0.hi32 >= 0)
        if ($a0.lo32 > 4294967295)
          action KILL;
    # filter for syscall "UNKNOWN" (1001) [priority: 65533]
    if ($syscall == 1001)
      if ($a0.hi32 >= 0)
        if ($a0.lo32 > 4294967295)
          action KILL;
    # filter for syscall "UNKNOWN" (1000) [priority: 65533]
    if ($syscall == 1000)
      if ($a0.hi32 >= 4294967295)
        if ($a0.lo32 > 4294967295)
          action KILL;
    # default action
    action ALLOW;
  # invalid architecture action
  action KILL;
  #
  # pseudo filter code end
  # 
$ ./00-test -b | ../tools/scmp_bpf_disasm 
   line  OP   JT   JF   K
  =================================
   0000: 0x20 0x00 0x00 0x00000004   ld  $data[4]
   0001: 0x15 0x00 0x0c 0xc000003e   jeq 3221225534 true:0002 false:0014
   0002: 0x20 0x00 0x00 0x00000000   ld  $data[0]
   0003: 0x35 0x0a 0x00 0x40000000   jge 1073741824 true:0014 false:0004
   0004: 0x15 0x00 0x02 0x000003e8   jeq 1000 true:0005 false:0007
   0005: 0x20 0x00 0x00 0x00000014   ld  $data[20]
   0006: 0x35 0x04 0x06 0xffffffff   jge 4294967295 true:0011 false:0013
   0007: 0x15 0x01 0x00 0x000003e9   jeq 1001 true:0009 false:0008
   0008: 0x15 0x00 0x04 0x000003ea   jeq 1002 true:0009 false:0013
   0009: 0x20 0x00 0x00 0x00000014   ld  $data[20]
   0010: 0x35 0x00 0x02 0x00000000   jge 0    true:0011 false:0013
   0011: 0x20 0x00 0x00 0x00000010   ld  $data[16]
   0012: 0x25 0x01 0x00 0xffffffff   jgt 4294967295 true:0014 false:0013
   0013: 0x06 0x00 0x00 0x7fff0000   ret ALLOW
   0014: 0x06 0x00 0x00 0x00000000   ret KILL

... seperti yang kita lihat, jika Anda menggunakan casting yang sesuai maka nilainya tidak diperpanjang. Namun, saya berharap ini bukan apa yang kebanyakan orang lakukan. Kabar baiknya adalah saya membayangkan jumlah syscalls yang mengambil argumen negatif relatif kecil, sehingga dampaknya harus agak terbatas.

Ke depan, kami pasti perlu memasukkan sesuatu ke dalam dokumen tentang ini dan melihat apakah kami dapat melakukan sesuatu untuk membuat hidup lebih mudah bagi pengembang, mungkin menerapkan varian 32-bit dari makro _SCMP_A*_.

@pcmoore - terima kasih atas tanggapan terperinci dan maaf karena tidak kembali lebih cepat. Tidak, saya belum mencoba menulis reproduksi berdasarkan https://github.com/torvalds/linux/tree/master/samples/seccomp , tetapi berdasarkan tanggapan Anda sepertinya saya tidak perlu melakukannya. Beri tahu saya jika Anda membutuhkan yang lain. Untuk saat ini, saya akan mengambil pendekatan 'hati-hati' dan melaporkan kembali jika saya memiliki masalah, dan menantikan bagaimana Anda dapat membuat ini lebih mudah untuk diperbaiki di masa mendatang.

@jdstrand Saya pikir kita sudah siap untuk saat ini. Sekali lagi terima kasih atas laporannya, maaf saya tidak punya jawaban yang lebih baik untuk Anda, tapi mudah-mudahan kami akan memiliki sesuatu di masa depan.

Sementara itu, jika Anda pernah mengalami masalah dengan jenis nilai pemeran yang benar, jangan ragu untuk memperbarui masalah ini.

Kabar baiknya adalah saya membayangkan jumlah syscalls yang mengambil argumen negatif relatif kecil, sehingga dampaknya harus agak terbatas.

Saya baru saja mengalami masalah ini ketika memeriksa (antara lain) apakah parameter fd openat() sama dengan nilai khusus AT_FDCWD yaitu -100. Hal ini menyebabkan:

  # filter for syscall "openat" (257) [priority: 131067]
  if ($syscall == 257)
    if ($a0.hi32 == 4294967295)
      if ($a0.lo32 == 4294967196)
        if ($a2.hi32 & 0x00000000 == 0)
          if ($a2.lo32 & 0x00000003 == 0)
            action ERRNO(2);

Dimana seharusnya:

  # filter for syscall "openat" (257) [priority: 131067]
  if ($syscall == 257)
    if ($a0.hi32 == 0)
      if ($a0.lo32 == 4294967196)
        if ($a2.hi32 & 0x00000000 == 0)
          if ($a2.lo32 & 0x00000003 == 0)
            action ERRNO(2);

Karena glibc 2.26+ tampaknya secara eksklusif menggunakan syscall openat dengan AT_FDCWD untuk mengimplementasikan open() ini mungkin membuat banyak orang tersandung. Menerapkan gips ke uint32_t seperti yang disarankan di atas memperbaiki masalah bagi saya:

        // selector, action, syscall, no of args, args
        { SEL, SCMP_ACT_ERRNO(ENOENT), "openat", 2,
-               { SCMP_A0(SCMP_CMP_EQ, AT_FDCWD), /* glibc 2.26+ */
+               { SCMP_A0(SCMP_CMP_EQ, (uint32_t)AT_FDCWD), /* glibc 2.26+ */
                  SCMP_A2(SCMP_CMP_MASKED_EQ, O_ACCMODE, O_RDONLY) }},

SCMP_A0_U32 eksplisit pasti akan menyenangkan untuk dimiliki.

@drakenclimber @jdstrand @michaelweiser apa yang kalian pikirkan https://github.com/pcmoore/misc-libseccomp/commit/b9ce39d776ed5a984c7e9e6db3b87463edce82a7 sebagai memperbaiki ini?

@pcmoore : Terima kasih untuk terus melihat ini! Saya baru saja memutarnya dan terlihat sangat bagus dalam kode:

static struct {
        const uint64_t promises;
        const uint32_t action;
        const char *syscall;
        const int arg_cnt;
        const struct scmp_arg_cmp args[3];
} scsb_calls[] = {
[...]
        { PLEDGE_WPATH, SCMP_ACT_ALLOW, "openat", 2, /* glibc 2.26+ */
                { SCMP_A0_32(SCMP_CMP_EQ, AT_FDCWD),
                  SCMP_A2_64(SCMP_CMP_MASKED_EQ, O_ACCMODE, O_WRONLY) }},

Sayangnya sepertinya fungsi pembantu tidak cocok sebagai penginisialisasi struct:

In file included from pledge.c:42:
/include/seccomp.h:230:26: error: initializer element is not constant
 #define SCMP_CMP32(...)  (__scmp_arg_32(SCMP_CMP64(__VA_ARGS__)))
                          ^
/include/seccomp.h:241:26: note: in expansion of macro ‘SCMP_CMP32’
 #define SCMP_A0_32(...)  SCMP_CMP32(0, __VA_ARGS__)
                          ^~~~~~~~~~
pledge.c:188:5: note: in expansion of macro ‘SCMP_A0_32’
   { SCMP_A0_32(SCMP_CMP_EQ, AT_FDCWD),
     ^~~~~~~~~~
/include/seccomp.h:230:26: note: (near initialization for ‘scsb_calls[21].args[0]’)
 #define SCMP_CMP32(...)  (__scmp_arg_32(SCMP_CMP64(__VA_ARGS__)))
                          ^
/include/seccomp.h:241:26: note: in expansion of macro ‘SCMP_CMP32’
 #define SCMP_A0_32(...)  SCMP_CMP32(0, __VA_ARGS__)
                          ^~~~~~~~~~
pledge.c:188:5: note: in expansion of macro ‘SCMP_A0_32’
   { SCMP_A0_32(SCMP_CMP_EQ, AT_FDCWD),
     ^~~~~~~~~~

Terima kasih atas ulasannya @michaelweiser , sayangnya saya tidak berpikir orang menggunakan makro ini sebagai penginisialisasi, tetapi itu adalah penggunaan yang valid dan pasti ada beberapa orang yang menggunakannya dengan cara ini.

Saya perlu memikirkan ini sebentar ... apakah Anda punya ide tentang bagaimana menyelesaikan ini dengan cara yang elegan?

Tidak tahu, maaf, saya sudah membuka mata saya dengan korek api. :)

Melihatnya sekarang, saya pikir saya melihat masalahnya: Karena daftar argumen variabel, Anda tidak dapat menyuntikkan gips yang diperlukan, bukan?

Bisakah scmp_arg_cmp mungkin berisi gabungan yang memberikan pandangan berbeda pada data dengan lebar, perataan yang benar (dan mungkin bahkan urutan byte) (yang IMO agak bertentangan dengan "elegan"):? Jika itu murni internal untuk libseccomp dan tidak perlu kompatibel dengan antarmuka kernel, dapatkah ia membawa indikator tipe data sebagai bidang terpisah dan meminta fungsi pengguna menyelesaikannya? Dan bisakah itu diinisialisasi menggunakan varargs?

Jika tidak, alih-alih menandai operasi secara keseluruhan 32/64 bit, dapatkah operan diberi anotasi, membungkus gips dan memberikan rekomendasi tegas kepada pengguna (seperti yang Anda lakukan) untuk selalu menggunakan anotasi tersebut dengan penalti karena kesulitan men-debug masalah ?

{ SCMP_A0(SCMP_CMP_EQ, SCMP_OP_32(AT_FDCWD)),
  SCMP_A2(SCMP_CMP_MASKED_EQ, SCMP_OP_64(O_ACCMODE), SCMP_OP_64(O_WRONLY)) }},

atau

{ SCMP_A0(SCMP_CMP_EQ, SCMP_OP1_32(AT_FDCWD)),
  SCMP_A2(SCMP_CMP_MASKED_EQ, SCMP_OP2_64(O_ACCMODE, O_WRONLY)) }},

Saya tidak cukup dengan celah praprosesor untuk menghasilkan lebih banyak lagi, maaf.

@pcmoore , perubahannya terlihat bagus bagi saya. Saya bukan ahli praprosesor, tetapi saya akan melihat masalah yang disebutkan @michaelweiser di atas

Melihatnya sekarang, saya pikir saya melihat masalahnya: Karena daftar argumen variabel, Anda tidak dapat menyuntikkan gips yang diperlukan, bukan?

Ya, kurang lebih seperti itu. Mungkin ada cara yang tidak buruk untuk itu, tetapi saya belum menemukannya.

Bisakah scmp_arg_cmp mungkin berisi gabungan yang memberikan pandangan berbeda pada data dengan lebar, perataan yang benar (dan mungkin bahkan urutan byte) (yang IMO agak bertentangan dengan "elegan"):? Jika itu murni internal untuk libseccomp dan tidak perlu kompatibel dengan antarmuka kernel, dapatkah ia membawa indikator tipe data sebagai bidang terpisah dan meminta fungsi pengguna menyelesaikannya? Dan bisakah itu diinisialisasi menggunakan varargs?

Kami memiliki masalah bahwa scmp_arg_cmp struct adalah bagian dari libseccomp API jadi kecuali kami ingin menabrak versi utama libseccomp, kami tidak dapat benar-benar mengubah ukuran struct atau offset bidang anggota mana pun; melakukannya akan merusak antarmuka biner yang ada dengan aplikasi yang ada. Mengubah bidang datum 64-bit menjadi gabungan yang berisi nilai 64-bit atau 32-bit seharusnya tidak masalah, tetapi Anda juga perlu menambahkan beberapa informasi tambahan ke scmp_arg_cmp struct untuk menunjukkan anggota serikat mana yang akan digunakan ; bendera ekstra inilah yang bisa menjadi masalah.

Dimungkinkan untuk mencuri beberapa bit dari bidang "arg" atau "op", keduanya adalah nilai 32-bit dan hanya menggunakan sebagian kecil dari ruang itu. Namun, saya menganggap itu pilihan yang agak ekstrem dan saya ingin menghindarinya jika memungkinkan.

Jika tidak, alih-alih menandai operasi secara keseluruhan 32/64 bit, dapatkah operan diberi anotasi, membungkus gips dan memberikan rekomendasi tegas kepada pengguna (seperti yang Anda lakukan) untuk selalu menggunakan anotasi tersebut dengan penalti karena kesulitan men-debug masalah ?

Saya tidak begitu mengerti apa yang akan kita peroleh dengan membungkus operan dengan makro, dapatkah Anda menjelaskan lebih lanjut? Kami dapat menyediakan makro untuk membungkus nilai datum, tetapi itu tidak benar-benar berbeda dari sekadar meminta penelepon untuk memberikan casting yang tepat.

@pcmoore , perubahannya terlihat bagus bagi saya. Saya bukan ahli praprosesor, tetapi saya akan melihat masalah yang disebutkan @michaelweiser di atas

Terima kasih banyak. Semoga di antara kami bertiga, kami dapat menemukan sesuatu yang bermanfaat di sini.

@pcmoore : Melihat http://efesx.com/2010/07/17/variadic-macro-to-count-number-of-arguments/ dan http://efesx.com/2010/08/31/overloading- macro/ Saya datang dengan yang berikut:

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N
#define macro_dispatcher(func, ...) \
            macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) \
            macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) \
            func ## nargs

#define SCMP_CMP64(...)         ((struct scmp_arg_cmp){__VA_ARGS__})

#define SCMP_CMP32_1(x)                 SCMP_CMP64(x)
#define SCMP_CMP32_2(x, y)              SCMP_CMP64(x, y)
#define SCMP_CMP32_3(x, y, z)           SCMP_CMP64(x, y, (uint32_t)(z))
#define SCMP_CMP32_4(x, y, z, q)        SCMP_CMP64(x, y, (uint32_t)(z), (uint32_t)(q))
#define SCMP_CMP32(...) macro_dispatcher(SCMP_CMP32_, __VA_ARGS__)(__VA_ARGS__)

#define SCMP_A0_64(...)         SCMP_CMP64(0, __VA_ARGS__)
#define SCMP_A0_32(...)         SCMP_CMP32(0, __VA_ARGS__)

Untuk kasus uji ini:

        struct scmp_arg_cmp f[] = {
                SCMP_A0_64(SCMP_CMP_EQ, 1, 20),
                SCMP_A0_32(SCMP_CMP_EQ, 2, 3),
                SCMP_A0_32(SCMP_CMP_LT, 2),
        };

itu keluar dari gcc-7.4.0 -E dan clang-7 -E sebagai:

 struct scmp_arg_cmp f[] = {
  ((struct scmp_arg_cmp){0, SCMP_CMP_EQ, 1, 20}),
  ((struct scmp_arg_cmp){0, SCMP_CMP_EQ, (uint32_t)(2), (uint32_t)(3)}),
  ((struct scmp_arg_cmp){0, SCMP_CMP_LT, (uint32_t)(2)}),
 };

Di bawah asumsi bahwa SCMP_A[0-5]_43 membutuhkan setidaknya op untuk bekerja dan SCMP_CMP32 membutuhkan arg , dua baris dapat disimpan dengan membuat parameter tersebut posisional:

#define SCMP_CMP32_1(x, y, z)           SCMP_CMP64(x, y, (uint32_t)(z))
#define SCMP_CMP32_2(x, y, z, q)        SCMP_CMP64(x, y, (uint32_t)(z), (uint32_t)(q))
#define SCMP_CMP32(x, y,...)            macro_dispatcher(SCMP_CMP32_, __VA_ARGS__)(x, y, __VA_ARGS__)

#define SCMP_A0_32(x,...)       SCMP_CMP32(0, x, __VA_ARGS__)

Bagus @michaelweiser! Apakah Anda ingin menyusun PR sehingga kami dapat meninjau/mengomentari perubahan dengan lebih mudah? Jika tidak, tidak apa-apa, saya akan menggabungkannya dan memastikan Anda mendapatkan banyak pujian :)

Saya akan membuat PR proyek malam ini. Di atas https://github.com/pcmoore/misc-libseccomp/commit/b9ce39d776ed5a984c7e9e6db3b87463edce82a7 atau dari awal?
Bagaimana kami menghargai Blogger Roman untuk solusi kelebihan bebannya? Temukan apa yang tampaknya menjadi rumah blognya saat ini di https://kecher.net/overloading-macros/. Postingannya terlihat seperti sumber aslinya. Komentar dengan tautan ke pos di atas logika macro_dispatcher ?

Saya akan membuat PR proyek malam ini. Di atas pcmoore@b9ce39d atau dari awal?

Terima kasih banyak! Silakan dan mendasarkannya dari cabang master, saya tidak pernah menggabungkan barang-barang di pohon misc-libseccomp saya, dan tidak berencana untuk saat ini karena pendekatan Anda jauh lebih baik.

Bagaimana kami menghargai Blogger Roman untuk solusi kelebihan bebannya? Temukan apa yang tampaknya menjadi rumah blognya saat ini di https://kecher.net/overloading-macros/. Postingannya terlihat seperti sumber aslinya. Komentar dengan tautan ke pos di atas logika macro_dispatcher ?

Kami biasanya tidak memberikan kredit kepada orang secara langsung di sumbernya, kecuali ada beberapa persyaratan lisensi; Saya akan merekomendasikan menambahkan komentar di deskripsi tambalan yang mengkredit Roman dengan ide dasar dan memberikan tautan ke posting blognya. Saya tidak melihat ada lisensi atau batasan yang ditempatkan pada contoh-contohnya, jadi saya tidak percaya ada masalah dalam hal itu, dan berdasarkan contoh blognya saya percaya niatnya adalah untuk membagikan ide-ide ini dengan orang lain (seperti kami ) untuk membantu mereka memecahkan masalah mereka. Jika Anda memiliki alamat email untuk Roman, Anda selalu dapat mencoba mengiriminya beberapa email; jika kita tidak dapat menghubunginya karena alasan apa pun, saya pikir tidak apa-apa untuk melanjutkan.

Diselesaikan melalui 80a987d6f8d0152def07fa90ace6417d56eea741.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat