2010-08-21 06:57:25

by Aijaz Baig

[permalink] [raw]
Subject: help needed with EXPORT_SYMBOL

Hello,

Ive been trying to EXPORT a SYMBOL from a netfilter module (actually a
hook) to the KERNEL. Various modules seem to export various symbols to
the kernel (or so it seems), an example being x_tables which exports a
whole lot of functions like xt_register_target and so on and all other
netfilter modules which use these functions dont seem to have any
problems.

So why is it that when my netfilter module is exporting something to the
kernel and im tryin to use it from within a core kernel file, the
compiler flags a 'undefined reference to' error?

I googled and came to the conclusion from the kernelnewbies mailing list
that using kallsyms_lookup() seems to be the answer or is it?
So, if I do intend to use kallsyms_lookup how do I use it? There aren't
so many instances of it being used it seems.

Ive seen it being used in dev/core.c like so:
symname = kallsyms_lookup((unsigned long)sym, &symsize,&offset,&modname,
namebuf);

I am basically trying to call a function that MY module EXPORTs inside
one of the core linux routines. This would also mean that my netfilter
module must be compiled (and linked also maybe?..not so sound with link
time stuff) before the address becomes visible so that kallsyms_lookup
can find it. So do I really shd be using it and if so, how?

Any input is appreciated.

Regards,
Aijaz Baig.



2010-08-21 09:23:40

by Jan Engelhardt

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

On Saturday 2010-08-21 08:57, Aijaz Baig wrote:

>So why is it that when my netfilter module is exporting something to the
>kernel and im tryin to use it from within a core kernel file, the
>compiler flags a 'undefined reference to' error?

There, you answered yourself. Exports only go one way. And that is
core -> module -> module.

2010-08-23 05:14:22

by Aijaz Baig

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

Hello,

Yeah I do understand that part, but there has to be a way to do what I
am trying to do here isn't it?

And can anyone tell me can kallsyms_lookup() be used in such a
situation? If yes than how do I use it?

Regards,
Aijaz

On Sat, Aug 21, 2010 at 2:53 PM, Jan Engelhardt <[email protected]>
wrote:
On Saturday 2010-08-21 08:57, Aijaz Baig wrote:

>So why is it that when my netfilter module is exporting something to
>the kernel and im tryin to use it from within a core kernel file, the
>compiler flags a 'undefined reference to' error?

There, you answered yourself. Exports only go one way. And that is
core -> module -> module.

On Sat, 2010-08-21 at 12:27 +0530, Aijaz Baig wrote:
> Hello,
>
> Ive been trying to EXPORT a SYMBOL from a netfilter module (actually a
> hook) to the KERNEL. Various modules seem to export various symbols to
> the kernel (or so it seems), an example being x_tables which exports a
> whole lot of functions like xt_register_target and so on and all other
> netfilter modules which use these functions dont seem to have any
> problems.
>
> So why is it that when my netfilter module is exporting something to the
> kernel and im tryin to use it from within a core kernel file, the
> compiler flags a 'undefined reference to' error?
>
> I googled and came to the conclusion from the kernelnewbies mailing list
> that using kallsyms_lookup() seems to be the answer or is it?
> So, if I do intend to use kallsyms_lookup how do I use it? There aren't
> so many instances of it being used it seems.
>
> Ive seen it being used in dev/core.c like so:
> symname = kallsyms_lookup((unsigned long)sym, &symsize,&offset,&modname,
> namebuf);
>
> I am basically trying to call a function that MY module EXPORTs inside
> one of the core linux routines. This would also mean that my netfilter
> module must be compiled (and linked also maybe?..not so sound with link
> time stuff) before the address becomes visible so that kallsyms_lookup
> can find it. So do I really shd be using it and if so, how?
>
> Any input is appreciated.
>
> Regards,
> Aijaz Baig.
>
>


2010-08-23 11:48:12

by Brian Gerst

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

