syzkaller icon indicating copy to clipboard operation
syzkaller copied to clipboard

MacOS XNU kernel can't be parsed by debug/elf

Open phyonism opened this issue 3 years ago • 6 comments

HOST : osx 12.6 TARGET : macOS 11.5

run >> ~/115/bin/syz-manager -config=/root/115/syzkaller.cfg result >> SYZFATAL: failed to open ELF file /Users/user/115/obj/kernel.kasan: bad magic number '[207 250 237 254]' in record at byte 0x0

What's Happen? Help Me

phyonism avatar Oct 26 '22 06:10 phyonism

Please re-send to the mailing list with full repro instructions.

dvyukov avatar Oct 26 '22 12:10 dvyukov

I checked the source code, it seem like it use method ctorBSD for ctorDarwin, and the ctorBSD method will make the kernel.kasan as elf file, so it crashed with message [FATAL] failed to open ELF file /Users/qaz/xnu_132/obj/kernel.kasan: bad magic number '[207 250 237 254]' in record at byte 0x0, How should I make it work with macos ?

retX0 avatar Jul 11 '23 09:07 retX0

Cc @HerrSpace

a-nogikh avatar Jul 11 '23 09:07 a-nogikh

the config file

{
    "target": "darwin/amd64",
    "http": "127.0.0.1:56741",
    "sshkey": "/Users/qaz/.ssh/id_rsa.pub",
    "workdir": "/Users/qaz/xnu_132",
    "kernel_obj": "/Users/qaz/xnu_132/obj/",
    "kernel_src": "/Users/qaz/xnu_132/src/",
    "syzkaller": "/Users/qaz/syzkaller",
    "procs": 2,
    "type": "qemu",
    "cover": true,
    "image": "/Users/qaz/Developer/fuzz-xnu/mac_hdd.qcow",
    "vm": {
        "count": 1,
        "cpu": 1,
        "mem": 4096,
        "efi_code_device": "/usr/local/share/OVMF/OVMF_CODE.fd",
        "efi_vars_device": "/usr/local/share/OVMF/OVMF_VARS.fd",
        "apple_smc_osk": "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"
    }
}

retX0 avatar Jul 11 '23 09:07 retX0

I reproduced this issue on head and narrowed the cause down to this commit, where we switched from symbolising reports via nm to golangs debug/elf. As the xnu kernel is a macho binary, this of course doesn't work.

Use d236a457274375e5273ac4e958722659929c469f and older for macos for now.

Previous report

RonjaPonja avatar Jul 11 '23 11:07 RonjaPonja

Now it works, and the xnu updated the ksancov.h path and struct ksancov_trace members with commit e6231be The path changed from san/ksancov.h to san/tools/ksancov.h before this commit


struct ksancov_trace {
	/* userspace R/O fields */
	union {
		struct ksancov_header hdr;
		struct {
			uint32_t magic;
			_Atomic uint32_t enabled;
		};
	};

	uintptr_t offset; /* pc entries relative to this */
	uint32_t maxpcs;
	_Atomic uint32_t head;
	uint32_t pcs[];
};

after the commit

typedef struct ksancov_trace {
	ksancov_header_t kt_hdr;         /* header (must be always first) */
	uintptr_t        kt_offset;      /* All recorded PCs are relateive to this offset. */
	uint32_t         kt_maxent;      /* Maximum entries in this shared buffer. */
	_Atomic uint32_t kt_head;        /* Pointer to the first unused element. */
	uint64_t         kt_entries[];   /* Trace entries in this buffer. */
} ksancov_trace_t;

Maybe the source code need to change to adjust for this commit, I just copy the san/tools/ksancov.h to the san/ksancov.h and change the executor/executor_darwin.h. like this

diff --git a/executor/executor_darwin.h b/executor/executor_darwin.h
index c16691663..6e5c990e8 100644
--- a/executor/executor_darwin.h
+++ b/executor/executor_darwin.h
@@ -113,8 +113,8 @@ static void cover_collect(cover_t* cov)
 {
 	struct ksancov_trace* trace = (struct ksancov_trace*)cov->data;
 	cov->size = ksancov_trace_head(trace);
-	cov->data_offset = ((int64_t) & (trace->pcs)) - ((int64_t)(cov->data));
-	cov->pc_offset = trace->offset;
+	cov->data_offset = ((int64_t) & (trace->kt_entries)) - ((int64_t)(cov->data));
+	cov->pc_offset = trace->kt_offset;
 }

 static bool use_cover_edges(uint64 pc)

retX0 avatar Jul 12 '23 01:07 retX0