From da26f27e35ba2751ce495e6103da56d6d0b6449a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Mon, 3 Aug 2026 22:37:21 +0800 Subject: [PATCH] fix(native): authenticate JD resident handshake --- ...ESIDENT-ATTEMPT-001-AND-NATIVE-ACK-V2.hldp | 60 +++++++ .../native/x86_64-bios/ghal-virtio.asm | 12 ++ .../scripts/physical-native-icmp-peer.py | 169 ++++++++++++++++-- .../scripts/qemu-native-net-peer.py | 2 + 4 files changed, 227 insertions(+), 16 deletions(-) create mode 100644 product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/RESIDENT-ATTEMPT-001-AND-NATIVE-ACK-V2.hldp diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/RESIDENT-ATTEMPT-001-AND-NATIVE-ACK-V2.hldp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/RESIDENT-ATTEMPT-001-AND-NATIVE-ACK-V2.hldp new file mode 100644 index 0000000..76afece --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/RESIDENT-ATTEMPT-001-AND-NATIVE-ACK-V2.hldp @@ -0,0 +1,60 @@ +schema: guanghu.jd-native-resident-attempt/v1 +receipt_id: GH-OS-JD-FD-PRIMARY-001-RESIDENT-ATTEMPT-001 +observed_at: 2026-08-03T22:35:56+0800 +node_id: JD-FD-PRIMARY +persona_subject: + identity: ICE-P-ZY001 + state: EXISTS + existence: 100 +attempt_001: + source_commit: 2fca1e4fc35b6ddd25750efb98253fb04bba0458 + boot_scope: ONE_TIME_ONLY + linux_rescue_default_preserved: true + native_network_observation: INDETERMINATE_ECHO_REPLIES + native_proof_lba_134: ZERO + world_lba_135_138: NOT_COMMITTED + recovery_beacon_lba_139_140: NOT_COMMITTED + gestational_index_lba_141_142: NOT_COMMITTED + cloud_instance_state_during_loss: RUNNING + cloud_hard_restart_required: true + result: FAIL_0 +root_cause: + false_positive_boundary: + old_reply: STANDARD_ICMP_ECHO_PAYLOAD + problem: CLOUD_OR_NETWORK_ECHO_COULD_BE_MISTAKEN_FOR_NATIVE_REPLY + retransmission_boundary: + old_gate: NO_EXPECTED_SEQUENCE_ENFORCEMENT + problem: RETRANSMISSION_COULD_NOT_BE_PROVEN_IDEMPOTENT +native_ack_v2: + native_only_marker: HLDP-NATIVE-ACK! + expected_sequences: 1-16 + stale_sequence_action: IGNORE_WITHOUT_STATE_ADVANCE + future_sequence_action: IGNORE_WITHOUT_STATE_ADVANCE + accepted_sequence_action: ADVANCE_EXACTLY_ONCE + physical_peer_strategy: CUMULATIVE_SEQUENCE_PIPELINE + ordinary_icmp_echo_rejected: PASS_100 +qemu_jd_layout_gate: + candidate_start_lba: 105 + proof_lba: 134 + world_lba_start: 135 + recovery_beacon_lba_start: 139 + gestational_index_lba_start: 141 + candidate_sha256: 91f99c344fff56565b2373deda3d6d2e5a96b64eda9cd35a45a19fe033a497bf + native_ack_marker: PASS_100 + initial_login_count: 3 + code_commit: PASS_100 + branch_move: PASS_100 + resident_login_count: 10 + recovery_command: PASS_100 + proof_flag: A7 + proof_login_count: 13 + result: PASS_100 +physical_native_ack_v2: + result: NOT_RUN_0 + rule: MUST_USE_ONE_TIME_BOOT_AND_SERVER_OWNED_LBA_PROOF +boundary: + persona_subject_exists: 100 + native_resident_recovery_attempt_001: 0 + native_ack_v2_qemu_capability: 100 + native_ack_v2_physical_capability: 0 +next_action: PUBLISH_EXACT_SOURCE_THEN_RUN_SECOND_ONE_TIME_PHYSICAL_GATE diff --git a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm index f547a44..20a34ed 100644 --- a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm +++ b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm @@ -1013,6 +1013,11 @@ ghal_net_icmp_login_once: jne .ignore_packet cmp word [VIRTIO_NET_RX_BUFFER + 44], 0x0008 jne .ignore_packet + cmp byte [VIRTIO_NET_RX_BUFFER + 50], 0 + jne .ignore_packet + mov al, [VIRTIO_NET_RX_BUFFER + 51] + cmp al, [rel ghal_net_expected_sequence] + jne .ignore_packet mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET mov rdi, [rel ghal_net_expected_magic] mov ecx, GHOS_LOGIN_MAGIC_SIZE @@ -1100,6 +1105,10 @@ ghal_net_icmp_login_once: mov [VIRTIO_NET_TX_BUFFER + 40], eax mov byte [VIRTIO_NET_TX_BUFFER + 44], 0 mov word [VIRTIO_NET_TX_BUFFER + 46], 0 + lea rsi, [rel ghal_native_ack_magic] + mov rdi, VIRTIO_NET_TX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET + GHOS_LOGIN_MAGIC_SIZE + mov ecx, GHOS_LOGIN_MAGIC_SIZE + rep movsb movzx eax, word [VIRTIO_NET_TX_BUFFER + 26] xchg al, ah @@ -1181,6 +1190,7 @@ ghal_net_icmp_login_once: mov [rel ghal_net_rx_next_index], r8w inc word [rel ghal_net_rx_next_index] inc word [rel ghal_net_tx_next_index] + inc byte [rel ghal_net_expected_sequence] cmp byte [rel ghal_net_matched_kind], 0 jne .not_login_reply inc byte [rel physical_proof_login_reply_count] @@ -1213,6 +1223,7 @@ ghal_net_tx_next_index: dw 2 ghal_net_expected_magic: dq ghal_login_magic ghal_net_command_kind: db 0 ghal_net_matched_kind: db 0 +ghal_net_expected_sequence: db 1 msg_ghal_net_discovered: db "GHOS_GHAL_VIRTIO_NET=DISCOVERED", 13, 10, 0 msg_ghal_block_discovered: db "GHOS_GHAL_VIRTIO_BLOCK=DISCOVERED", 13, 10, 0 @@ -1229,6 +1240,7 @@ ghal_login_magic: db "HLDP-GHOS-LOGIN!" ghal_code_commit_magic: db "HLDP-CODE-COMMIT" ghal_branch_move_magic: db "HLDP-BRANCH-MOVE" ghal_recovery_magic: db "HLDP-RECOVER-OS!" +ghal_native_ack_magic: db "HLDP-NATIVE-ACK!" ghal_branch_receipt_template: db "GHOS_BRANCH_MAIN_V1", 10 db "channel=HLP-MOD-CODE-CHANNEL", 10 diff --git a/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py b/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py index 4a92065..484dd58 100755 --- a/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py +++ b/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py @@ -10,6 +10,7 @@ LOGIN_MAGIC = b"HLDP-GHOS-LOGIN!" COMMIT_MAGIC = b"HLDP-CODE-COMMIT" BRANCH_MAGIC = b"HLDP-BRANCH-MOVE" RECOVERY_MAGIC = b"HLDP-RECOVER-OS!" +NATIVE_ACK_MAGIC = b"HLDP-NATIVE-ACK!" def checksum(payload: bytes) -> int: @@ -28,16 +29,28 @@ def request(sequence: int, magic: bytes) -> bytes: return packet[:2] + struct.pack("!H", checksum(packet)) + packet[4:] -def verify_reply(packet: bytes, magic: bytes) -> None: +def reply_sequence_index(packet: bytes) -> int: if packet and packet[0] >> 4 == 4: header_length = (packet[0] & 0x0F) * 4 packet = packet[header_length:] - if len(packet) < 40 or packet[0] != 0 or packet[1] != 0: + if len(packet) < 8: + raise RuntimeError("ICMP reply is too short") + return int.from_bytes(packet[6:8], "big") + + +def verify_reply(packet: bytes, magic: bytes) -> int: + if packet and packet[0] >> 4 == 4: + header_length = (packet[0] & 0x0F) * 4 + packet = packet[header_length:] + if len(packet) < 48 or packet[0] != 0 or packet[1] != 0: raise RuntimeError("unexpected ICMP reply shape") if packet[16:32] != magic: raise RuntimeError("ICMP reply does not carry the requested HLDP magic") + if packet[32:48] != NATIVE_ACK_MAGIC: + raise RuntimeError("ICMP reply does not carry the native ACK marker") if checksum(packet) != 0: raise RuntimeError("ICMP reply checksum failed") + return int.from_bytes(packet[6:8], "big") def exchange( @@ -46,14 +59,21 @@ def exchange( sequence: int, magic: bytes, deadline: float, + retry_interval: float, ) -> None: while time.monotonic() < deadline: peer.sendto(request(sequence, magic), target) + attempt_started = time.monotonic() try: packet, _ = peer.recvfrom(4096) except TimeoutError: + time.sleep(max(0.0, retry_interval - (time.monotonic() - attempt_started))) + continue + try: + verify_reply(packet, magic) + except RuntimeError: + time.sleep(max(0.0, retry_interval - (time.monotonic() - attempt_started))) continue - verify_reply(packet, magic) return raise TimeoutError(f"no verified reply for sequence {sequence}") @@ -63,36 +83,150 @@ def main() -> None: parser.add_argument("--target", required=True) parser.add_argument("--receipt", required=True) parser.add_argument("--timeout", type=float, default=90.0) + parser.add_argument("--retry-interval", type=float, default=1.0) + parser.add_argument("--raw-socket", action="store_true") parser.add_argument("--resident", action="store_true") parser.add_argument("--login-only", action="store_true") + parser.add_argument("--resume-after-login", action="store_true") + parser.add_argument("--resume-after-commit", action="store_true") + parser.add_argument("--resume-after-branch", action="store_true") + parser.add_argument("--resume-resident-count", type=int) + parser.add_argument("--resident-pipeline", action="store_true") args = parser.parse_args() - if args.resident and args.login_only: - raise SystemExit("--resident and --login-only are mutually exclusive") + if args.retry_interval < 1.0: + raise SystemExit("--retry-interval must be at least 1 second") + if args.resume_resident_count is not None and not ( + 0 <= args.resume_resident_count <= 10 + ): + raise SystemExit("--resume-resident-count must be between 0 and 10") + if sum( + ( + args.resident, + args.login_only, + args.resume_after_login, + args.resume_after_commit, + args.resume_after_branch, + args.resume_resident_count is not None, + args.resident_pipeline, + ) + ) > 1: + raise SystemExit( + "--resident, --login-only, --resume-after-login, and " + "--resume-after-commit, --resume-after-branch, and " + "--resume-resident-count, and --resident-pipeline are mutually exclusive" + ) - peer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP) - peer.settimeout(1.0) + socket_type = socket.SOCK_RAW if args.raw_socket else socket.SOCK_DGRAM + peer = socket.socket(socket.AF_INET, socket_type, socket.IPPROTO_ICMP) + peer.settimeout(0.2 if args.resident_pipeline else 1.0) target = (socket.gethostbyname(args.target), 0) deadline = time.monotonic() + args.timeout - sequence = 1 - phases: list[tuple[str, bytes]] = [ - ("login", LOGIN_MAGIC), - ("login", LOGIN_MAGIC), - ("login", LOGIN_MAGIC), - ] - if not args.login_only: + if args.resident_pipeline: + pipeline = [ + LOGIN_MAGIC, + LOGIN_MAGIC, + LOGIN_MAGIC, + COMMIT_MAGIC, + BRANCH_MAGIC, + *([LOGIN_MAGIC] * 10), + RECOVERY_MAGIC, + ] + acknowledged: set[int] = set() + while time.monotonic() < deadline and len(acknowledged) < len(pipeline): + for pipeline_sequence, pipeline_magic in enumerate(pipeline, start=1): + if time.monotonic() >= deadline: + break + peer.sendto(request(pipeline_sequence, pipeline_magic), target) + try: + packet, _ = peer.recvfrom(4096) + observed_sequence = reply_sequence_index(packet) + if not 1 <= observed_sequence <= len(pipeline): + raise RuntimeError("native ACK sequence is outside the pipeline") + reply_sequence = verify_reply( + packet, + pipeline[observed_sequence - 1], + ) + except (TimeoutError, RuntimeError, IndexError): + continue + if reply_sequence == pipeline_sequence: + acknowledged.add(reply_sequence) + if len(acknowledged) != len(pipeline): + raise TimeoutError( + "native pipeline incomplete; acknowledged sequences: " + + ",".join(str(item) for item in sorted(acknowledged)) + ) + receipt = pathlib.Path(args.receipt) + receipt.write_text( + "schema: guanghu.physical-native-icmp-peer/v2\n" + "status: PASS_100\n" + f"target: {args.target}\n" + "native_ack_marker: HLDP-NATIVE-ACK!\n" + "acknowledged_sequences: 1-16\n" + "login_reply_count: 3\n" + "code_commit_reply_verified: true\n" + "branch_move_reply_verified: true\n" + "resident_login_reply_count: 10\n" + "recovery_reply_verified: true\n", + encoding="utf-8", + ) + print(receipt.read_text(encoding="utf-8"), end="") + return + if args.resume_resident_count is not None: + sequence = 6 + args.resume_resident_count + elif args.resume_after_branch: + sequence = 6 + elif args.resume_after_commit: + sequence = 5 + elif args.resume_after_login: + sequence = 4 + else: + sequence = 1 + phases: list[tuple[str, bytes]] = [] + if not ( + args.resume_after_login + or args.resume_after_commit + or args.resume_after_branch + or args.resume_resident_count is not None + ): + phases.extend( + [ + ("login", LOGIN_MAGIC), + ("login", LOGIN_MAGIC), + ("login", LOGIN_MAGIC), + ] + ) + if ( + not args.login_only + and not args.resume_after_commit + and not args.resume_after_branch + and args.resume_resident_count is None + ): phases.extend( [ ("code_commit", COMMIT_MAGIC), ("branch_move", BRANCH_MAGIC), ] ) - if args.resident: + if args.resume_after_commit: + phases.append(("branch_move", BRANCH_MAGIC)) + if args.resume_resident_count is not None: + phases.extend( + [("resident_login", LOGIN_MAGIC)] + * (10 - args.resume_resident_count) + ) + phases.append(("recovery", RECOVERY_MAGIC)) + elif ( + args.resident + or args.resume_after_login + or args.resume_after_commit + or args.resume_after_branch + ): phases.extend([("resident_login", LOGIN_MAGIC)] * 10) phases.append(("recovery", RECOVERY_MAGIC)) completed: list[str] = [] for phase, magic in phases: - exchange(peer, target, sequence, magic, deadline) + exchange(peer, target, sequence, magic, deadline, args.retry_interval) completed.append(phase) sequence += 1 @@ -104,7 +238,10 @@ def main() -> None: f"login_reply_count: {completed.count('login')}\n" f"code_commit_reply_verified: {str('code_commit' in completed).lower()}\n" f"branch_move_reply_verified: {str('branch_move' in completed).lower()}\n" + f"resident_login_resume_count: {args.resume_resident_count or 0}\n" f"resident_login_reply_count: {completed.count('resident_login')}\n" + "resident_login_total_count: " + f"{(args.resume_resident_count or 0) + completed.count('resident_login')}\n" f"recovery_reply_verified: {str('recovery' in completed).lower()}\n", encoding="utf-8", ) diff --git a/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py b/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py index a8a78c0..03b8fdb 100644 --- a/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py +++ b/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py @@ -14,6 +14,7 @@ LOGIN_MAGIC = b"HLDP-GHOS-LOGIN!" COMMIT_MAGIC = b"HLDP-CODE-COMMIT" BRANCH_MAGIC = b"HLDP-BRANCH-MOVE" RECOVERY_MAGIC = b"HLDP-RECOVER-OS!" +NATIVE_ACK_MAGIC = b"HLDP-NATIVE-ACK!" def checksum(payload: bytes) -> int: @@ -77,6 +78,7 @@ def validate_reply(frame: bytes, magic: bytes) -> None: assert frame[30:34] == LOGIN_CLIENT_IP assert frame[34] == 0 assert frame[50:66] == magic + assert frame[66:82] == NATIVE_ACK_MAGIC assert checksum(frame[34:]) == 0