Improper Access Control in Fabric Bridge

Description

Improper Access Control in Fabric Bridge occurs when the product uses a fabric bridge for transactions between two Intellectual Property (IP) blocks, but the bridge does not properly perform the expected privilege, identity, or other access control checks between those IP blocks. Fabric bridges connect different IP blocks and bus protocols within System-on-Chip (SoC) designs, and they must maintain access-control privileges during transaction routing. Bridges lacking security features or failing to verify master privilege levels and hardware identities create vulnerabilities that allow unauthorized access to protected resources.

Risk

Improper access control in fabric bridges has severe implications. Privilege escalation enabled. Unauthorized memory access possible. Protection mechanisms bypassed. Denial of service attacks. Arbitrary reads and writes to protected peripherals. BMC and management processor compromise. Low-privilege agents accessing high-security resources. Complete SoC security breakdown. Medium likelihood when bridges are implemented without security considerations.

Solution

Incorporate access-control checks in bridge designs for both upstream and downstream transactions during architecture and design phase. Enforce access-control validation in bridge code for bidirectional transactions during implementation phase. Verify that privilege levels, security attributes, and hardware identities are properly validated at bridge boundaries. Use formal verification to prove access control cannot be bypassed.

Common Consequences

ImpactDetails
ConfidentialityScope: Confidentiality

Unauthorized read access through incorrectly permissive bridge.
IntegrityScope: Integrity

Memory and peripheral modification by agents with insufficient privilege.
Access ControlScope: Access Control

Protection mechanisms bypassed through unsecured bridge path.
AvailabilityScope: Availability

Denial of service through bridge access to critical resources.

Example Code

Vulnerable Code

// Vulnerable: Fabric bridge without access control

module vulnerable_fabric_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // Master side (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,      // Protection signals
    input  wire [3:0]  master_id,        // Master ID
    output reg  [31:0] master_rdata,
    output reg         master_ready,

    // Slave side (target)
    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
);

    // VULNERABLE: Bridge passes transactions without checking privileges

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            slave_write <= 1'b0;
            slave_read <= 1'b0;
        end else begin
            // VULNERABLE: No privilege check - just forward everything
            slave_addr <= master_addr;
            slave_wdata <= master_wdata;
            slave_write <= master_write;
            slave_read <= master_read;

            // VULNERABLE: Protection signals passed without validation
            slave_prot <= master_prot;
            slave_id <= master_id;

            // Forward response
            master_rdata <= slave_rdata;
            master_ready <= slave_ready;
        end
    end

    // Attack:
    // 1. Low-privilege master initiates transaction
    // 2. Bridge forwards to protected slave without checking
    // 3. Slave may trust bridge-forwarded signals
    // 4. Unauthorized access to protected resources

endmodule

// Vulnerable: iLPC2AHB bridge example (based on CVE-2019-6260)
module vulnerable_ilpc2ahb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // iLPC interface (from untrusted host)
    input  wire [31:0] ilpc_addr,
    input  wire [31:0] ilpc_data,
    input  wire        ilpc_read,
    input  wire        ilpc_write,

    // AHB interface (to BMC peripherals)
    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
);

    // VULNERABLE: No validation of iLPC requests
    // Host can access any BMC peripheral through this bridge

    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
                // VULNERABLE: Direct pass-through without access control
                ahb_haddr <= ilpc_addr;
                ahb_hwdata <= ilpc_data;
                ahb_hwrite <= ilpc_write;
                ahb_htrans <= 2'b10;  // NONSEQ

                // VULNERABLE: No address filtering
                // VULNERABLE: No privilege checking
                // VULNERABLE: Host can read/write any peripheral
            end else begin
                ahb_htrans <= 2'b00;
            end
        end
    end

    // CVE-2019-6260: This pattern allowed arbitrary reads/writes
    // from host to all BMC peripherals including:
    // - Flash controller
    // - Crypto engines
    // - Management interfaces

endmodule

Fixed Code

// Fixed: Fabric bridge with proper access control

