Cai
Cai

Reputation: 3649

KEXT: vnode_open() result in Kernel Panic

Sorry if it was asked before, but I can't really google any.

I was trying to read files within the KEXT of OSX, using vnode_open() like the following:

        struct vnode *vp = NULL;
        kern_return_t kret;
        vfs_context_t ctx = vfs_context_current();

        kret = vnode_open(path, FREAD, 0, 0, &vp, ctx);
        if (kret != KERN_SUCCESS) {
            // Error log
        } else {
            proc_t proc = vfs_context_proc(ctx);
            kauth_cred_t vp_cred = vfs_context_ucred(ctx);

            char *buf = NULL;
            int resid;
            int len = sizeof(struct astruct);
            buf = (char *)IOMalloc(len);

            kret = vn_rdwr(UIO_READ, fvp, (caddr_t)buf,
                           len, 0, UIO_SYSSPACE, 0, vp_cred, &resid, proc);

            vnode_close(fvp, FREAD, ctx);

            if (kret != KERN_SUCCESS) {
                // Error log
            }

            // Do something with the result.
        }
        vfs_context_rele(ctx);

Once the kext was loaded, the system panics and reboots. As long as vnode_open() is there, it panics.

Am I doing it wrong?

Upvotes: 1

Views: 776

Answers (1)

pmdj
pmdj

Reputation: 23428

One thing that immediately stands out:

You shouldn't be using vfs_context_current() - use vfs_context_create(NULL). What's worse, you're subsequently calling vfs_context_rele(ctx); on the returned context. Only vfs_context_create retains, vfs_context_current() does not, so you're over-releasing the VFS context. This could certainly cause a kernel panic.

In general, when developing kexts, you can really be doing a lot more than just letting the system reboot after a kernel panic:

  1. Panic logs are written to NVRAM, and on next boot, are saved to file. You can inspect them via Console.app, under "System Diagnostic Reports" starting with "kernel".
  2. Panic logs contain a stack trace, which is by default unsymbolicated. You can symbolicate them after the crash, but it's a lot more convenient to set the keepsyms=1 boot argument and get the crash handler to symbolicate for you.
  3. You can set up the debug boot argument to make crashes initiate the kernel debugger or core dumps, write the stack trace to serial/firewire console, etc.

These things are documented in part on Apple's site, but a bit of searching on the web might get you some more detailed information. In any case, they're incredibly useful for debugging problems like this.

Upvotes: 2

Related Questions