Unsachgemäße Zugriffskontrolle in Fabric Bridge

Beschreibung

Unsachgemäße Zugriffskontrolle in einer Fabric Bridge tritt auf, wenn das Produkt eine Fabric Bridge für Transaktionen zwischen zwei IP-Blöcken verwendet, die Bridge aber die erwarteten Berechtigungs-, Identitäts- oder sonstigen Zugriffskontrollprüfungen zwischen diesen IP-Blöcken nicht ordnungsgemäß durchführt. Fabric Bridges verbinden verschiedene IP-Blöcke und Bus-Protokolle innerhalb von System-on-Chip (SoC)-Designs und müssen Zugriffskontrollberechtigungen während der Transaktionsweiterleitung aufrechterhalten. Bridges ohne Sicherheitsfunktionen oder ohne Verifizierung von Master-Berechtigungsstufen und Hardware-Identitäten erzeugen Schwachstellen, die unbefugten Zugriff auf geschützte Ressourcen ermöglichen.

Risiko

Unsachgemäße Zugriffskontrolle in Fabric Bridges hat schwerwiegende Auswirkungen. Privilegienerweiterung ermöglicht. Unbefugter Speicherzugriff möglich. Schutzmechanismen umgangen. Denial-of-Service-Angriffe. Beliebige Lese- und Schreibzugriffe auf geschützte Peripheriegeräte. BMC- und Management-Prozessor-Kompromittierung. Niedrigprivilegierte Agenten greifen auf hochsichere Ressourcen zu. Vollständiger SoC-Sicherheitszusammenbruch. Mittlere Wahrscheinlichkeit wenn Bridges ohne Sicherheitsüberlegungen implementiert werden.

Lösung

Integrieren Sie Zugriffskontrollprüfungen in Bridge-Designs für sowohl Upstream- als auch Downstream-Transaktionen während der Architektur- und Entwurfsphase. Erzwingen Sie Zugriffskontrollvalidierung im Bridge-Code für bidirektionale Transaktionen während der Implementierungsphase. Verifizieren Sie, dass Berechtigungsstufen, Sicherheitsattribute und Hardware-Identitäten an Bridge-Grenzen ordnungsgemäß validiert werden. Verwenden Sie formale Verifikation, um zu beweisen, dass Zugriffskontrolle nicht umgangen werden kann.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Unbefugter Lesezugriff durch unzureichend permissive Bridge.
IntegritätBereich: Integrität

Speicher- und Peripherieänderung durch Agenten mit unzureichender Berechtigung.
ZugriffskontrolleBereich: Zugriffskontrolle

Schutzmechanismen durch ungesicherten Bridge-Pfad umgangen.
VerfügbarkeitBereich: Verfügbarkeit

Denial of Service durch Bridge-Zugriff auf kritische Ressourcen.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: Fabric Bridge ohne Zugriffskontrolle

module vulnerable_fabric_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // Master-Seite (Initiator)
    input  wire [31:0] master_addr,
    input  wire [31:0] master_wdata,
    input  wire        master_write,
    input  wire        master_read,
    input  wire [2:0]  master_prot,      // Schutz-Signale
    input  wire [3:0]  master_id,        // Master-ID
    output reg  [31:0] master_rdata,
    output reg         master_ready,

    // Slave-Seite (Ziel)
    output reg  [31:0] slave_addr,
    output reg  [31:0] slave_wdata,
    output reg         slave_write,
    output reg         slave_read,
    output reg  [2:0]  slave_prot,
    output reg  [3:0]  slave_id,
    input  wire [31:0] slave_rdata,
    input  wire        slave_ready
);

    // VERWUNDBAR: Bridge leitet Transaktionen ohne Berechtigungsprüfung weiter

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            slave_write <= 1'b0;
            slave_read <= 1'b0;
        end else begin
            // VERWUNDBAR: Keine Berechtigungsprüfung - einfach alles weiterleiten
            slave_addr <= master_addr;
            slave_wdata <= master_wdata;
            slave_write <= master_write;
            slave_read <= master_read;

            // VERWUNDBAR: Schutz-Signale ohne Validierung weitergeleitet
            slave_prot <= master_prot;
            slave_id <= master_id;

            // Antwort weiterleiten
            master_rdata <= slave_rdata;
            master_ready <= slave_ready;
        end
    end

    // Angriff:
    // 1. Niedrigprivilegierter Master initiiert Transaktion
    // 2. Bridge leitet an geschützten Slave weiter ohne zu prüfen
    // 3. Slave vertraut möglicherweise den von der Bridge weitergeleiteten Signalen
    // 4. Unbefugter Zugriff auf geschützte Ressourcen