module secure_fabric_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // Master side (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 side (target)
    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,

    // Access control configuration
    input  wire [15:0] allowed_masters,       // Bitmap of allowed master IDs
    input  wire [31:0] allowed_addr_base,
    input  wire [31:0] allowed_addr_mask,
    input  wire [2:0]  min_privilege_level
);

    // FIXED: Validate master identity
    wire master_allowed = allowed_masters[master_id];

    // FIXED: Validate address range
    wire addr_in_range = ((master_addr & ~allowed_addr_mask) ==
                          (allowed_addr_base & ~allowed_addr_mask));

    // FIXED: Validate privilege level
    // master_prot[0] = privileged/user
    // master_prot[1] = secure/non-secure
    wire privilege_sufficient = (master_prot >= min_privilege_level);

    // FIXED: Combined access decision
    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
                // FIXED: Check access control before forwarding
                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
                    // FIXED: Block unauthorized access
                    slave_write <= 1'b0;
                    slave_read <= 1'b0;
                    master_error <= 1'b1;
                    master_ready <= 1'b1;  // Complete with error
                    master_rdata <= 32'hDEAD_BEEF;  // Error pattern
                end
            end else begin
                slave_write <= 1'b0;
                slave_read <= 1'b0;
            end
        end
    end

endmodule

// Fixed: Secure iLPC2AHB bridge with access control
module secure_ilpc2ahb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // iLPC interface (from potentially untrusted 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 interface (to BMC peripherals)
    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
);

    // FIXED: Define allowed address ranges for host access
    // Only expose specific, non-sensitive peripherals

    // Allowed ranges (example - customize per system)
    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

    // FIXED: Block access to sensitive areas
    localparam SENSITIVE_START = 32'h0800_0000;  // Flash controller
    localparam SENSITIVE_END   = 32'h0FFF_FFFF;

    // FIXED: Address validation
    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
                // FIXED: Validate access before forwarding
                if (access_allowed) begin
                    ahb_haddr <= ilpc_addr;
                    ahb_hwdata <= ilpc_data;
                    ahb_hwrite <= ilpc_write;
                    ahb_htrans <= 2'b10;

                    // FIXED: Mark as non-privileged, non-secure
                    ahb_hprot <= 4'b0000;  // User, non-secure
                end else begin
                    // FIXED: Block and signal error
                    ahb_htrans <= 2'b00;
                    ilpc_error <= 1'b1;
                end
            end else begin
                ahb_htrans <= 2'b00;
            end
        end
    end

endmodule

// Fixed: Bidirectional bridge with comprehensive access control
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
);

    // FIXED: Access control lookup table
    // Row = source ID, Column = destination range
    reg [7:0] access_matrix [0:15];  // 16 masters, 8 destination regions

    // FIXED: Check access control for A->B direction
    function automatic check_access;
        input [3:0] master_id;
        input [2:0] master_prot;
        input [31:0] target_addr;
        reg [2:0] region;
        begin
            // Map address to region (simplified)
            region = target_addr[30:28];

            // Check access matrix
            if (access_matrix[master_id][region]) begin
                check_access = 1'b1;
            end else begin
                check_access = 1'b0;
            end
        end
    endfunction

    // FIXED: Apply access control in both directions
    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 transactions
            if (porta_read || porta_write) begin
                if (check_access(porta_id, porta_prot, porta_addr)) begin
                    // Forward transaction
                    porta_error <= 1'b0;
                end else begin
                    porta_error <= 1'b1;
                end
            end

            // B -> A transactions
            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 Examples

  • CVE-2019-6260: An iLPC2AHB bridge in Aspeed AST2400/AST2500 BMC devices failed to validate privilege levels, allowing arbitrary reads and writes from all privilege tiers to protected peripherals.
  • CVE-2020-8705: Fabric bridge in Intel processors incorrectly handled access control checks.

  • CWE-284: Improper Access Control (parent)
  • CWE-1203: Peripherals, On-chip Fabric, and Interface/IO Problems (category)
  • CWE-1311: Improper Translation of Security Attributes by Fabric Bridge (related)
  • CWE-122: Heap-based Buffer Overflow (CAPEC-122 Privilege Abuse)

References

  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