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
| Impact | Details |
|---|---|
| Confidentiality | Scope: Confidentiality Unauthorized read access through incorrectly permissive bridge. |
| Integrity | Scope: Integrity Memory and peripheral modification by agents with insufficient privilege. |
| Access Control | Scope: Access Control Protection mechanisms bypassed through unsecured bridge path. |
| Availability | Scope: 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.
Related CWEs
- 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
- MITRE Corporation. "CWE-1317: Improper Access Control in Fabric Bridge." https://cwe.mitre.org/data/definitions/1317.html
- ARM. "AMBA AXI and ACE Protocol Specification"
- CAPEC-122: Privilege Abuse