O que o argumento de linha de comando “proto” não documentado faz em auditdistd no FreeBSD?

2

Como você deve saber, há um daemon auditdistd(8) disponível em FreeBSD. Ele tem alguns argumentos de linha de comando documentados como -c , -d , etc. (veja mais aqui (link) ).

Eu estava tentando aprender como funciona quando me deparei com um código manipulando um argumento de linha de comando não documentado, proto :

  • Aparentemente, proto_exec é chamado quando você executa /usr/sbin/auditdistd proto foo bar baz e foo bar baz são passados para a função como seus argumentos.

    /*
     * We are executed from proto to create sandbox.
     */
    if (argc > 1 && strcmp(argv[1], "proto") == 0) {
            argc -= 2;
            argv += 2;
            if (proto_exec(argc, argv) == -1)
                    err(EX_USAGE, "Unable to execute proto");
    }
    

    (See /contrib/openbsm/bin/auditdistd/auditdistd.c:main() (link) for more details.)

  • Veja a função proto_exec :

    int
    proto_exec(int argc, char *argv[])
    {
            struct proto *proto;
            int error;
    
            if (argc == 0) {
                    errno = EINVAL;
                    return (-1);
            }
            TAILQ_FOREACH(proto, &protos, prt_next) {
                    if (strcmp(proto->prt_name, argv[0]) == 0)
                            break;
            }
            if (proto == NULL) {
                    errno = EINVAL;
                    return (-1);
            }
            if (proto->prt_exec == NULL) {
                    errno = EOPNOTSUPP;
                    return (-1);
            }
            error = proto->prt_exec(argc, argv);
            if (error != 0) {
                    errno = error;
                    return (-1);
            }
            /* NOTREACHED */
            return (0);
    }
    

    (See /contrib/openbsm/bin/auditdistd/proto.c:proto_exec() (link) for more details.)

    Honestamente, não consigo descobrir o que está acontecendo aqui.

  • A variável protos é inicializada assim:

    static TAILQ_HEAD(, proto) protos = TAILQ_HEAD_INITIALIZER(protos);
    

    (See /contrib/openbsm/bin/auditdistd/proto.c (link) for more details.)

  • Quando /usr/sbin/auditdistd proto foo é chamado, apenas diz:

    auditdistd: Unable to execute proto: Invalid argument

Alguém sabe o que é essa opção e como usá-la?

    
por Mateusz Piotrowski 13.09.2016 / 20:42

2 respostas

1

Auditdistd está usando o sandbox. Para garantir que nenhuma memória vaze de um pai para o processo filho, em vez de apenas fork (2), ele também executa o binário auditdistd. O argumento 'proto' é passado para permitir que o comando recém-executado saiba que está sendo um processo filho.

    
por 12.06.2017 / 09:39
1

Pelo que entendi, auditdistd usa __attribute__((constructor)) para inicializar certas estruturas (consulte Como exatamente __attribute__((constructor)) funciona? para mais detalhes).

Como resultado, protos é um TAILQ de tls , uds e tcp proto structures.

O mistério está resolvido agora - protos é feito daquelas proto estruturas inicializadas com o recurso __attribute__((constructor)) .

    
por 15.09.2016 / 19:02