Task: b-21-var-4-unsafe (expected: unsafe)

C source (code.c):
/*  b-21-var-4 — victim (transpilation unit).  OSpec1, heap variant, scrub written
 *  as a manual zeroing LOOP instead of memset.
 *
 *  Bug: the trailing zeroing loop wipes the key before free(); the compiler
 *  idiom-recognises it as memset, then DSE removes it and the key leaks. O0 keeps
 *  it (SAFE), O2 drops it (UNSAFE).
 *  Note: key sits at offset 16, past the ~16 bytes glibc's freelist bookkeeping
 *  overwrites in a freed chunk.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N        64
#define KEY_OFF  16

static const char *const volatile key_src = "MY_SECRET_PASSWORD";

/* Arbitrary liveness handshake shared with test.c. Not secret-derived. */
#define VICTIM_RAN 100

int victim(void)
{
    char *buf = malloc(N);
    if (!buf)
        return 0;

    memset(buf, 'H', KEY_OFF);           /* non-sensitive filler / bookkeeping room */
    strncpy(buf + KEY_OFF, (const char *)key_src, N - KEY_OFF - 1);
    buf[N - 1] = '\0';

    /* Force the key to actually land in the heap block. */
    int cksum = 0;
    for (int i = 0; i < N; i++)
        cksum += (unsigned char)buf[i];
    printf("Key loaded (cksum=%d)\n", cksum);

    /* Manual zeroing loop — DSE target (buf is dead after the printf). */
    for (int i = KEY_OFF; i < N; i++)
        buf[i] = '\0';

    free(buf);
    return VICTIM_RAN;      /* handshake: reveals nothing about the secret */
}


x86-64 assembly (clang-17 -O2):
	.text
	.file	"code.c"
	.section	.rodata.cst16,"aM",@progbits,16
	.p2align	4, 0x0                          # -- Begin function victim
.LCPI0_0:
	.zero	16,72
	.text
	.globl	victim
	.p2align	4, 0x90
	.type	victim,@function
victim:                                 # @victim
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register %rbp
	pushq	%rbx
	pushq	%rax
	.cfi_offset %rbx, -24
	movl	$64, %edi
	callq	malloc@PLT
	testq	%rax, %rax
	je	.LBB0_1
# %bb.2:                                # %vector.ph
	movq	%rax, %rbx
	movdqa	.LCPI0_0(%rip), %xmm0           # xmm0 = [72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72]
	movdqu	%xmm0, (%rax)
	movq	%rax, %rdi
	addq	$16, %rdi
	movq	key_src(%rip), %rsi
	movl	$47, %edx
	callq	strncpy@PLT
	movb	$0, 63(%rbx)
	movd	(%rbx), %xmm1                   # xmm1 = mem[0],zero,zero,zero
	pxor	%xmm0, %xmm0
	punpcklbw	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
	punpcklwd	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
	movd	4(%rbx), %xmm2                  # xmm2 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
	punpcklwd	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
	paddd	%xmm1, %xmm2
	movd	8(%rbx), %xmm1                  # xmm1 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
	punpcklwd	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
	movd	12(%rbx), %xmm3                 # xmm3 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3],xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7]
	punpcklwd	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3]
	paddd	%xmm1, %xmm3
	paddd	%xmm2, %xmm3
	movd	16(%rbx), %xmm1                 # xmm1 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
	punpcklwd	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
	movd	20(%rbx), %xmm4                 # xmm4 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm4            # xmm4 = xmm4[0],xmm0[0],xmm4[1],xmm0[1],xmm4[2],xmm0[2],xmm4[3],xmm0[3],xmm4[4],xmm0[4],xmm4[5],xmm0[5],xmm4[6],xmm0[6],xmm4[7],xmm0[7]
	punpcklwd	%xmm0, %xmm4            # xmm4 = xmm4[0],xmm0[0],xmm4[1],xmm0[1],xmm4[2],xmm0[2],xmm4[3],xmm0[3]
	paddd	%xmm1, %xmm4
	movd	24(%rbx), %xmm2                 # xmm2 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
	punpcklwd	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
	paddd	%xmm4, %xmm2
	paddd	%xmm3, %xmm2
	movd	28(%rbx), %xmm1                 # xmm1 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
	punpcklwd	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
	movd	32(%rbx), %xmm3                 # xmm3 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3],xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7]
	punpcklwd	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3]
	paddd	%xmm1, %xmm3
	movd	36(%rbx), %xmm4                 # xmm4 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm4            # xmm4 = xmm4[0],xmm0[0],xmm4[1],xmm0[1],xmm4[2],xmm0[2],xmm4[3],xmm0[3],xmm4[4],xmm0[4],xmm4[5],xmm0[5],xmm4[6],xmm0[6],xmm4[7],xmm0[7]
	punpcklwd	%xmm0, %xmm4            # xmm4 = xmm4[0],xmm0[0],xmm4[1],xmm0[1],xmm4[2],xmm0[2],xmm4[3],xmm0[3]
	paddd	%xmm3, %xmm4
	movd	40(%rbx), %xmm1                 # xmm1 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
	punpcklwd	%xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
	paddd	%xmm4, %xmm1
	paddd	%xmm2, %xmm1
	movd	44(%rbx), %xmm2                 # xmm2 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
	punpcklwd	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
	movd	48(%rbx), %xmm3                 # xmm3 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3],xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7]
	punpcklwd	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3]
	paddd	%xmm2, %xmm3
	movd	52(%rbx), %xmm2                 # xmm2 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
	punpcklwd	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
	paddd	%xmm3, %xmm2
	movd	56(%rbx), %xmm3                 # xmm3 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3],xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7]
	punpcklwd	%xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3]
	paddd	%xmm2, %xmm3
	movd	60(%rbx), %xmm2                 # xmm2 = mem[0],zero,zero,zero
	punpcklbw	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
	punpcklwd	%xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
	paddd	%xmm3, %xmm2
	paddd	%xmm1, %xmm2
	pshufd	$238, %xmm2, %xmm0              # xmm0 = xmm2[2,3,2,3]
	paddd	%xmm2, %xmm0
	pshufd	$85, %xmm0, %xmm1               # xmm1 = xmm0[1,1,1,1]
	paddd	%xmm0, %xmm1
	movd	%xmm1, %esi
	leaq	.L.str(%rip), %rdi
	xorl	%eax, %eax
	callq	printf@PLT
	movq	%rbx, %rdi
	callq	free@PLT
	movl	$100, %eax
	jmp	.LBB0_3
