Informazioni sull'ambito dell'errore di hyperthreading Intel KBL095

5

Recentemente, molte schede madri che supportano skylake o kabylake, hanno ricevuto un aggiornamento uefi descritto come aggiornamento per la sicurezza del microcodice cpu per un errore specifico di Intel, descritto da Intel come:

Short Loops Which Use AH/BH/CH/DH Registers May Cause Unpredictable System Behavior.

Under complex micro-architectural conditions, short loops of less than 64 instructions that use AH, BH, CH or DH registers as well as their corresponding wider register (e.g. RAX, EAX or AX for AH) may cause unpredictable system behavior. This can only happen when both logical processors on the same physical processor are active.

Intel emette errate frequenti della cpu che possono causare denial of service, ma in questo caso, il produttore non ha creato un aggiornamento uefi specifico per ognuna di esse.
Certo, ho provato il seguente codice su diversi core logici che non bloccano nulla (non capisco se tutti e 8 i registri devono essere coinvolti per far scattare il bug o solo uno di essi è sufficiente) :

48 ba ff 00 00 00 04    movabs $0x4000000ff,%rdx
00 00 00
.L5:
48 89 d0                movq    %rdx,%rax
48 2d fe 00 00 00       subq    $0xfe,%rax
08 f4                   orb     %dh,%ah
48 89 c3                movq    %rax,%rbx
48 81 eb fe 00 00 00    subq    $0xfe,%rbx
08 e7                   orb     %ah,%bh
48 89 d9                movq    %rbx,%rcx
48 81 e9 fe 00 00 00    subb    $0xfe,%rcx
08 fd                   orb     %bh,%ch
48 89 ca                movq    %rcx,%rdx
48 81 ea fe 00 00 00    subq    $0xfe,%rdx
08 ee                   orb     %ch,%dh
48 85 cb                test   %rcx,%rbx
75 cc                   jne    .L5
movq    %rcx, %rdx
movq    %rbx, %rax
movq    %rax, %rsi
leaq    .LC0(%rip), %rdi
movl    $0, %eax
call    printf@PLT

Quindi unpredictable system behavior implica l'esecuzione di codice remoto (ad esempio perché tali loop propagano la modifica del registro all'altro thread in esecuzione sullo stesso core) ?

Inoltre, che tipo di loop può attivare il bug? La semplice modifica di alcuni dei registri coinvolti in meno di 64 istruzioni attiva l'errore? I loop devono essere diversi (voglio dire che i thread non dovrebbero usare lo stesso codice) ?
Almeno può essere possibile avere un codice Ocaml di esempio che può attivare il bug ?
Come sapere se un microcode vulnerabile viene utilizzato durante l'esecuzione di qemu-kvm? (qemu -cpu host nasconde il numero di revisione del microcode)

    
posta user2284570 08.10.2017 - 20:22
fonte

3 risposte

2

Il bug tracker ocaml ha ancora il bug report originale: link

Usando la stessa versione di ocaml (4.03) e usando i passaggi da riprodurre, vale a dire: while ocamlfind opt -c -g -bin-annot -ccopt -g -ccopt -O2 -ccopt -Wextra -ccopt '-Wstrict-overflow=5' -thread -w +a-4-40..42-44-45-48-58 -w -27-32 -package extprot test.ml -o test.cmx; do echo "ok"; done si afferma che può essere riprodotto entro ~ 30 m su una macchina senza patch.

Non sono riuscito a trovare alcuna informazione Intel interna riguardante l'errata. Presumo che sia tenuto segreto a causa della natura sensibile del problema.

Il post debian ML ( link ) ha più dettagli sul problema stesso e i tipi di processori interessati. Questo potrebbe essere rilevante per la tua ricerca.

    
risposta data 31.10.2017 - 06:05
fonte
1

Hai chiesto un sacco di cose a cui è stata data una risposta molto esplicita nel rapporto Debian e anche nella documentazione Intel ... Comunque, entrambi i thread hardware devono avere un ciclo stretto (che si adatti alle condizioni per attivare il rilevatore di flusso in loop in entrambi i thread allo stesso tempo), che toccano quei registri e che colpiscono altri dettagli del microprocessore interno sconosciuto, affinché l'errata venga attivata.

