Skip to content

Commit dc5caa2

Browse files
authored
Merge pull request #35 from datachainlab/audit-202503
Audit-202503 Signed-off-by: Jun Kimura <jun.kimura@datachain.jp>
2 parents 06c9a4a + 05d403d commit dc5caa2

File tree

6 files changed

+64
-7
lines changed

6 files changed

+64
-7
lines changed

contracts/ILCPClientErrors.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,16 @@ interface ILCPClientErrors {
5959
error LCPClientUpdateOperatorsPermissionless();
6060
error LCPClientUpdateOperatorsSignatureUnexpectedOperator(address actual, address expected);
6161

62+
error LCPClientBaseInvalidConstructorParams();
63+
6264
error LCPClientZKDCAPInvalidConstructorParams();
6365
error LCPClientZKDCAPOutputNotValid();
6466
error LCPClientZKDCAPUnrecognizedTCBStatus();
6567
error LCPClientZKDCAPCurrentTcbEvaluationDataNumberNotSet();
6668
error LCPClientZKDCAPInvalidNextTcbEvaluationDataNumberInfo();
6769
error LCPClientZKDCAPInvalidVerifierInfos();
6870
error LCPClientZKDCAPInvalidVerifierInfoLength();
69-
error LCPClientZKDCAPInvalidVerifierInfoZKVMType();
71+
error LCPClientZKDCAPInvalidVerifierInfoRisc0Header();
7072
error LCPClientZKDCAPUnsupportedZKVMType();
7173
error LCPClientZKDCAPRisc0ImageIdNotSet();
7274
error LCPClientZKDCAPUnexpectedIntelRootCAHash();

contracts/LCPClientBase.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,17 @@ abstract contract LCPClientBase is ILightClient, ILCPClientErrors {
5555
/// @dev clientId => client storage
5656
mapping(string => ClientStorage) internal clientStorages;
5757

58+
/// @dev Reserved storage space to allow for layout changes in the future
59+
uint256[50] private __gap;
60+
5861
// --------------------- Constructor ---------------------
5962

6063
/// @custom:oz-upgrades-unsafe-allow constructor
6164
/// @param ibcHandler_ the address of the IBC handler contract
6265
constructor(address ibcHandler_) {
66+
if (ibcHandler_ == address(0)) {
67+
revert LCPClientBaseInvalidConstructorParams();
68+
}
6369
ibcHandler = ibcHandler_;
6470
}
6571

contracts/LCPClientIASOwnableUpgradeable.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
88
/// @custom:oz-upgrades-unsafe-allow external-library-linking
99
contract LCPClientIASOwnableUpgradeable is LCPClientIASBase, UUPSUpgradeable, OwnableUpgradeable {
1010
/// @custom:oz-upgrades-unsafe-allow constructor
11-
constructor(address ibcHandler, bool developmentMode) LCPClientIASBase(ibcHandler, developmentMode) {}
11+
constructor(address ibcHandler, bool developmentMode) LCPClientIASBase(ibcHandler, developmentMode) {
12+
_disableInitializers();
13+
}
1214

1315
function initialize(bytes memory rootCACert) public initializer {
1416
initializeRootCACert(rootCACert);

contracts/LCPClientZKDCAPBase.sol

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ abstract contract LCPClientZKDCAPBase is LCPClientBase {
264264
// The format is as follows:
265265
// - First byte (0): zkVM type identifier.
266266
// - Remaining bytes (1–N): zkVM-specific data.
267+
// - N must be greater than or equal to 32.
267268
//
268269
// Currently, only RISC Zero zkVM (type=1) is supported, with the following format:
269270
//
@@ -273,12 +274,19 @@ abstract contract LCPClientZKDCAPBase is LCPClientBase {
273274
// | 1–31 | Reserved (set as zero) |
274275
// | 32–63 | Image ID |
275276
uint256 vlen = verifierInfo.length;
276-
if (vlen == 0) {
277+
if (vlen < 32) {
277278
revert LCPClientZKDCAPInvalidVerifierInfoLength();
278279
}
279-
// Currently, the client only supports RISC Zero zkVM
280-
if (uint8(verifierInfo[0]) != ZKVM_TYPE_RISC_ZERO) {
281-
revert LCPClientZKDCAPInvalidVerifierInfoZKVMType();
280+
// Currently, the client only supports RISC Zero zkVM.
281+
// Load the first 32 bytes of 'verifierInfo' into 'header'.
282+
// According to the format, the first byte should be 0x01 (RISC Zero type),
283+
// and the remaining 31 bytes must be zero (reserved field).
284+
bytes32 header;
285+
assembly {
286+
header := mload(add(verifierInfo, 32))
287+
}
288+
if (header != bytes32(bytes1(ZKVM_TYPE_RISC_ZERO))) {
289+
revert LCPClientZKDCAPInvalidVerifierInfoRisc0Header();
282290
}
283291
// risc0 verifier info should be 64 bytes
284292
if (vlen != 64) {

contracts/LCPClientZKDCAPOwnableUpgradeable.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ contract LCPClientZKDCAPOwnableUpgradeable is LCPClientZKDCAPBase, UUPSUpgradeab
1010
/// @custom:oz-upgrades-unsafe-allow constructor
1111
constructor(address ibcHandler_, bool developmentMode_, bytes memory intelRootCA, address riscZeroVerifier_)
1212
LCPClientZKDCAPBase(ibcHandler_, developmentMode_, intelRootCA, riscZeroVerifier_)
13-
{}
13+
{
14+
_disableInitializers();
15+
}
1416

1517
function initialize() public initializer {
1618
__UUPSUpgradeable_init();

test/LCPClientZKDCAPTest.t.sol

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,43 @@ contract LCPClientZKDCAPTest is BasicTest {
376376
lc.zkDCAPRegisterEnclaveKey(clientId, msgData);
377377
}
378378

379+
function testRegisterEnclaveKeyInvalidRisc0Header() public {
380+
string memory clientId = "lcp-zkdcap";
381+
TestLCPClientZKDCAPExtended lc = new TestLCPClientZKDCAPExtended(
382+
address(this), false, ZKDCAPTestHelper.dummyIntelRootCACert(), address(new NopRiscZeroVerifier())
383+
);
384+
{
385+
IbcLightclientsLcpV1ClientState.Data memory clientState = defaultClientState();
386+
clientState.zkdcap_verifier_infos[0][0] = 0x00;
387+
bytes memory clientStateBytes = LCPProtoMarshaler.marshal(clientState);
388+
bytes memory consensusStateBytes = LCPProtoMarshaler.marshal(defaultConsensusState());
389+
vm.expectRevert(
390+
abi.encodeWithSelector(ILCPClientErrors.LCPClientZKDCAPInvalidVerifierInfoRisc0Header.selector)
391+
);
392+
lc.initializeClient(clientId, clientStateBytes, consensusStateBytes);
393+
}
394+
{
395+
IbcLightclientsLcpV1ClientState.Data memory clientState = defaultClientState();
396+
clientState.zkdcap_verifier_infos[0][0] = 0x02;
397+
bytes memory clientStateBytes = LCPProtoMarshaler.marshal(clientState);
398+
bytes memory consensusStateBytes = LCPProtoMarshaler.marshal(defaultConsensusState());
399+
vm.expectRevert(
400+
abi.encodeWithSelector(ILCPClientErrors.LCPClientZKDCAPInvalidVerifierInfoRisc0Header.selector)
401+
);
402+
lc.initializeClient(clientId, clientStateBytes, consensusStateBytes);
403+
}
404+
{
405+
IbcLightclientsLcpV1ClientState.Data memory clientState = defaultClientState();
406+
clientState.zkdcap_verifier_infos[0][1] = 0x01;
407+
bytes memory clientStateBytes = LCPProtoMarshaler.marshal(clientState);
408+
bytes memory consensusStateBytes = LCPProtoMarshaler.marshal(defaultConsensusState());
409+
vm.expectRevert(
410+
abi.encodeWithSelector(ILCPClientErrors.LCPClientZKDCAPInvalidVerifierInfoRisc0Header.selector)
411+
);
412+
lc.initializeClient(clientId, clientStateBytes, consensusStateBytes);
413+
}
414+
}
415+
379416
function testRegisterEnclaveKeyEnclaveDebugMismatch() public {
380417
string memory clientId = "lcp-zkdcap";
381418
// developmentMode=false but output.enclaveDebugEnabled is set to true

0 commit comments

Comments
 (0)