fix(security): no VM but Artemis and Hera can make Hera run text; a message runs once; word-ACL elevation removed
Any identity could have arbitrary FORTH run as Zuse: KH-ELEVATE-SEND and KH-BLK-ATTACH-SEND sent any text to Hera, from any VM (shown live). And the drain popped a message after running it, so a payload calling a colon word ran twice. Both fixed test first (FABRIC-3 SXXXVII): - KH-BLK-ATTACH-SEND is ( dev-addr ok? -- sent? ), Artemis only; the kernel writes the reply text. BLK-ATTACH-ACK is Hera's only. - The drain pops before it runs. - Elevation, ruled not needed: KH-ELEVATE-SEND, message type 8, zuse-eligibility.4th, ZUSE-ELIGIBLE?/ZUSE-ELIGIBILITY-ADD/ ELEVATE-PUBKEY-UNPACK and the eligibility list removed; its disk area stays reserved, unused. FABRIC-3.7 closed. Three ISAs: POST 1052 passed; new parity baseline word_count=523 hash=0xb73b58052d591638 (deliberate). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
029a8ed9cf
commit
5e26fad30d
@@ -49,7 +49,6 @@
|
||||
#include "starkernel/capsule_mint.h"
|
||||
#include "starkernel/user_identity_seed.h"
|
||||
#include "starkernel/vm_identity.h"
|
||||
#include "starkernel/zuse_eligibility.h"
|
||||
#include "starkernel/capsule_loader.h"
|
||||
#include "starkernel/capsule_run.h"
|
||||
#include "starkernel/capsule_loader.h"
|
||||
@@ -1345,70 +1344,6 @@ static void mama_word_mint_scratch_emit(VM *vm)
|
||||
vm_push(vm, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ZUSE-ELIGIBILITY-ADD ( c-addr -- ok? )
|
||||
* Add the 32-byte Ed25519 public key at c-addr to Zuse's elevation
|
||||
* eligibility list (FABRIC-2.md §H.5/§H.12 item 19). Plain, unconditional
|
||||
* primitive -- no authorization check here or anywhere else in this
|
||||
* codebase gates on vm->zuse_session. Zuse's authority is the *absence*
|
||||
* of any ACL restricting her, not a bit this or any other word checks;
|
||||
* restricting who may call this word, if ever wanted, is the same
|
||||
* standing word-level ACL mechanism (acl_allow/ACL-PIN in ACL.4th) any
|
||||
* other word would use, applied later if and when actually needed --
|
||||
* not invented here.
|
||||
*/
|
||||
static void mama_word_zuse_eligibility_add(VM *vm)
|
||||
{
|
||||
if (vm->dsp < 0) {
|
||||
console_println("ZUSE-ELIGIBILITY-ADD: stack underflow");
|
||||
vm->error = 1;
|
||||
vm_push(vm, 0);
|
||||
return;
|
||||
}
|
||||
cell_t caddr = vm_pop(vm);
|
||||
const uint8_t *pubkey = vm_ptr(vm, (vaddr_t)caddr);
|
||||
if (!pubkey) {
|
||||
console_println("ZUSE-ELIGIBILITY-ADD: invalid address on the stack");
|
||||
vm->error = 1;
|
||||
vm_push(vm, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (zuse_eligibility_add(pubkey) != 0) {
|
||||
console_println("ZUSE-ELIGIBILITY-ADD: FAILED -- fence write error");
|
||||
vm_push(vm, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
vm_push(vm, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ZUSE-ELIGIBLE? ( c-addr -- flag )
|
||||
* Membership check over Zuse's elevation eligibility list (FABRIC-2.md
|
||||
* §H.5/§H.12 item 21). Plain, unconditional wrapper over
|
||||
* zuse_eligibility_is_member() -- same "no bespoke gate" convention as
|
||||
* ZUSE-ELIGIBILITY-ADD above; is_member() itself is already fail-closed.
|
||||
*/
|
||||
static void mama_word_zuse_eligible_query(VM *vm)
|
||||
{
|
||||
if (vm->dsp < 0) {
|
||||
log_message(LOG_ERROR, "ZUSE-ELIGIBLE?: stack underflow");
|
||||
vm->error = 1;
|
||||
vm_push(vm, 0);
|
||||
return;
|
||||
}
|
||||
cell_t caddr = vm_pop(vm);
|
||||
const uint8_t *pubkey = vm_ptr(vm, (vaddr_t)caddr);
|
||||
if (!pubkey) {
|
||||
log_message(LOG_ERROR, "ZUSE-ELIGIBLE?: invalid address on the stack");
|
||||
vm->error = 1;
|
||||
vm_push(vm, 0);
|
||||
return;
|
||||
}
|
||||
vm_push(vm, zuse_eligibility_is_member(pubkey) ? -1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief NAME>XT ( c-addr u -- xt|0 )
|
||||
* Dynamic dictionary lookup for a name already sitting in a data buffer
|
||||
@@ -1444,41 +1379,6 @@ static void mama_word_name_to_xt(VM *vm)
|
||||
vm_push(vm, (cell_t)(uintptr_t)e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ELEVATE-PUBKEY-UNPACK ( pk0 pk1 pk2 pk3 buf-addr -- )
|
||||
* Reconstructs a 32-byte Ed25519 pubkey from 4 cells into the 32-byte
|
||||
* buffer at buf-addr, matching ZUSE-PUBKEY@'s own convention exactly:
|
||||
* chunk i (0..3) is the 8-byte little-endian encoding of pubkey bytes
|
||||
* [i*8 .. i*8+7] -- this is that packing's inverse, so a pubkey sent as
|
||||
* 4 cells (the convention SEND-ELEVATE-REQUEST used before it was
|
||||
* deleted with messaging.4th, FABRIC-3.6.md Phase 4 Stage E) round-trips
|
||||
* byte-exact regardless of any individual chunk's sign bit.
|
||||
*/
|
||||
static void mama_word_elevate_pubkey_unpack(VM *vm)
|
||||
{
|
||||
if (vm->dsp < 4) {
|
||||
log_message(LOG_ERROR, "ELEVATE-PUBKEY-UNPACK: stack underflow");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
cell_t buf_addr = vm_pop(vm);
|
||||
cell_t pk[4];
|
||||
for (int i = 3; i >= 0; i--) pk[i] = vm_pop(vm);
|
||||
|
||||
uint8_t *buf = vm_ptr(vm, (vaddr_t)buf_addr);
|
||||
if (!buf) {
|
||||
log_message(LOG_ERROR, "ELEVATE-PUBKEY-UNPACK: invalid address on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint64_t chunk = (uint64_t)pk[i];
|
||||
for (int b = 0; b < 8; b++) {
|
||||
buf[i * 8 + b] = (uint8_t)(chunk >> (8 * b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RUNCAP-TEST ( caddr u -- ok? rc )
|
||||
* Diagnostic-only word (FABRIC-2.md §F.6/§F.18): calls
|
||||
@@ -2375,10 +2275,7 @@ void register_mama_forth_words(VM *vm)
|
||||
register_word(vm, "WORKER-BIRTH", mama_word_worker_birth);
|
||||
register_word(vm, "UNATTENDED-BIRTH", mama_word_unattended_birth);
|
||||
register_word(vm, "CONSOLE-ATTACH", mama_word_console_attach);
|
||||
register_word(vm, "ZUSE-ELIGIBILITY-ADD", mama_word_zuse_eligibility_add);
|
||||
register_word(vm, "ZUSE-ELIGIBLE?", mama_word_zuse_eligible_query);
|
||||
register_word(vm, "NAME>XT", mama_word_name_to_xt);
|
||||
register_word(vm, "ELEVATE-PUBKEY-UNPACK", mama_word_elevate_pubkey_unpack);
|
||||
register_word(vm, "RUNCAP-TEST", mama_word_runcap_test);
|
||||
register_word(vm, "PAIR-TEST", mama_word_pair_test);
|
||||
register_word(vm, "MAMA-VM-ID", mama_word_mama_vm_id);
|
||||
@@ -2440,10 +2337,7 @@ void register_mama_forth_words(VM *vm)
|
||||
register_word(vm, "WORKER-BIRTH", mama_word_worker_birth);
|
||||
register_word(vm, "UNATTENDED-BIRTH", mama_word_unattended_birth);
|
||||
register_word(vm, "CONSOLE-ATTACH", mama_word_console_attach);
|
||||
register_word(vm, "ZUSE-ELIGIBILITY-ADD", mama_word_zuse_eligibility_add);
|
||||
register_word(vm, "ZUSE-ELIGIBLE?", mama_word_zuse_eligible_query);
|
||||
register_word(vm, "NAME>XT", mama_word_name_to_xt);
|
||||
register_word(vm, "ELEVATE-PUBKEY-UNPACK", mama_word_elevate_pubkey_unpack);
|
||||
register_word(vm, "RUNCAP-TEST", mama_word_runcap_test);
|
||||
register_word(vm, "PAIR-TEST", mama_word_pair_test);
|
||||
register_word(vm, "MAMA-VM-ID", mama_word_mama_vm_id);
|
||||
|
||||
Reference in New Issue
Block a user