Esiste un approccio praticabile per testare un negativo in una base di codice di sicurezza critica?

6

Dato un requisito come

if A and B and not C then D must happen within 10ms

Questo può essere chiaramente testato, anche se a costo di qualche sofferenza che dimostra il bit di 10 ms, ma cosa succede se il requisito fosse invece

if and only if A and B and not C then D..... 

Mi sembra che solo se probabilmente richiede un'esplorazione approfondita dello spazio degli stati dei programmi, e che è chiaramente irrealizzabile data una quantità ragionevolmente ampia di stato (e potrebbe essere il tipo di cosa che Turing aveva cose da dire su). Questo è molto il tipo di condizione che si applica a cose come gli airbag che sparano e altre cose che riguardano la riduzione del danno.

Il mio sospetto sulla difficoltà di testare queste cose è corretto, e quali sono le strategie per ridurre le dimensioni dello spazio dello stato che devono essere esplorate per ottenere la copertura di tale requisito?

    
posta Dan Mills 03.06.2018 - 21:19
fonte

2 risposte

5

Verificare che qualcosa non avvenga è generalmente molto difficile. Tuttavia, il test non è l'unica tecnica QA disponibile. Qui, la combinazione di un'architettura conveniente con analisi statiche e alcuni test può essere ottimale:

  • astratto sui registri di I / O in modo che vengano manipolati solo tramite macro, funzioni o variabili con alcuni nomi facilmente distinguibili.

  • trova tutti i posti che utilizzano i registri relativi agli airbag. Se possibile, spostali in un unico file sorgente.

  • Implementa un tipo di analisi statica per garantire che:

    (1) nessun codice accede ai registri senza passare attraverso il livello di astrazione

    (2) nessun codice tranne i file specifici utilizza i registri relativi agli airbag

    Potrebbe essere semplice come uno script di shell che esegue il grepping di tutti i file di origine per un pattern specifico e confronta l'elenco di file corrispondenti:

    #!/bin/sh
    for file in 'find src/ include/ \
        -type f \( -name '*.c' -o -name '*.h' \) \
        -exec grep -l 'REG_TRIGGER_AIRBAG' {} +'
    do
      case "$file" in
        include/registers.h) ;;  # ok
        src/airbags.c) ;;  # ok
        *)
          echo "unexpected file is accessing airbag registers: $file"
          exit 1
          ;;
      esac
    done
    
  • Quei file sorgente che usano i registri relativi agli airbag, esegui un test completo. Prendi in considerazione l'utilizzo di tecniche white-box per costruire una suite di test ad alta copertura. Questo può essere semplificato organizzando il codice in modo lineare ed esprimendo le precondizioni attraverso le clausole di guardia:

    /* called every 5ms */
    void trigger_airbag_if_necessary(bool A, bool B, bool C) {
      if (!A) return;
      if (!B) return;
      if (C) return;
      SET_REGISTER(REG_TRIGGER_AIRBAG, 1);
    }
    

    Se le condizioni sono lineari, è più facile costruire un modello mentale delle condizioni che portano all'evento innescato. Inoltre, abbiamo solo bisogno di 4 casi di test per una copertura completa di tale funzione. Le condizioni più complesse non si adattano a questo schema e i test potrebbero essere basati su un diagramma di flusso o su una tabella di verità.

Questa strategia di isolare il codice rilevante non è perfetta. È possibile sovvertire questi controlli. Ma questo dovrebbe proteggere dagli errori accidentali . Per esempio. se imposto i registri relativi all'airbag in una parte diversa del codice, l'analisi statica ti avviserà rapidamente del problema.

La prima impressione che dovremmo verificare lo stato completo del programma non è completamente sbagliata. Ma fortunatamente, possiamo modellare lo spazio degli stati in modo che gli eventi che attivano gli airbag debbano attraversare un'area specifica, e possiamo prestare particolare attenzione a quell'area.

    
risposta data 06.06.2018 - 22:15
fonte
1

It seems to me that the only if likely requires an exhaustive exploration of the programs state space,

Oppure puoi loggare e verificare che ogni volta che succede la cosa giusta accadeva 10ms fa.

Il test riguarda la lettura del codice. Certo, questa cosa è fondamentale per la sicurezza, ma se ti lasci motivare a scrivere test pazzeschi approfonditi nessuno può leggere, quindi non stai salvando nessuno.

Potrebbe anche essere utile usare un linguaggio che ti permetta di controllare facilmente cosa può cambiare D e che esplode ogni volta che corri alla fine di un array.

    
risposta data 04.06.2018 - 13:57
fonte

Leggi altre domande sui tag