|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
Problemi con netlink
mentre cercavo di capire come usare connector ho trovato un articolo su netlink che mi sembrava molto chiaro.
ho provato a implementarlo per comunicare una piccola stringa in userspace, ma ci sono ENORMI problemi ![]() al caricamento del modulo parte (tra le altre che però sono di certo corrette) questo: Codice:
static void create_socket(){ int err; nl_sk = netlink_kernel_create(NETLINK_MINOX, 1, nl_data_ready, THIS_MODULE); skb = skb_recv_datagram(nl_sk, 0, 0, &err); nlh = (struct nlmsghdr *)skb->data; pid = nlh->nlmsg_pid; } comuque è definita così: Codice:
static void nl_data_ready (struct sock *sk, int len) { wake_up_interruptible(sk->sk_sleep); } Codice:
static int negotiate_auth(u32 app_pid, int auth_type){ char buf[MAX_PAYLOAD]; int err; snprintf(buf, MAX_PAYLOAD, "%d", app_pid/*, auth_type*/); if(nlh != NULL && skb != NULL){ strcpy(NLMSG_DATA(nlh), buf); NETLINK_CB(skb).pid = 0; NETLINK_CB(skb).dst_pid = pid; NETLINK_CB(skb).dst_group = 0; netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT); skb = skb_recv_datagram(nl_sk, 0, 0, &err); if(skb != NULL){ nlh = (struct nlmsghdr *)skb->data; if(strcmp(NLMSG_DATA(nlh), ACCESS_PERMITTED) == 0){ return 0; } } } return -EPERM; } il problema è che quando un processo apre una socket viene rilevato, e viene inviato il pid copiato due volte di seguito. nel frattempo il programma che apre la socket va in segmentation fault, e dmesg si lamenta di aver trovaoto un puntatore nullo... io ho cercato, ma nel mio codice non ne trovo... qualcuno con più esperienza di me a usare netlink mi può dare una mano? grazie, ciao! |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
su che siete capaci...
![]() |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Puoi postare del codice minimale compilabile per riprodurre il problema?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
appena torno a casa metto tutto il codice.
comunque il resto e` abbastanza banale. il codice che esegue durante l'errore non fa altro che controllare che la connessione sia af_inet, dopo di che restituisce la negotiate (passando come parametri current-->pid e un enum). la funzione e` chiamata utilizzando il linux security framework (anche se mi sa che alcune cose di selinux mi verrebbero piu` comode che non lfs), aganciandosi alla chiamata di creazione di socket. ciao! |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
mmmmmh... insospettito dalla doppia scritta del pid ho tolto la sprintf e sembra andare tutto...
non posso usare le funzioni standard nei moduli? ora la ho sostituita con una memcopy di una struttura e sembra andare. ah, ultima cosa... quando lancio il modulo compare questa linea su dmesg... Codice:
assertion (!atomic_read(&sk->sk_rmem_alloc)) failed at net/netlink/af_netlink.c (145) quanto mi devo preoccupare? ![]() ho trovato questa patch http://www.uwsg.iu.edu/hypermail/lin...03.3/0033.html mi posso fidare? grazie di nuovo ![]() ciao! |
![]() |
![]() |
![]() |
#6 | |||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Quote:
Quote:
ciao!
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|||
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
Quote:
ma non c'e`... ho controllato sul 2.6.16.20, non risulta applicata ![]() |
|
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
Quote:
mmmmh... hai delle letture da consigliarmi? mi sono letto quasi tutto linux kernel internal, ma non ne parla. ciao |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Allora forse non è più necessaria.
Comunque se fosse un problema così comune sarebbe noto; più facile che c'è qualche errore nel tuo codice.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
velocita impressionante
![]() vedro` di risolvere ![]() e per la seconda domanda? ![]() ![]() edit: ho trovato tal struct_copy che ho sostituito alla memcpy, ma se hai delle indicazioni la domanda rimane valida per avere un riferimento pper altri casi ![]() Ultima modifica di NA01 : 20-06-2006 alle 14:43. |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
cat NA01_br0ken_module.c
cat: NA01_br0ken_module.c: No such file or directory
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
Quote:
![]() ![]() mi sa che non ho capito ![]() |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
-ENOENT
'ndo stanno i sorgenti che ti ho chiesto?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
mmmmh... già
![]() tolte tuuuuttte le chiamate di libreria sembra andare in modo abbastanza stabile. l'ultimo problema lo avevo causato io da idiota. controllavo tutte le creazioni di socket, comprese le netlink. quindi provava a controllarsi da solo, e si comportava in modo abbastanza casuale. il link al download te lo ho messo qui apposta per te (sei commosso? ![]() www.minox.altervista.org/download.html gli occhi del grande ilsensine sul codice sono sempre i benvenuti, anche perchè non ho mai scritto roba del genere ![]() ha bisogno del linux security framework compilato come modulo (altrimenti si arrabbia davvero tanto ![]() per sostituire la memcpy avevo trovato la struct_cpy, ma sembra che sia saltata allegramente per problemi di portabilità ![]() si consigliava di usare memcpy, e effettivamente non sembra dare problemi. l'altra cosa che mi è rimasta da sistemare è che se il demone secca il modulo non sa più fare nulla (e questo è ok), ma nemmeno riaccettare un'altra connessione (e questo è un pò meno ok ![]() bho, comunque sia suppongo di poter trovare una soluzione. il client invece è ancora incasinato. ho la versione semi funzionante che si andava a cercare il processo partendo dagli idirizzi di connessione tutto in userspace (che però era lento lento, in quanto doveva controllare tutto a ogni pacchetto), e ora devo sistemarlo per farlo andare con netlink (e dovrebbe essere molto più veloce dato che deve controllare solo sull'apertura della socket). metto qui la versione scritta a babbo con vari copia e incolla a caso per provare il modulo: il file netlink incluso differisce dall'originale solo per questa riga: #define NETLINK_MINOX 19 Codice:
#include <stdio.h> #include <linux/init.h> #include <linux/un.h> #include <sys/un.h> #include <sys/socket.h> #include "/usr/src/linux-2.6.16.20/include/linux/netlink.h" #define MAX_PAYLOAD 1024 struct sockaddr_nl src_addr, dst_addr; struct nlmsghdr *nlh = NULL; struct msghdr msg; struct iovec iov; int sock_fd; struct Query{ int app_pid; int request; }; int main() { int app_pid, auth_type; sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_MINOX); memset(&src_addr, 0, sizeof(src_addr)); src_addr.nl_family = AF_NETLINK; src_addr.nl_pid = getpid(); src_addr.nl_groups = 0; bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); memset(&dst_addr, 0, sizeof(dst_addr)); dst_addr.nl_family = AF_NETLINK; dst_addr.nl_pid = 0; dst_addr.nl_groups = 0; nlh = (struct nlhmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; strcpy(NLMSG_DATA(nlh), "Register"); iov.iov_base = (void *)nlh; iov.iov_len = nlh->nlmsg_len; msg.msg_name = (void *)&dst_addr; msg.msg_namelen = sizeof(dst_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; sendmsg(sock_fd, &msg, 0); while(1){ int perm = 1; fprintf(stderr,"In Attesa...\n"); recvmsg(sock_fd, &msg, 0); fprintf(stderr,"Comunicazione: pid: %d --- %d\n", (*((struct Query*)((NLMSG_DATA(nlh))))).app_pid , (*((struct Query*)((NLMSG_DATA(nlh))))).request); memcpy(NLMSG_DATA(nlh), &perm, sizeof(int)); iov.iov_base = (void *)nlh; iov.iov_len = nlh->nlmsg_len; msg.msg_name = (void *)&dst_addr; msg.msg_namelen = sizeof(dst_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; sendmsg(sock_fd, &msg, 0); } memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); recvmsg(sock_fd, &msg, 0); printf("Received message payload: %d\n", NLMSG_DATA(nlh)); close(sock_fd); return 0; } grazie, ciao! Ultima modifica di NA01 : 20-06-2006 alle 22:12. |
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
C'è ben poco in quel sorgente; comunque...
Codice:
nl_sk = netlink_kernel_create(NETLINK_MINOX, 1, nl_wait, THIS_MODULE); skb = skb_recv_datagram(nl_sk, 0, 0, &err); Codice:
netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT); Codice:
skb = skb_recv_datagram(nl_sk, 0, 0, &err); Poi, ho visto che nei sorgenti non è più presente questa chicca: Codice:
static int negotiate_auth(u32 app_pid, int auth_type){ char buf[MAX_PAYLOAD]; ... Quote:
Inizialmente falla semplice; visto che un programma per aprire una connessione netlink ha comunque bisogno dei privilegi di root, potresti inizialmente trascurare la forzatura di dover conoscere il pid del demone. Semplicemente, invia il messaggio netlink; se un demone c'è (netlink_has_listeners) riceverai risposta (metti sempre un timeout -- hint: poll); altrimenti fai una azione di default. Ultima cosa -- ho paura che in release il modulo va marcato come "permanente". Non credo possa essere rimosso con sicurezza, una volta caricato.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#16 | ||||
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
Quote:
![]() e` semplicissimo rispetto agli infiniti giri che devi fare in userspace per risalire al pid che ha creato il pacchetto. senza contare che in questo modo devi controllare solo le creazioni delle socket ![]() Quote:
![]() no, scherzo. non doveva nemmeno essere pubblicato, semplicemente volevo vedere se era davvero cosi` semplice. Quote:
![]() nono, era solo la cosa piu` veloce che mi era venuta in mente ![]() avevo appena cancellato tutta la parte di comunicazione precedente, e mi ero accorto che non avevo copie i backup ![]() volevo essere certo di non aver fatto una cavolata il piu` presto possibile Quote:
![]() ti faccio la solita domanda... dove trovo della documentazione su netlink? ho cercato netlink samples e netlink howto su google, ma ho trovato solo un esempietto di unicast e multicast da cui ho tirato fuori questo... grazie, ciao! |
||||
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
![]()
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
ah, niente riassunto
![]() come libro e` un po` esteso ![]() sul serio non esiste nulla? ![]() terribili sti programmatori ![]() |
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Non c'è grande interesse a scrivere documentazione per netlink; è una tecnica vecchia (quindi anche piena di esempi) e non accettata come utilizzo "general purpose", per il quale è stato sviluppato il connector.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Jun 2003
Città: Genova
Messaggi: 5676
|
ok, lo prendo come un consiglio di passare a connector
![]() rinizio a leggere la documentazione allora. intanto sono abituato a riscrivere tutto... prima era in c e si appoggiava alla tua patch poi e` rimasto in c, ma appoggiato a iptables poi mi faceva schifo e lo ho riscritto in c++ (e ho buttato via un 5000 righe, o quantomeno le ho modificate pesantemente) poi era lento a controllare tutto dato che calcolava gli md5 a ogni pacchetto e sono passato al modulo che comunicava con af_unix (e sono andate via migliai a di righe...) poi mi sono preso degli insulti e sono passato a netlink... e ora communicator? perche` no :-D tutta esperienza ![]() ciaaaaao! |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 18:59.