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

C source (code.c):
/*  b-21-var-0 — victim (transpilation unit).  OSpec1 / DSE-memset, heap variant.
 *
 *  Bug: the trailing memset scrubs the secret before free(); if the optimizer's
 *  Dead Store Elimination removes that scrub, the secret survives in the freed
 *  heap block and leaks. O0 keeps it (SAFE), O2 drops it (UNSAFE).
 *  Note: secret sits at offset 16 — glibc writes freelist bookkeeping into a
 *  freed chunk's first ~16 bytes, which would otherwise clobber it.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N           64
#define SECRET_OFF  16

static const char *const volatile secret_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', SECRET_OFF);        /* non-sensitive filler / bookkeeping room */
    strncpy(buf + SECRET_OFF, (const char *)secret_src, N - SECRET_OFF - 1);
    buf[N - 1] = '\0';

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

    memset(buf + SECRET_OFF, 0, N - SECRET_OFF);   /* scrub the secret — DSE target */
    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	secret_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	secret_src,@object              # @secret_src
	.section	.data.rel.ro,"aw",@progbits
	.p2align	3, 0x0
secret_src:
	.quad	.L.str.1
	.size	secret_src, 8

	.type	.L.str,@object                  # @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"Victim stored secret (cksum=%d)\n"
	.size	.L.str, 33

	.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 secret_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, secret_src
	orr	x8, x8, #0x4040404040404040
	mov	x19, x0
	mov	w2, #47                         // =0x2f
	stp	x8, x8, [x0], #16
	ldr	x1, [x9, :lo12:secret_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	secret_src,@object              // @secret_src
	.section	.data.rel.ro,"aw",@progbits
	.p2align	3, 0x0
secret_src:
	.xword	.L.str.1
	.size	secret_src, 8

	.type	.L.str,@object                  // @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"Victim stored secret (cksum=%d)\n"
	.size	.L.str, 33

	.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 secret_src


Test harness (test.c):
/*  b-21-var-0 — test harness.  3-state oracle, see b-21-var-1/test.c.
 *  Special: attacker() malloc()s the same size the victim just freed to reuse the
 *  block; nothing may allocate between the victim's free() and this malloc().
 */
#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's allocator 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. leak[] is volatile so the residue reads actually occur. */
__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.
 * It knows nothing about "the secret" — the caller decides what to look for. */
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"
Victim stored secret (cksum=2589)