[Kernel]Link e utilizzo di una syscall

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
Calzo
Linux 1.x
Linux 1.x
Messaggi: 112
Iscritto il: sab 6 ott 2007, 22:21
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE
Località: MN

[Kernel]Link e utilizzo di una syscall

Messaggio 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

Avatar utente
masalapianta
Iper Master
Iper Master
Messaggi: 2775
Iscritto il: lun 25 lug 2005, 0:00
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian
Località: Roma
Contatta:

Re: [Kernel]Link e utilizzo di una syscall

Messaggio 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

Avatar utente
Calzo
Linux 1.x
Linux 1.x
Messaggi: 112
Iscritto il: sab 6 ott 2007, 22:21
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE
Località: MN

Re: [Kernel]Link e utilizzo di una syscall

Messaggio 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

Avatar utente
masalapianta
Iper Master
Iper Master
Messaggi: 2775
Iscritto il: lun 25 lug 2005, 0:00
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian
Località: Roma
Contatta:

Re: [Kernel]Link e utilizzo di una syscall

Messaggio 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.

Rispondi