endmodule

// VERWUNDBAR: iLPC2AHB-Bridge-Beispiel (basierend auf CVE-2019-6260)
module vulnerable_ilpc2ahb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // iLPC-Schnittstelle (vom nicht vertrauenswürdigen Host)
    input  wire [31:0] ilpc_addr,
    input  wire [31:0] ilpc_data,
    input  wire        ilpc_read,
    input  wire        ilpc_write,

    // AHB-Schnittstelle (zu BMC-Peripheriegeräten)
    output reg  [31:0] ahb_haddr,
    output reg  [31:0] ahb_hwdata,
    output reg         ahb_hwrite,
    output reg  [1:0]  ahb_htrans,
    input  wire [31:0] ahb_hrdata,
    input  wire        ahb_hready
);

    // VERWUNDBAR: Keine Validierung der iLPC-Anfragen
    // Host kann auf jedes BMC-Peripheriegerät über diese Bridge zugreifen

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            ahb_htrans <= 2'b00;  // IDLE
        end else begin
            if (ilpc_read || ilpc_write) begin
                // VERWUNDBAR: Direkte Durchleitung ohne Zugriffskontrolle
                ahb_haddr <= ilpc_addr;
                ahb_hwdata <= ilpc_data;
                ahb_hwrite <= ilpc_write;
                ahb_htrans <= 2'b10;  // NONSEQ

                // VERWUNDBAR: Keine Adressfilterung
                // VERWUNDBAR: Keine Berechtigungsprüfung
                // VERWUNDBAR: Host kann jedes Peripheriegerät lesen/schreiben
            end else begin
                ahb_htrans <= 2'b00;
            end
        end
    end

    // CVE-2019-6260: Dieses Muster erlaubte beliebige Lese-/Schreibzugriffe
    // vom Host auf alle BMC-Peripheriegeräte einschließlich:
    // - Flash-Controller
    // - Krypto-Engines
    // - Management-Schnittstellen

endmodule

Sichere Lösung

// SICHER: Fabric Bridge mit ordnungsgemäßer Zugriffskontrolle

