[nycbug-talk] Understanding sys/module.h , *module_t and *modeventhand_t

nikolai nikolai at fetissov.org
Wed Apr 9 14:42:12 EDT 2008


>> I'm working through "Designing FreeBSD Rootkits" as a means
>> of deepening my understanding of both FreeBSD and C.
>> I'm understanding it well enough (I hope), examples all work,
>> experimenting has worked. Up to hooking syscalls now.
>>
>> There's this one part from the beginning though, concerning
>> FreeBSD source from sys/module.h that I can't seem to wrap my head
>> around and it's bothering me.
>> Understanding it isn't essential to making things work.
>> But, I feel like if I can just understand this, it's a personal break
>> through for me. It's probably some simple explanation that's right
>> in front of my face but eluding me.
>>
>> We had debated the meaning of the *modeventhand_t in discussion after
>> the last meeting. And after closer examination I felt I understood it
>> for the most part.
>>
>> This question partly involves that line but more so the line
>> immediately preceding it, which declares *module_t and how we see
>> *module_t is used.
>>
>> Using cscope, I could find no definition for the "struct module"
>> structure.
>> *module_t points to "struct module" (which is, apparently, undefined).
>>
>> If I have to guess, I'd say the module structure then becomes defined by
>> whatever
>> we make module_t point to, so long as it's a structure.
>>
>> Later in hello.c
>> modeventhand_t is set to point to our event handler function "load".
>> *modeventhand_t expects for it's first argument (module_t), a pointer
>> variable pointing to a structure type.
>> but load expects for it's first argument (struct module *module), a
>> dereferrenced pointer
>> to a module structure that exists, but isn't defined?
>>
>
> You are wrong here - parameter declaration "struct module *module"
> means module here is a pointer (otherwise it would just be
> "struct module varname" - but people usually don't pass structures
> by value in C :)
>
>> What's really going on here?
>> And, here's a good question: What *is* the first argument being passed
>> to load in execution?
>>
>> I didn't see source for kldload, but I guess I'll hit the KLD man page
>> and maybe that will
>> explain things more.
>>
>> #######################################################################
>>
>> #/sys/sys/module.h
>>
>> ...snip...
>>
>> typedef struct module *module_t; /* Tim: Where is this module struct
>> defined? */
>> typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void
>> *);
>>
>> /*
>>  * Struct for registering modules statically via SYSINIT.
>>  */
>> typedef struct moduledata {
>>         const char      *name;          /* module name */
>>         modeventhand_t  evhand;         /* event handler */
>>         void            *priv;          /* extra data */
>> } moduledata_t;
>>
>> ...snip...
>>
>
> I don't know what's actually being given to the function
> here, but suspect it's that "priv" thing above that is used
> as a pointer to "opaque" module-specific data structure
> that only your module would understand. I might be wrong.
>
> Cheers,
> --
>  Nikolai
>
>
>> #./hello.c
>>
>> ...snip...
>> /* Event Handler */
>> static int
>> load(struct module *module, int cmd, void *arg)
>> {...snip...}
>>
>> /* Module data structure, 2nd argument of DECLARE_MODULE */
>> static moduledata_t hello_mod = {
>>     "hello",
>>     load,
>>     NULL,
>> };
>>
>> DECLARE_MODULE(hello, hello_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);

Also, pointer to anything is still a pointer (4 or 8 byte thing).
So it doesn't matter to a compiler if it knows the exact type
when it sees pointer declaration (it does care when pointer is
being dereferenced though.) Here's a quick example to show this point
(compiles on sparc/solaris with SunStudio11):

#include <stdio.h>

typedef struct booohaaa* booohaaa_t;
typedef int (*boo_f)( booohaaa_t, void* );

int boo_ex( booohaaa_t p, void* ptr )
{
    printf( "boo_ex( %p, %p )\n", p, ptr );
}

int main( int argc, char* argv[] )
{
    boo_f func = boo_ex;

    (*func)( ( void* )0x0000ffff, ( void* )0xffff0000 );

    return 0;
}

Cheers,
--
 Nikolai





More information about the talk mailing list