Repository 32bit  Forum
Repository 64bit  Wiki

[Kernel]Link e utilizzo di una syscall

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata e la versione del Kernel. Questi dati aiutano le persone che possono rispondere.
2) Specificare sempre il tipo di shell (bash, sh, csh, etc...)
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 dell'ultima regola porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

[Kernel]Link e utilizzo di una syscall

Messaggioda Calzo » sab ott 02, 2010 15:33

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
Calzo
Linux 2.0
Linux 2.0
 
Messaggi: 112
Iscritto il: sab ott 06, 2007 22:21
Località: MN
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE

Re: [Kernel]Link e utilizzo di una syscall

Messaggioda masalapianta » dom ott 03, 2010 21:57

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
masalapianta
Iper Master
Iper Master
 
Messaggi: 2358
Iscritto il: lun lug 25, 2005 0:00
Località: Roma
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian

Re: [Kernel]Link e utilizzo di una syscall

Messaggioda Calzo » dom ott 03, 2010 22:52

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
Calzo
Linux 2.0
Linux 2.0
 
Messaggi: 112
Iscritto il: sab ott 06, 2007 22:21
Località: MN
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE

Re: [Kernel]Link e utilizzo di una syscall

Messaggioda masalapianta » lun ott 04, 2010 10:42

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.
Avatar utente
masalapianta
Iper Master
Iper Master
 
Messaggi: 2358
Iscritto il: lun lug 25, 2005 0:00
Località: Roma
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 0 ospiti