module secure_fabric_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // Master-Seite (Initiator)
    input  wire [31:0] master_addr,
    input  wire [31:0] master_wdata,
    input  wire        master_write,
    input  wire        master_read,
    input  wire [2:0]  master_prot,
    input  wire [3:0]  master_id,
    output reg  [31:0] master_rdata,
    output reg         master_ready,
    output reg         master_error,

    // Slave-Seite (Ziel)
    output reg  [31:0] slave_addr,
    output reg  [31:0] slave_wdata,
    output reg         slave_write,
    output reg         slave_read,
    output reg  [2:0]  slave_prot,
    output reg  [3:0]  slave_id,
    input  wire [31:0] slave_rdata,
    input  wire        slave_ready,

    // Zugriffskontroll-Konfiguration
    input  wire [15:0] allowed_masters,       // Bitmap erlaubter Master-IDs
    input  wire [31:0] allowed_addr_base,
    input  wire [31:0] allowed_addr_mask,
    input  wire [2:0]  min_privilege_level
);

    // SICHER: Master-Identität validieren
    wire master_allowed = allowed_masters[master_id];

    // SICHER: Adressbereich validieren
    wire addr_in_range = ((master_addr & ~allowed_addr_mask) ==
                          (allowed_addr_base & ~allowed_addr_mask));

    // SICHER: Berechtigungsstufe validieren
    // master_prot[0] = privilegiert/benutzer
    // master_prot[1] = sicher/nicht-sicher
    wire privilege_sufficient = (master_prot >= min_privilege_level);

    // SICHER: Kombinierte Zugriffsentscheidung
    wire access_permitted = master_allowed && addr_in_range && privilege_sufficient;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            slave_write <= 1'b0;
            slave_read <= 1'b0;
            master_error <= 1'b0;
        end else begin
            master_error <= 1'b0;

            if (master_read || master_write) begin
                // SICHER: Zugriffskontrolle vor Weiterleitung prüfen
                if (access_permitted) begin
                    slave_addr <= master_addr;
                    slave_wdata <= master_wdata;
                    slave_write <= master_write;
                    slave_read <= master_read;
                    slave_prot <= master_prot;
                    slave_id <= master_id;

                    master_rdata <= slave_rdata;
                    master_ready <= slave_ready;
                end else begin
                    // SICHER: Unbefugten Zugriff blockieren
                    slave_write <= 1'b0;
                    slave_read <= 1'b0;
                    master_error <= 1'b1;
                    master_ready <= 1'b1;  // Mit Fehler abschließen
                    master_rdata <= 32'hDEAD_BEEF;  // Fehlermuster
                end
            end else begin
                slave_write <= 1'b0;
                slave_read <= 1'b0;
            end
        end
    end

endmodule

// SICHER: Sichere iLPC2AHB-Bridge mit Zugriffskontrolle
module secure_ilpc2ahb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // iLPC-Schnittstelle (von potenziell nicht vertrauenswürdigem Host)
    input  wire [31:0] ilpc_addr,
    input  wire [31:0] ilpc_data,
    input  wire        ilpc_read,
    input  wire        ilpc_write,
    output reg         ilpc_error,

    // AHB-Schnittstelle (zu BMC-Peripheriegeräten)
    output reg  [31:0] ahb_haddr,
    output reg  [31:0] ahb_hwdata,
    output reg         ahb_hwrite,
    output reg  [1:0]  ahb_htrans,
    output reg  [3:0]  ahb_hprot,
    input  wire [31:0] ahb_hrdata,
    input  wire        ahb_hready
);

    // SICHER: Erlaubte Adressbereiche für Host-Zugriff definieren
    // Nur spezifische, nicht-sensible Peripheriegeräte freigeben

    // Erlaubte Bereiche (Beispiel - systemspezifisch anpassen)
    localparam ALLOWED_RANGE1_BASE = 32'h1000_0000;
    localparam ALLOWED_RANGE1_SIZE = 32'h0000_1000;  // 4KB
    localparam ALLOWED_RANGE2_BASE = 32'h2000_0000;
    localparam ALLOWED_RANGE2_SIZE = 32'h0000_0100;  // 256B

    // SICHER: Zugriff auf sensible Bereiche blockieren
    localparam SENSITIVE_START = 32'h0800_0000;  // Flash-Controller
    localparam SENSITIVE_END   = 32'h0FFF_FFFF;

    // SICHER: Adressvalidierung
    wire in_range1 = (ilpc_addr >= ALLOWED_RANGE1_BASE) &&
                     (ilpc_addr < ALLOWED_RANGE1_BASE + ALLOWED_RANGE1_SIZE);
    wire in_range2 = (ilpc_addr >= ALLOWED_RANGE2_BASE) &&
                     (ilpc_addr < ALLOWED_RANGE2_BASE + ALLOWED_RANGE2_SIZE);
    wire in_sensitive = (ilpc_addr >= SENSITIVE_START) &&
                        (ilpc_addr <= SENSITIVE_END);

    wire access_allowed = (in_range1 || in_range2) && !in_sensitive;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            ahb_htrans <= 2'b00;
            ilpc_error <= 1'b0;
        end else begin
            ilpc_error <= 1'b0;

            if (ilpc_read || ilpc_write) begin
                // SICHER: Zugriff vor Weiterleitung validieren
                if (access_allowed) begin
                    ahb_haddr <= ilpc_addr;
                    ahb_hwdata <= ilpc_data;
                    ahb_hwrite <= ilpc_write;
                    ahb_htrans <= 2'b10;

                    // SICHER: Als nicht-privilegiert, nicht-sicher markieren
                    ahb_hprot <= 4'b0000;  // Benutzer, nicht-sicher
                end else begin
                    // SICHER: Blockieren und Fehler signalisieren
                    ahb_htrans <= 2'b00;
                    ilpc_error <= 1'b1;
                end
            end else begin
                ahb_htrans <= 2'b00;
            end
        end
    end