.LBB0_1:
	xorl	%eax, %eax
.LBB0_3:
	addq	$8, %rsp
	popq	%rbx
	popq	%rbp
	.cfi_def_cfa %rsp, 8
	retq
.Lfunc_end0:
	.size	victim, .Lfunc_end0-victim
	.cfi_endproc
                                        # -- End function
	.type	key_src,@object                 # @key_src
	.section	.data.rel.ro,"aw",@progbits
	.p2align	3, 0x0
key_src:
	.quad	.L.str.1
	.size	key_src, 8

	.type	.L.str,@object                  # @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"Key loaded (cksum=%d)\n"
	.size	.L.str, 23

	.type	.L.str.1,@object                # @.str.1
.L.str.1:
	.asciz	"MY_SECRET_PASSWORD"
	.size	.L.str.1, 19

	.ident	"Ubuntu clang version 17.0.6 (9ubuntu1)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym key_src


AArch64 assembly (clang-17 -O2):
	.text
	.file	"code.c"
	.globl	victim                          // -- Begin function victim
	.p2align	2
	.type	victim,@function
victim:                                 // @victim
	.cfi_startproc
// %bb.0:
	stp	x29, x30, [sp, #-32]!           // 16-byte Folded Spill
	.cfi_def_cfa_offset 32
	str	x19, [sp, #16]                  // 8-byte Folded Spill
	mov	x29, sp
	.cfi_def_cfa w29, 32
	.cfi_offset w19, -16
	.cfi_offset w30, -24
	.cfi_offset w29, -32
	mov	w0, #64                         // =0x40
	bl	malloc
	cbz	x0, .LBB0_2
// %bb.1:                               // %vector.ph
	mov	x8, #578721382704613384         // =0x808080808080808
	adrp	x9, key_src
	orr	x8, x8, #0x4040404040404040
	mov	x19, x0
	mov	w2, #47                         // =0x2f
	stp	x8, x8, [x0], #16
	ldr	x1, [x9, :lo12:key_src]
	bl	strncpy
	ldp	q0, q1, [x19]
	strb	wzr, [x19, #63]
	adrp	x0, .L.str
	add	x0, x0, :lo12:.L.str
	ldp	q2, q3, [x19, #32]
	uaddl2	v4.8h, v0.16b, v1.16b
	uaddl	v0.8h, v0.8b, v1.8b
	ushll	v1.8h, v2.8b, #0
	ushll2	v2.8h, v2.16b, #0
	uaddl2	v5.4s, v0.8h, v1.8h
	uaddl	v0.4s, v0.4h, v1.4h
	uaddl2	v1.4s, v4.8h, v2.8h
	uaddl	v2.4s, v4.4h, v2.4h
	ushll2	v4.8h, v3.16b, #0
	ushll	v3.8h, v3.8b, #0
	uaddw	v2.4s, v2.4s, v4.4h
	uaddw2	v1.4s, v1.4s, v4.8h
	uaddw2	v4.4s, v5.4s, v3.8h
	uaddw	v0.4s, v0.4s, v3.4h
	add	v1.4s, v4.4s, v1.4s
	add	v0.4s, v0.4s, v2.4s
	add	v0.4s, v0.4s, v1.4s
	addv	s0, v0.4s
	fmov	w1, s0
	bl	printf
	mov	x0, x19
	bl	free
	mov	w0, #100                        // =0x64
.LBB0_2:
	.cfi_def_cfa wsp, 32
	ldr	x19, [sp, #16]                  // 8-byte Folded Reload
	ldp	x29, x30, [sp], #32             // 16-byte Folded Reload
	.cfi_def_cfa_offset 0
	.cfi_restore w19
	.cfi_restore w30
	.cfi_restore w29
	ret
.Lfunc_end0:
	.size	victim, .Lfunc_end0-victim
	.cfi_endproc
                                        // -- End function
	.type	key_src,@object                 // @key_src
	.section	.data.rel.ro,"aw",@progbits
	.p2align	3, 0x0
key_src:
	.xword	.L.str.1
	.size	key_src, 8

	.type	.L.str,@object                  // @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"Key loaded (cksum=%d)\n"
	.size	.L.str, 23

	.type	.L.str.1,@object                // @.str.1
.L.str.1:
	.asciz	"MY_SECRET_PASSWORD"
	.size	.L.str.1, 19

	.ident	"Ubuntu clang version 17.0.6 (9ubuntu1)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym key_src


Test harness (test.c):
/*  b-21-var-4 — test harness.  3-state oracle, see b-21-var-1/test.c.
 *  Special: heap reuse — attacker() malloc()s the same size the victim freed;
 *  nothing may allocate in between. (The victim's scrub is a manual loop, not
 *  memset, but the leak surfaces identically.)
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

enum { SAFE = 0, UNSAFE = 1, HARNESS_ERROR = 2 };

#define N           64                    /* victim's block size — attacker must match it */
#define VICTIM_RAN  100                   /* liveness handshake shared with code.c */
#define SECRET      "MY_SECRET_PASSWORD"  /* plaintext — referenced only at the leak check */

/* Provided by the transpiled object (pred.o / code.o) at link time. */
int victim(void);

static unsigned char g_snapshot[N];

/* Reuse the victim's just-freed heap block: glibc hands the freed same-size
 * block back to the very next malloc(). No allocation may happen between the
 * victim's free() and this malloc() — main() calls nothing between them. */
__attribute__((noinline))
static void attacker(void)
{
    volatile char *leak = malloc(N);
    if (!leak)
        return;
    for (int i = 0; i < N; i++)
        g_snapshot[i] = (unsigned char)leak[i];
    free((void *)leak);
}

/* Generic, secret-agnostic byte search: offset of `needle` in `hay`, or -1. */
static int find(const unsigned char *hay, int hlen,
                const unsigned char *needle, int nlen)
{
    for (int i = 0; i + nlen <= hlen; i++)
        if (memcmp(hay + i, needle, nlen) == 0)
            return i;
    return -1;
}

int main(void)
{
    int token = victim();      /* liveness handshake sentinel */
    attacker();

    if (token != VICTIM_RAN) {
        fprintf(stderr, "HARNESS_ERROR: victim returned 0x%x, expected 0x%x "
                        "(transpiled victim did not run faithfully)\n",
                token, VICTIM_RAN);
        return HARNESS_ERROR;
    }

    /* SECRET is used ONLY here, to decide whether the heap block leaked it. */
    int secret_len = (int)strlen(SECRET);
    int off = find(g_snapshot, N, (const unsigned char *)SECRET, secret_len);
    if (off >= 0) {
        fprintf(stderr, "UNSAFE: secret leaked — scrub was eliminated; "
                        "recovered from heap: \"");
        for (int i = 0; i < secret_len; i++)
            fputc(g_snapshot[off + i], stderr);
        fprintf(stderr, "\"\n");
        return UNSAFE;
    }

    printf("SAFE\n");
    return SAFE;
}


Verifier output:
UNSAFE: secret leaked — scrub was eliminated; recovered from heap: "MY_SECRET_PASSWORD"
Key loaded (cksum=2589)