Una delle persone OCAML ha segnalato pubblicamente un singolo caso di corruzione della tabella di pagina, quindi sembra , da questa singola prova, che non dovremmo escludere che l'errata possa causare un danno che sfugge elaborare il contesto e causare comportamenti imprevedibili su un processo non correlato.

Ma sarebbe necessario fare test statisticamente rilevanti per saperlo con certezza.

L'attivazione del bug è difficile, ma il garbage collector di OCAML riesce a farlo in modo relativamente semplice (non è "on demand"). Cerca la copertura Hacker News per i dettagli, in pratica è più probabile che il rilevatore del flusso di loop (un ottimizzazione della gestione energetica) inneschi l'errata e che che esegua su entrambi i thread nel modo in cui è necessario perché l'errata da attivare di proposito non è banale. Nessuno ha pubblicato ancora nulla relativo a questo.

Il garbage collector di OCAML riesce a farlo abbastanza spesso, ed è l'unico riproduttore conosciuto. Alcune ricerche di sicurezza molto buone sono state segnalate come interessate, ma finora non è emerso nulla.

Nel frattempo, applica la patch al microcodice. Non possiamo essere certi che al momento non sia possibile la sicurezza sfruttabile su richiesta, ma anche se fossimo sicuri che non fosse sfruttabile per l'escalation dei privilegi, sarebbe comunque una tasca di cattiveria imprevedibile.

Per quanto riguarda le distro Linux, anche i più conservatori hanno già rilasciato pacchetti aggiornati poiché ci sono stati test sufficienti e non sono emersi problemi reali con questo ciclo di aggiornamenti [che non erano presenti negli aggiornamenti precedenti, comunque].

Come per i fornitori di schede madri, ormai dovresti sapere quali evitare in futuro.

    
risposta data 10.10.2017 - 15:40
fonte
0

da questo articolo un caso di commutazione sembrava causare il problema:

# The main loop condition
.L108:
    .loc 3 542 0
    testq   %r13, %r13
    jg  .L111
[...]

la condizione if che verifica il caricamento del prossimo chunk di memoria sul bordo del blocco

.L103:
    .loc 3 567 0
    movq    chunk(%rip), %rax
    movq    -8(%rax), %rax
    movq    %rax, chunk(%rip)
    .loc 3 568 0

la condizione di uscita. Questo codice viene preso una sola volta all'uscita e gcc inserisce un collegamento diretto alla funzione exit

    testq   %rax, %rax
    je  .L115
    .loc 3 575 0
    movq    %rax, caml_gc_sweep_hp(%rip)
    .loc 3 576 0
    addq    -16(%rax), %rax
    movq    %rax, limit(%rip)
.L111:
    .loc 3 543 0

Il ramo if. Questo è probabilmente l'effetto diretto della propagazione dell'intervallo di valori, che salta direttamente all'interno del ciclo invece di eseguire nuovamente il controllo

 movq    caml_gc_sweep_hp(%rip), %rbx
    cmpq    limit(%rip), %rbx
    jnb .L103
    .loc 3 545 0

La parola di intestazione di decodifica del punto di passaggio dello switch

movq    (%rbx), %rax
.loc 3 546 0
movq    %rax, %rdx
shrq    $10, %rdx
movq    %rdx, %r13
notq    %r13
addq    %r12, %r13
movq    %r13, %r12
.loc 3 547 0
leaq    8(%rbx,%rdx,8), %rdx
movq    %rdx, caml_gc_sweep_hp(%rip)
.loc 3 548 0

il ramo che gestisce il colore bianco, ovvero i blocchi non raggiungibili (esclusi da questo campione)

movq    %rax, %rdx
andl    $768, %edx
je  .L105

il ramo che gestisce il colore blu (lasciato fuori da questo campione)

cmpq    $512, %rdx
je  .L106

Il ramo predefinito aka i blocchi raggiungibili

.loc 3 562 0

aggiornamento della parte colorata dell'intestazione

andb    $252, %ah
movq    %rax, (%rbx)
.loc 3 563 0
jmp .L108 # jumping back to the loop condition to scan next block

in particolare questo blocco di codice ha causato il problema:

.L111:
   .loc 3 562 0
   movq    -16(%rbp), %rax
   andb    $252, %ah
   movq    %rax, %rdx
   movq    -8(%rbp), %rax
   movq    %rdx, (%rax)
   .loc 3 563 0
   nop
   jmp     .L102
    
risposta data 04.11.2017 - 07:28
fonte

Leggi altre domande sui tag