Pagina 1 di 1

[Kernel]Link e utilizzo di una syscall

Inviato: sab 2 ott 2010, 15:33
da Calzo
Ciao a tutti.
Stavo guardando un po' il kernel e mi stavo chiedendo se è possibile chiamare delle syscall all'interno di un modulo. Per esempio mi chiedevo se è possibile ottenere il pid del processo senza usare la struttura current (giusto per fare un esempio: so che questo non è di nessuna utilità pratica :)).
Nel kernel 2.6 il simbolo sys_call_table non è esportato, mentre la chiamata sys_getpid() lo è. Allora ho provato a scrivere questo modulo:

Codice: Seleziona tutto

/*** PROVA.C ***/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/version.h>

#include <asm/unistd.h>	// contiene i numeri delle chiamate __NR_xxx
#include <asm/page.h>	// per avere le funzioni per la memoria come virt_to_page
#include <asm/linkage.h>
#include <linux/syscalls.h>		// x syscall sys_xxx

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Calzo");

int __init repsys_init_module(void);
void repsys_clenup_module(void);

/* Inizializzazione */
int __init prova_init_module(void)
{
	printk("PID: %d\n", (int)sys_getpid());

	return 0;
}

void prova_clenup_module()
{
}

module_init(prova_init_module);
module_exit(prova_clenup_module);
Compilandolo il risultato è questo:

Codice: Seleziona tutto

make -C /lib/modules/2.6.35.6/build -I /lib/modules/2.6.35.6/build/include M=/home/calzo/kernel modules
make[1]: Entering directory `/usr/src/linux-2.6.35.6'
  CC [M]  /home/calzo/kernel/prova.o
/home/calzo/kernel/prova.c:57: warning: function declaration isn't a prototype
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "sys_getpid" [/home/calzo/kernel/prova.ko] undefined!
  LD [M]  /home/calzo/kernel/prova.ko
make[1]: Leaving directory `/usr/src/linux-2.6.35.6'
Ok, mi dice che sys_getpid() non è definita. Però io non me ne curo perchè da /proc/kallsyms vedo che questa funzione è esportata, e quindi dovrebbe essere noto al kernel dove essa si trova: c102405e T sys_getpid.
Quindi carico il modulo, ma il risultato è questo:

Codice: Seleziona tutto

insmod prova.ko
insmod: error inserting 'prova.ko': -1 Unknown symbol in module
e dal file /var/log/syslog/ leggo

Codice: Seleziona tutto

Oct  2 15:14:18 SkyNet kernel: prova: Unknown symbol sys_getpid (err 0)
Quindi la domanda: dov'è che sbaglio? se il kernel conosce il l'indirizzo della funzione, non dovrebbe assegnarglielo in fase di caricamento del modulo?

grazie

Re: [Kernel]Link e utilizzo di una syscall

Inviato: dom 3 ott 2010, 21:57
da masalapianta
non so cosa effettivamente contenga /proc/kallsyms (è un milione di anni che non scrivo codice kernel, son rimasto a /proc/ksysm), ma risulta ovvio, sia dall'output di insmod che dai sorgenti del kernel (grep non trova alcuna macro EXPORT_SYMBOL() che esporti sys_getpid), che il simbolo non è affatto esportato; il che è abbastanza normale visto che, come hai sottolineato all'inizio, si può ottenere il pid usando current->pid

Re: [Kernel]Link e utilizzo di una syscall

Inviato: dom 3 ott 2010, 22:52
da Calzo
masalapianta ha scritto:non so cosa effettivamente contenga /proc/kallsyms (è un milione di anni che non scrivo codice kernel, son rimasto a /proc/ksysm)
kallsyms è l'equivalente (attuale) di ksym (almeno per quanto ne so io... non è che sono proprio un esperto di kernel... purtroppo).
masalapianta ha scritto:grep non trova alcuna macro EXPORT_SYMBOL() che esporti sys_getpid
Io lo davo per sott'inteso, ma effettivamente è come dici: non viene esportato con la macro EXPORT_SYMBOL. Eppure io vedo il simbolo in kallsyms e l'indirizzo è quello giusto: ho scritto anche un modulo che mi estrae dall'array sys_call_table il puntatore a sys_getpid() ed è lo stesso valore riportato in kallsyms.

Per questo, secondo me, dovrebbe non dovrebbe darmi problami in fase di caricamento del modulo :-k ...o sbaglio (bhè sicuramente sbaglio visto che non lo fa, ma non capisco perchè)

Grazie
bye

Re: [Kernel]Link e utilizzo di una syscall

Inviato: lun 4 ott 2010, 10:42
da masalapianta
Calzo ha scritto:
masalapianta ha scritto:grep non trova alcuna macro EXPORT_SYMBOL() che esporti sys_getpid
Io lo davo per sott'inteso, ma effettivamente è come dici: non viene esportato con la macro EXPORT_SYMBOL. Eppure io vedo il simbolo in kallsyms e l'indirizzo è quello giusto: ho scritto anche un modulo che mi estrae dall'array sys_call_table il puntatore a sys_getpid() ed è lo stesso valore riportato in kallsyms.
come ho premesso, son secoli che non sviluppo codice kernel, quindi non so se oggi è ancora così, ma fino a qualche anno fa l'unico modo per infilare dei simboli in __ksymtab era usando la macro EXPORT_SYMBOL (che, come ho gia detto, stando a grep attualmente non esporta sys_getpid); ovviamente questo vale solo per i moduli, in quanto nel kernel statico per rendere visibile una funzione basta che non sia static (quindi non hai bisogno di conoscere esplicitamente l'indirizzo, come invece avviene per i moduli, per i quali spetta ad insmod risolvere i simboli in indirizzi validi; per questo il tuo modulo compila ma poi da errore in fase di caricamento).
Il fatto che tu riesca in qualche modo a ricavarti l'indirizzo della syscall_table (che oltre ad essere stata spostata in .rodata, non è neanche più esportata, quindi va cercata "a mano") e da li, gli indirizzi di tutte le syscall, è irrilevante, in quanto tu non l'hai trovata perchè il simbolo è esportato, che è l'unico modo che ha insmod per tradurre i simboli in indirizzi.
In sostanza se tra __start___ksymtab e __stop___ksymtab ci sta l'associazione del smbolo di sys_getpid con il suo indirizzo, allora insmod riesce a risolvere il simbolo nel modulo con il suddetto indirizzo, altrimenti no, e l'unico modo standard che io conosca per aggiungere il simbolo è usando EXPORT_SYMBOL, quindi no macro no party.