endmodule

// SICHER: Bidirektionale Bridge mit umfassender Zugriffskontrolle
module secure_bidirectional_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // Port A
    input  wire [31:0] porta_addr,
    input  wire [31:0] porta_wdata,
    input  wire        porta_write,
    input  wire        porta_read,
    input  wire [3:0]  porta_id,
    input  wire [2:0]  porta_prot,
    output reg  [31:0] porta_rdata,
    output reg         porta_ready,
    output reg         porta_error,

    // Port B
    input  wire [31:0] portb_addr,
    input  wire [31:0] portb_wdata,
    input  wire        portb_write,
    input  wire        portb_read,
    input  wire [3:0]  portb_id,
    input  wire [2:0]  portb_prot,
    output reg  [31:0] portb_rdata,
    output reg         portb_ready,
    output reg         portb_error
);

    // SICHER: Zugriffskontroll-Nachschlagetabelle
    // Zeile = Quell-ID, Spalte = Zielregion
    reg [7:0] access_matrix [0:15];  // 16 Master, 8 Zielregionen

    // SICHER: Zugriffskontrolle für A->B-Richtung prüfen
    function automatic check_access;
        input [3:0] master_id;
        input [2:0] master_prot;
        input [31:0] target_addr;
        reg [2:0] region;
        begin
            // Adresse auf Region abbilden (vereinfacht)
            region = target_addr[30:28];

            // Zugriffsmatrix prüfen
            if (access_matrix[master_id][region]) begin
                check_access = 1'b1;
            end else begin
                check_access = 1'b0;
            end
        end
    endfunction

    // SICHER: Zugriffskontrolle in beide Richtungen anwenden
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            porta_error <= 1'b0;
            portb_error <= 1'b0;
        end else begin
            // A -> B Transaktionen
            if (porta_read || porta_write) begin
                if (check_access(porta_id, porta_prot, porta_addr)) begin
                    // Transaktion weiterleiten
                    porta_error <= 1'b0;
                end else begin
                    porta_error <= 1'b1;
                end
            end

            // B -> A Transaktionen
            if (portb_read || portb_write) begin
                if (check_access(portb_id, portb_prot, portb_addr)) begin
                    portb_error <= 1'b0;
                end else begin
                    portb_error <= 1'b1;
                end
            end
        end
    end

endmodule

CVE-Beispiele

  • CVE-2019-6260: Eine iLPC2AHB-Bridge in Aspeed AST2400/AST2500-BMC-Geräten validierte Berechtigungsstufen nicht und ermöglichte beliebige Lese- und Schreibzugriffe von allen Berechtigungsstufen auf geschützte Peripheriegeräte.
  • CVE-2020-8705: Fabric Bridge in Intel-Prozessoren behandelte Zugriffskontrollprüfungen fehlerhaft.

Verwandte CWEs

  • CWE-284: Improper Access Control (Eltern)
  • CWE-1203: Peripherals, On-chip Fabric, and Interface/IO Problems (Kategorie)
  • CWE-1311: Improper Translation of Security Attributes by Fabric Bridge (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-1317: Improper Access Control in Fabric Bridge." https://cwe.mitre.org/data/definitions/1317.html
  2. ARM. "AMBA AXI and ACE Protocol Specification"
  3. CAPEC-122: Privilege Abuse