On Mon, Aug 23, 2010 at 1:14 AM, Aijaz Baig <[email protected]> wrote:
> Hello,
>
> Yeah I do understand that part, but there has to be a way to do what I
> am trying to do here isn't it?
>
> And can anyone tell me can kallsyms_lookup() be used in such a
> situation? If yes than how do I use it?
>
> Regards,
> Aijaz
>
> On Sat, Aug 21, 2010 at 2:53 PM, Jan  Engelhardt <[email protected]>
> wrote:
> On Saturday 2010-08-21 08:57, Aijaz Baig wrote:
>
>>So why is it that when my netfilter module is exporting something to
>>the kernel and im tryin to use it from within a core kernel file, the
>>compiler flags a 'undefined reference to' error?
>
> There, you answered yourself. Exports only go one way. And that is
> core -> module -> module.
>
> On Sat, 2010-08-21 at 12:27 +0530, Aijaz Baig wrote:
>> Hello,
>>
>> Ive been trying to EXPORT a SYMBOL from a netfilter module (actually a
>> hook) to the KERNEL. Various modules seem to export various symbols to
>> the kernel (or so it seems), an example being x_tables which exports a
>> whole lot of functions like xt_register_target and so on and all other
>> netfilter modules which use these functions dont seem to have any
>> problems.
>>
>> So why is it that when my netfilter module is exporting something to the
>> kernel and im tryin to use it from within a core kernel file, the
>> compiler flags a 'undefined reference to' error?
>>
>> I googled and came to the conclusion from the kernelnewbies mailing list
>> that using kallsyms_lookup() seems to be the answer or is it?
>> So, if I do intend to use kallsyms_lookup how do I use it? There aren't
>> so many instances of it being used it seems.
>>
>> Ive seen it being used in dev/core.c like so:
>> symname = kallsyms_lookup((unsigned long)sym, &symsize,&offset,&modname,
>> namebuf);
>>
>> I am basically trying to call a function that MY module EXPORTs inside
>> one of the core linux routines. This would also mean that my netfilter
>> module must be compiled (and linked also maybe?..not so sound with link
>> time stuff) before the address becomes visible so that kallsyms_lookup
>> can find it. So do I really shd be using it and if so, how?
>>
>> Any input is appreciated.
>>
>> Regards,
>> Aijaz Baig.
>>
>>

Use an exported function pointer in the main kernel as a hook that the
module sets when it is loaded. Note, you must use module_get and
module_put around the call to the module to prevent it from unloading
while in use.

--
Brian Gerst

2010-08-23 13:18:03

by Peter Zijlstra

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

On Mon, 2010-08-23 at 07:48 -0400, Brian Gerst wrote:
>
> Use an exported function pointer in the main kernel as a hook that the
> module sets when it is loaded. Note, you must use module_get and
> module_put around the call to the module to prevent it from unloading
> while in use.

Please don't do any such thing, its impossible to use correctly.

Suppose there are two modular users, A and B.

Both have something like:

extern void (*fptr)(void);

static void (*old_fptr)(void);

static void func(void)
{
/* foo */
if (old_fptr)
old_fptr();
}

module_init()
{
old_fptr = fptr;
fptr = A_func;
}

Then you load A, load B and unload A, then guess what happens?

2010-08-23 13:32:07

by Jan Engelhardt

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

On Monday 2010-08-23 15:17, Peter Zijlstra wrote:

>On Mon, 2010-08-23 at 07:48 -0400, Brian Gerst wrote:
>>
>> Use an exported function pointer in the main kernel as a hook that the
>> module sets when it is loaded. Note, you must use module_get and
>> module_put around the call to the module to prevent it from unloading
>> while in use.
>
>Please don't do any such thing, its impossible to use correctly.
>
>Suppose there are two modular users, A and B.

Though in case there is just a single user it can work out.
Just like bridge.c, and the bunch of nf_nat_*.c. :-)
Though yeah. Bad bad.

This is starting to sound pretty much like an XY problem: XY problem:
You want to do X, but don't know how. You think you can solve it using
Y, but don't know how to do that, either. You ask about Y, which is a
strange thing to want to do. Just ask about X.

(And then there is still the "good idea to do X in the first place"
thing.) Like what's so important to have as a module when you can build
it in, given that the caller is built-in (obj-y) itself.

>module_init()
>{
> old_fptr = fptr;
> fptr = A_func;
>}
>
>Then you load A, load B and unload A, then guess what happens?
>

2010-08-23 13:43:08

by Peter Zijlstra

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

