Libseccomp: BOGUE : SCMP_CMP_GT/GE/LT/LE ne fonctionne pas comme prévu pour les arguments d'appel système négatifs

Créé le 18 janv. 2017  ·  20Commentaires  ·  Source: seccomp/libseccomp

Salut!

Je ne sais pas si le comportement actuel de SCMP_CMP_GT/GE/LT/LE fonctionne comme prévu ou s'il y a un bogue dans son implémentation. La page de manuel de seccomp_rule_add n'a que ceci à dire à propos de 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 )

La page de manuel ne spécifie pas le type de datum et contient des exemples pour divers types (implicites) (et un transtypage en scmp_datum_t).

Sur la base de la page de manuel, je m'attendais à ce que quelque chose comme ceci fonctionne pour toute valeur donnée au 3ème argument de setpriority (supposez la politique par défaut de SCMP_ACT_ALLOW pour cela):

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

Au lieu de cela, setpriority(PRIO_PROCESS, 0, -1) entraîne le blocage de l'appel système lorsque '-1' est évidemment inférieur à '0'. setpriority(PRIO_PROCESS, 0, 0) et setpriority(PRIO_PROCESS, 0, 1) fonctionnent comme prévu. Ce qui se passe, c'est que '-1' est converti en scmp_datum_t (uint64_t de secomp.h.in) ce qui le rend bien sûr positif, mais SCMP_CMP_GT et ses amis ne gèrent pas cette conversion. SCMP_CMP_EQ fonctionne très bien avec une donnée négative (en supposant que la donnée est toujours positive (je n'ai pas vérifié), mais la comparaison se fait entre scmp_datum_t converti).

Ce comportement a été confirmé avec 2.1.0+dfsg-1 (Ubuntu 14.04 LTS, noyau 3.13), 2.2.3-3ubuntu3 (Ubuntu 16.04 LTS, noyau 4.9), 2.3.1-2ubuntu2 (version de développement Ubuntu 17.04, noyau 4.9) et master d'il y a quelques instants (sur la version dev Ubuntu 17.04, noyau 4.9), le tout sur amd64.

AFAICT, il n'y a pas de tests pour SCMP_CMP_GT et SCMP_CMP_LE. Les quelques tests pour SCMP_CMP_LT ne semblent pas tenir compte des valeurs négatives et celui de SCMP_CMP_GE non plus (veuillez me corriger si je me trompe).

La question est alors : ce comportement est-il intentionnel ? Si c'est le cas, même si j'admets que l'on pourrait affirmer que la page de manuel est exacte car elles fonctionnent parfaitement correctement lorsque l'on comprend que scmp_datum_t est le type de données, cette situation n'est pas immédiatement claire et la page de manuel devrait probablement dire que les applications doivent prendre en compte ce. Sinon, cela semble être un bogue dans l'implémentation pour SCMP_CMP_GT/GE/LT/LE.

Voici un petit programme qui illustre ce problème avec SCMP_CMP_GT, bien que GE, LT et LE puissent tous être observés comme ayant le même comportement :

/*
 * 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

Tous les 20 commentaires

Merci pour le rapport de problème; c'en est une bonne.

Par hasard, avez-vous essayé d'écrire le reproducteur en utilisant les en-têtes/macros du répertoire samples/seccomp du noyau ?

J'avais l'impression que le code BPF du noyau traitait les valeurs immédiates comme signées ; ce n'est peut-être pas le cas, ou j'ai peut-être foiré quelque chose dans le code libseccomp.

FWIW, BPF lui-même utilise u32 pour ses arguments. libseccomp signe-t-il l'extension sur les arguments compatibles ? (Cela ne devrait probablement pas, mais alors les règles pour correspondre à "-1" doivent être différentes entre 32 bits et 64 bits...)

Le problème qui m'inquiète en ce moment est celui des comparaisons BPF GT/GE dans l'opérateur de saut, d'autant plus que je soupçonne que presque tout le monde a traité le BPF immédiat comme une valeur signée pour ces comparaisons.

@kees quelle est l'approche recommandée pour effectuer des comparaisons signées d'arguments d'appel système avec la machine seccomp-bpf du noyau ? J'espère que ce n'est pas quelque chose du genre "vérifier d'abord le bit élevé, puis effectuer la conversion de compliment à deux nécessaire avant de comparer les nombres négatifs". Bien que ennuyeux, nous pouvons toujours changer libseccomp pour générer le BPF nécessaire (bien que les filtres générés soient désormais beaucoup plus gros dans certains cas), mais je m'inquiète des applications qui créent leurs propres filtres BPF ; les chances qu'ils gèrent cela correctement ne sont probablement pas très bonnes.

Malheureusement, étant donné que les arguments de l'appel système sont "longs non signés" (voir syscall_get_arguments() et struct seccomp_data), il n'y a pas de cas courant sur la façon dont un appel système gère les conversions de signes. Certains appels système lors du franchissement de la barrière de compatibilité feront une extension de signe, d'autres (prctl) ne le feront pas. Y a-t-il beaucoup d'arguments d'appel système négatifs mais pas moins un ?

Pour en revenir aujourd'hui, et après avoir joué un peu plus avec les choses ce matin, je pense que ça va finir par une documentation/"attention !" problème car il n'y a pas de bonne solution, surtout lorsque nous parlons d'utilisateurs existants. Permettez-moi d'essayer de fournir un arrière-plan/une explication de libseccomp pour @kees du côté du noyau.

FWIW, BPF lui-même utilise u32 pour ses arguments. libseccomp signe-t-il l'extension sur les arguments compatibles ? (Cela ne devrait probablement pas, mais les règles pour correspondre à "-1" doivent être différentes entre 32[-bit et 64-bit...)

Les fonctions de règle de l'API libseccomp interprètent toutes les valeurs immédiates comme _uint64_t_, donc si vous ne faites pas attention à vos types/casting, vous risquez de rencontrer des problèmes. Exemple:

$ 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

... comme nous pouvons le voir, si vous utilisez un casting approprié, la valeur n'est pas étendue par signe. Cependant, je pense que ce n'est pas ce que font la plupart des gens. La bonne nouvelle est que j'imagine que le nombre d'appels système qui prennent des arguments négatifs est relativement faible, donc l'impact devrait être quelque peu limité.

À l'avenir, nous devons absolument mettre quelque chose dans la documentation à ce sujet et voir si nous pouvons faire quelque chose pour faciliter la vie des développeurs, peut-être implémenter des variantes 32 bits des macros _SCMP_A*_.

@pcmoore - merci pour la réponse détaillée et désolé de ne pas être revenu plus tôt. Non, je n'ai pas encore essayé d'écrire un reproducteur basé sur https://github.com/torvalds/linux/tree/master/samples/seccomp , mais d'après vos commentaires, il semble que je n'en ai pas besoin. Fait moi savoir si tu as besoin de quoique ce soit d'autre. Pour l'instant, je vais adopter l'approche « faire attention » et signaler si j'ai des problèmes, et j'attends avec impatience comment vous pourriez faciliter la tâche à l'avenir.

@jdstrand Je pense que nous sommes tous prêts pour le moment. Merci encore pour le rapport, je suis désolé de ne pas avoir de meilleure réponse pour vous, mais j'espère que nous aurons quelque chose à l'avenir.

En attendant, si vous rencontrez des problèmes une fois avec une valeur de cast correctement saisie, n'hésitez pas à mettre à jour ce problème.

La bonne nouvelle est que j'imagine que le nombre d'appels système qui prennent des arguments négatifs est relativement faible, donc l'impact devrait être quelque peu limité.

Je viens de rencontrer ce problème en vérifiant (entre autres) si le paramètre fd d'openat() est égal à la valeur spéciale AT_FDCWD qui est -100. Cela a conduit à :

  # 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);

Où il devrait être :

  # 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);

Étant donné que la glibc 2.26+ semble utiliser exclusivement l'appel système openat avec AT_FDCWD pour implémenter open(), cela pourrait faire trébucher beaucoup de gens. L'application d'un cast à uint32_t comme suggéré ci-dessus a résolu le problème pour moi :

        // 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) }},

Un SCMP_A0_U32 explicite serait certainement bien d'avoir.

@drakenclimber @jdstrand @michaelweiser que https://github.com/pcmoore/misc-libseccomp/commit/b9ce39d776ed5a984c7e9e6db3b87463edce82a7 comme solution à ce problème ?

@pcmoore : Merci de continuer à étudier ça ! Je viens de lui donner un tourbillon et ça a l'air vraiment sympa dans le code:

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) }},

Malheureusement, il semble que la fonction d'assistance ne convient pas comme initialiseur de structure :

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),
     ^~~~~~~~~~

Merci pour la critique @michaelweiser , malheureusement, je ne pensais pas que les gens utilisaient ces macros comme initialiseurs, mais c'est une utilisation valide et il y a sûrement quelques personnes qui l'utilisent de cette façon.

Je vais devoir y réfléchir un peu... avez-vous des idées sur la façon de résoudre ce problème de manière élégante ?

Aucune idée, désolé, j'avais déjà les yeux ouverts avec des allumettes. :)

En le regardant maintenant, je pense voir le problème : en raison des listes d'arguments variables, vous ne pouvez pas injecter les transtypages nécessaires, n'est-ce pas ?

scmp_arg_cmp pourrait-il contenir une union donnant différentes vues sur les données avec la largeur, l'alignement (et peut-être même l'ordre des octets) corrects (ce qui IMO est en conflit avec "élégant") : ? S'il est purement interne à libseccomp et n'a pas besoin d'être compatible avec une interface de noyau, pourrait-il porter un indicateur de type de données en tant que champ séparé et laisser les fonctions utilisateur le trier ? Et cela pourrait-il même être initialisé à l'aide de varargs?

Sinon, au lieu de marquer l'opération dans son ensemble sur 32/64 bits, les opérandes pourraient-ils être annotés, enveloppant un casting et en recommandant sévèrement à l'utilisateur (comme vous le faites) de toujours utiliser ces annotations sous peine de rencontrer des problèmes difficiles à déboguer ?

{ 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)) }},

ou alors

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

Je ne suis pas assez d'un crack de préprocesseur pour proposer beaucoup plus, désolé.

@pcmoore , les changements me semblent bons. Je ne suis pas un expert des préprocesseurs, mais je vais examiner le problème mentionné ci-dessus par @michaelweiser

En le regardant maintenant, je pense voir le problème : en raison des listes d'arguments variables, vous ne pouvez pas injecter les transtypages nécessaires, n'est-ce pas ?

Ouais, c'est à peu près ça. Il y a peut-être un moyen non terrible de contourner cela, mais je n'en ai pas encore trouvé.

scmp_arg_cmp pourrait-il contenir une union donnant différentes vues sur les données avec la largeur, l'alignement (et peut-être même l'ordre des octets) corrects (ce qui IMO est en conflit avec "élégant") : ? S'il est purement interne à libseccomp et n'a pas besoin d'être compatible avec une interface de noyau, pourrait-il porter un indicateur de type de données en tant que champ séparé et laisser les fonctions utilisateur le trier ? Et cela pourrait-il même être initialisé à l'aide de varargs?

Nous avons un problème en ce que la structure scmp_arg_cmp fait partie de l'API libseccomp, donc à moins que nous ne voulions modifier la version majeure de libseccomp, nous ne pouvons pas vraiment changer la taille de la structure ou l'offset de l'un des champs membres ; cela briserait l'interface binaire existante avec les applications existantes. La conversion des champs de données 64 bits en une union contenant une valeur 64 bits ou 32 bits devrait être acceptable en soi, mais vous devrez également ajouter des informations supplémentaires à la structure scmp_arg_cmp pour indiquer quel membre de l'union utiliser ; c'est ce drapeau supplémentaire qui pourrait être problématique.

Il pourrait être possible de voler certains bits des champs "arg" ou "op", les deux sont des valeurs de 32 bits et n'utilisent qu'une fraction de cet espace. Cependant, je considère que c'est une option plutôt extrême et j'aimerais éviter cela si possible.

Sinon, au lieu de marquer l'opération dans son ensemble sur 32/64 bits, les opérandes pourraient-ils être annotés, enveloppant un casting et en recommandant sévèrement à l'utilisateur (comme vous le faites) de toujours utiliser ces annotations sous peine de rencontrer des problèmes difficiles à déboguer ?

Je ne comprends pas très bien ce que nous gagnerions à envelopper les opérandes avec une macro, pouvez-vous développer un peu plus? Nous pourrions fournir une macro pour envelopper les valeurs de référence, mais ce n'est pas vraiment différent de simplement demander aux appelants de fournir le casting approprié.

@pcmoore , les changements me semblent bons. Je ne suis pas un expert des préprocesseurs, mais je vais examiner le problème mentionné ci-dessus par @michaelweiser

Grand merci. Espérons qu'entre nous trois, nous pourrons trouver quelque chose d'utile ici.

@pcmoore : En regardant http://efesx.com/2010/07/17/variadic-macro-to-count-number-of-arguments/ et http://efesx.com/2010/08/31/overloading- macros/ j'obtiens ce qui suit :

#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__)

Pour ce cas de test :

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

il sort de gcc-7.4.0 -E et clang-7 -E comme :

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

En supposant que SCMP_A[0-5]_43 besoin d'au moins op pour fonctionner et que SCMP_CMP32 nécessite arg , deux lignes peuvent être enregistrées en rendant ces paramètres positionnels :

#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__)

Bravo @michaelweiser ! Vouliez-vous mettre en place un PR afin que nous puissions examiner/commenter les changements un peu plus facilement ? Sinon, c'est très bien, je vais en préparer un et m'assurer que vous obtenez beaucoup de crédit :)

Je ferai le projet de relations publiques de ce soir. En plus de https://github.com/pcmoore/misc-libseccomp/commit/b9ce39d776ed5a984c7e9e6db3b87463edce82a7 ou à partir de zéro ?
Comment créditer le Blogger Roman pour sa solution de surcharge ? Trouvé ce qui semble être la maison actuelle de son blog à https://kecher.net/overloading-macros/. Son message ressemble tout à fait à la source originale. Commentaire avec lien vers la publication au-dessus de la logique macro_dispatcher ?

Je ferai le projet de relations publiques de ce soir. En plus de pcmoore@b9ce39d ou à partir de zéro ?

Super merci! Allez-y et basez-le sur la branche master, je n'ai jamais fusionné les éléments dans mon arbre misc-libseccomp, et je ne prévois pas de le faire à ce stade car votre approche est bien meilleure.

Comment créditer le Blogger Roman pour sa solution de surcharge ? Trouvé ce qui semble être la maison actuelle de son blog à https://kecher.net/overloading-macros/. Son message ressemble tout à fait à la source originale. Commentaire avec lien vers la publication au-dessus de la logique macro_dispatcher ?

Nous ne créditons généralement pas les personnes directement dans la source, à moins qu'il n'y ait une exigence de licence ; Je recommanderais d'ajouter un commentaire dans la description du patch attribuant à Roman l'idée de base et fournissant un lien vers son article de blog. Je ne vois aucune licence ou restriction imposée à ses exemples, donc je ne pense pas qu'il y ait de problèmes à cet égard, et sur la base d'un échantillon de son blog, je pense que son intention est de partager ces idées avec d'autres (comme nous ) pour les aider à résoudre leurs problèmes. Si vous avez une adresse e-mail pour Roman, vous pouvez toujours essayer de lui envoyer un e-mail ; si nous ne pouvons pas le joindre pour une raison quelconque, je pense que c'est correct de continuer.

Résolu via 80a987d6f8d0152def07fa90ace6417d56eea741.

Cette page vous a été utile?
0 / 5 - 0 notes