On Mon, 2010-08-23 at 15:32 +0200, Jan Engelhardt wrote:
> On Monday 2010-08-23 15:17, Peter Zijlstra wrote:
>
> >On Mon, 2010-08-23 at 07:48 -0400, Brian Gerst wrote:
> >>
> >> Use an exported function pointer in the main kernel as a hook that the
> >> module sets when it is loaded. Note, you must use module_get and
> >> module_put around the call to the module to prevent it from unloading
> >> while in use.
> >
> >Please don't do any such thing, its impossible to use correctly.
> >
> >Suppose there are two modular users, A and B.
>
> Though in case there is just a single user it can work out.
> Just like bridge.c, and the bunch of nf_nat_*.c. :-)
> Though yeah. Bad bad.

We have this problem in several areas in the kernel (pm_idle being the
one I hate most since its in code I touch actually grew tons of users).

If you really need to export hooks, provide a registration mechanism and
an arbiter. A very simple, already existing, implementation of this
would be notification chains (include/linux/notifier.h), these provide a
registration interface, and the arbiter is a combination of static
priority combined with return codes.

A more complex example would be the cpuidle/pm_qos subsystem, where you
can register idle states and provide various attributes (exit latency,
energy break even duration, etc) and have the governor pick an idle
state depending on the predicted idle time and required exit latencies.

Bare function pointers suck.

2010-08-23 13:44:30

by Brian Gerst

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

On Mon, Aug 23, 2010 at 9:17 AM, Peter Zijlstra <[email protected]> wrote:
> On Mon, 2010-08-23 at 07:48 -0400, Brian Gerst wrote:
>>
>> Use an exported function pointer in the main kernel as a hook that the
>> module sets when it is loaded.  Note, you must use module_get and
>> module_put around the call to the module to prevent it from unloading
>> while in use.
>
> Please don't do any such thing, its impossible to use correctly.
>
> Suppose there are two modular users, A and B.
>
> Both have something like:
>
> extern void (*fptr)(void);
>
> static void (*old_fptr)(void);
>
> static void func(void)
> {
>        /* foo */
>        if (old_fptr)
>                old_fptr();
> }
>
> module_init()
> {
>        old_fptr = fptr;
>        fptr = A_func;
> }
>
> Then you load A, load B and unload A, then guess what happens?
>

The assumption was that there was a single module using that hook.
For multiple users you'd need to use a register function that adds the
module to a linked list.

--
Brian Gerst

2010-08-23 14:05:49

by Peter Zijlstra

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

On Mon, 2010-08-23 at 09:44 -0400, Brian Gerst wrote:
> The assumption was that there was a single module using that hook.

Not really a future-proof design, is it?

2010-08-24 04:44:26

by Aijaz Baig

[permalink] [raw]
Subject: Re: help needed with EXPORT_SYMBOL

Hello everyone,

thanks for sending in the replies with so many options. I am still a
relative newbie so please do bear with me guys if I sound a bit naive at
times.

I'll first start with brian's suggestion. He said:
"Use an exported function pointer in the main kernel as a hook that the
module sets when it is loaded. Note, you must use module_get and
module_put around the call to the module to prevent it from unloading
while in use."

I have never used such a technique and do not understand what you mean.
Could you please elaborate a little. Do you mean I should NF_HOOK within
the kernel code and then make the function that I would like to execute
as the hookfn? Well..if this is what u meant then wouldn't it also cause
all hooks at that particular position to be executed as well?

And then peter and finally jan came up with, perhaps better suggestions
(i really cannot judge the quality of any of these suggestions..m too
much of a noob to do that). I got confused in the XY explanation by jan
since there both X and Y are modules it seems and I was talking about a
module exporting a certain symbol to be used by the kernel. Peter did
suggest notification chains. Is there a simple example that I can look
at? Will it allow the kernel to see symbols defined within the module?

Lastly, will I be able to use kallsyms_lookup() to do what I can? I
notice that it replaced EXPORT_SYMTAB sometime back. So if yes I can use
it, does anyone know how to fill in the very first parameter of this
function which says address (of what exactly and how am I supposed to
know this address?)

Keen to hear from you and once again, thank you for your inputs,

Regards,
Aijaz Baig.