elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Sigue las noticias más importantes de seguridad informática en el Twitter! de elhacker.NET


  Mostrar Temas
Páginas: [1]
1  Programación / Programación C/C++ / Módulo del kernel que interactúa con llamada al sistema (C) en: 30 Noviembre 2013, 12:55 pm
Buenas, estoy programando un módulo propio para el kernel de linux (Estoy trabajando sobre debian 6 con kernel 2.6.39.4) que interactúa con una llamada al sistema. Son dos muy sencillos. La llamada funciona perfectamente y exporta funcionalidad que permite a un módulo insertarse en una lista de entradas y registrar en ella dos funciones, una de escritura y otra de lectura.

El módulo es un contador, y las funciones de lectura y escritura son la suma del contador y la consulta del número actual. Su escritura sólo suma si todo va bien, y su lectura devuelve en el buffer del usuario la copia del valor. El problema es que al hacer el makefile del módulo recibo el error:

Citar
"insmod: error inserting 'ModuloUsaKifs.ko': -1 Unknown symbol in module"

Y no sé exáctamente por qué no reconoce Kifs, que según creo, está integrado en el sistema correctamente (Incluidas las fuentes, modificado el planificador, añadido a la tabla de llamadas, incluida la cabecera, compilado el kernel, instalado el nuevo, y probado con un programa aparte, aunque sólo pruebo sys_kifs, mi llamada al sistema, exporto también create_kifs_entry y remove_kifs_entry mediante <linux/kifs.h>)
Este es mi makefile, es muy estándar y no contemplo nada especial, porque se supone que kifs ya está en las fuentes de linux y así lo incluyo en el módulo.
¿Podría alguien orientarme hacia dónde está mi fallo?

Citar
obj-m = ModuloUsaKifs.o

all :
   make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean :
   make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


Este es el módulo. Siento la falta de comentarios, todavía no lo he acabado y está un poco guarro(Esto es como tener visita con la casa sucia) Tengo algunos includes de más porque aún no los he borrado, he reutilizado algo de código de aquí y allá.
Código
  1. #ifdef __KERNEL__
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/proc_fs.h>
  5. #include <linux/string.h>
  6. #include <linux/vmalloc.h>
  7. #include <linux/kifs.h>
  8. #include <asm-generic/uaccess.h>
  9. MODULE_LICENSE("GPL");
  10. MODULE_DESCRIPTION("List Kernel Module para DSO");
  11. MODULE_LICENSE("GPL");
  12. #else
  13. //#include <iostream>
  14. //#include <linux/list.h>
  15. #include <string.h>
  16. #include "list.h"
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "kifs.h"
  20. #endif
  21. int counter;
  22. //typedef int (read_kifs_t)(char *user_buffer, unsigned int maxchars, void *data);
  23. //typedef int (write_kifs_t)(const char *user_buffer, unsigned int maxchars, void *data);
  24. //initialices the module
  25. int sum(char *user_buffer, unsigned int maxchars, void *data){
  26. counter++;
  27. return maxchars;
  28. }
  29. int lect(const char *user_buffer, unsigned int maxchars, void *data){
  30. char buf[32];
  31. int len=sprintf(buf,"%d\n",counter);
  32. if (len> maxchars)
  33. {
  34. return -EINVAL;
  35. }
  36. if(copy_to_user(buf, user_buffer, len)){
  37. printk(KERN_ALERT) "problemas en lect";
  38. return -EINVAL;
  39. }
  40. return len;
  41.  
  42. }
  43.  
  44. int metodoInicial(void){
  45.  
  46. counter = 0;
  47. if(create_kifs_entry("counter",sum,lect,NULL))
  48. {
  49. counter = 0;
  50. printk(KERNEL_ALERT "modulo abierto correctamente");
  51. }
  52. printk(KERNEL_ALERT "Error, módulo counter incorrectamente agregado a kifs");
  53. }
  54.  
  55. void metodoFinal(void){
  56.  
  57. if(remove_kifs_entry("counter")){
  58. printk(KERNEL_ALERT "modulo cerrado correctamente");
  59. }
  60. printk(KERNEL_ALERT "Error, módulo counter incorrectamente borrado de kifs");
  61. }
  62.  
  63. module_init(metodoInicial);
  64. module_exit(metodoFinal);
  65.  


Esta es la llamada al sistema, por si pudiese ser algo relacionado con esto, sinceramente ya no sé qué puede ser porque me estoy volviendo loco.
Código
  1. #include <linux/kifs.h>
  2. #include <linux/string.h>
  3. #include <linux/module.h>
  4. #include <linux/kernel.h>
  5. #include <asm-generic/errno-base.h>
  6. #include <asm-generic/errno.h>
  7. #include <asm-generic/uaccess.h>
  8. /*
  9. MODULE_LICENSE("GPL");
  10. MODULE_DESCRIPTION("Modulo KIFS para DSO");
  11. MODULE_AUTHOR("Ismel Gonjal Montero");
  12. */
  13. /* Callback prototypes for kifs entries */
  14.  
  15. /*
  16. typedef int (read_kifs_t)(char *user_buffer, unsigned int maxchars, void *data);
  17. typedef int (write_kifs_t)(const char *user_buffer, unsigned int maxchars, void *data);
  18. */
  19.  
  20. /*     Valores de lectura y escritura */
  21.  
  22. /*
  23. enum {
  24. KIFS_READ_OP=0,
  25. KIFS_WRITE_OP,
  26. KIFS_NR_OPS};
  27. */
  28. /***********************************/
  29. /*      Declaraciones de kifs      */
  30. /***********************************/
  31. #define MAX_KIFS_ENTRIES 10
  32. LIST_HEAD(entry_list);
  33. LIST_HEAD(free_list);
  34. kifs_entry_t pool[MAX_KIFS_ENTRIES];
  35.  
  36. /***********************************/
  37. /*   Declaraciones de clipboard    */
  38. /***********************************/
  39. #define MAX_KIFS_CHARS 512
  40. char clipboard[MAX_KIFS_CHARS];
  41. /************************************/
  42. /*    Declaracion de funciones    */
  43. /************************************/
  44. int read_list (char *user_buffer, unsigned int maxchars, void *data);
  45.  
  46.  
  47. /******************************************************************************/
  48. /*                           CLIPBOARD                                        */
  49. /******************************************************************************/
  50.  
  51.  
  52. int read_clipboard (char *user_buffer, unsigned int maxchars, void *data){
  53. int total = strlen(clipboard);
  54.  
  55. if (total>maxchars)
  56. {
  57. return  -EINVAL;
  58. }
  59.  
  60. if (copy_to_user(user_buffer, clipboard, total))
  61. {
  62. printk(KERN_ALERT "Fallo en copy_to_user()");
  63. return  -EINVAL;
  64. }
  65. return total;
  66. }
  67.  
  68. int write_clipboard (const char *user_buffer, unsigned int maxchars, void *data){
  69.  
  70. if (maxchars>MAX_KIFS_CHARS-1)
  71. {
  72. printk(KERN_ALERT "Excede tamanio");
  73. return  -EINVAL;
  74. }
  75.  
  76. if (copy_from_user(clipboard, user_buffer, maxchars))
  77. {
  78. printk(KERN_ALERT "Fallo en copy_from_user()");
  79. return  -EINVAL;
  80. }
  81. clipboard[maxchars]='\0';
  82.  
  83. return  maxchars;
  84. }
  85.  
  86.  
  87.  
  88. /****************************************************/
  89. /*     Código de KIFS    */
  90. /****************************************************/
  91.  
  92.  
  93. /* KIFS's global initialization */
  94. void init_kifs_entry_set(void){
  95. int i = 0;
  96. //añade a la lista todas las entradas de freelist
  97. for(i =0; i<MAX_KIFS_ENTRIES;i++){
  98. list_add_tail(&pool[i].links,&free_list);
  99. }
  100. clipboard[0]='\0';
  101. create_kifs_entry("list", read_list,NULL,NULL);
  102. create_kifs_entry("clipboard", read_clipboard,write_clipboard ,NULL);
  103. printk(KERN_ALERT "Inicializado kifs");
  104. }
  105.  
  106. /*
  107.  * Recibe un buffer de usuario, que llenará con una lista de las entradas
  108.  * de la lista entry_list
  109.  */
  110. int read_list (char *user_buffer, unsigned int maxchars, void *data){
  111. int total = 0;
  112. char buf[512];
  113. struct list_head* pos = entry_list.next;
  114. kifs_entry_t* item;
  115.  
  116. printk(KERN_ALERT "Entra en read_list");
  117.  
  118. list_for_each(pos, &entry_list){
  119. item = list_entry(pos, kifs_entry_t, links);
  120. total+= sprintf(&buf[total],"%s\n",item->entryname);
  121. }
  122.  
  123. if (copy_to_user(user_buffer,buf,total))
  124. {
  125. printk(KERN_ALERT "Fallo en copy_to_user()");
  126. return -EINVAL;
  127. }
  128.  
  129. printk(KERN_ALERT "Sale de read_list por las buenas");
  130. return total;
  131. }
  132.  
  133. /* This fuction must ensure that no entry will be created as long as another entry with the same name already exists.
  134.  * == Return Value ==
  135.  * NULL Entry name already exists or No space is availables
  136.  * Pointer to the kifs entry
  137.  * */
  138. kifs_entry_t* create_kifs_entry(const char* entryname,
  139. read_kifs_t *read_kifs,
  140. write_kifs_t *write_kifs,
  141. void* data){
  142. kifs_entry_t* item;
  143. struct list_head* pos = entry_list.next;
  144. kifs_entry_t* itemFound = NULL;
  145.  
  146. printk(KERN_ALERT "Creando entrada %s en Kifs",entryname);
  147.  
  148. //Si la lista no está vacía
  149. list_for_each(pos, &entry_list){
  150. item = list_entry(pos, kifs_entry_t, links);
  151. if (strcmp(item->entryname,entryname) ==0){
  152. itemFound = item;
  153. break;
  154. }
  155. }
  156. if (itemFound != NULL) {
  157. printk(KERN_ALERT "El item existe");
  158. return NULL;
  159. }
  160.  
  161. //No hay espacio
  162. if(free_list.next == &free_list) {
  163. printk(KERN_ALERT "Error, lista llena");
  164. return NULL;
  165. }
  166. pos = free_list.next;
  167. item = list_entry(pos, kifs_entry_t, links);
  168. item->read_kifs = read_kifs;
  169. item->write_kifs = write_kifs;
  170. item->data = NULL;
  171. strcpy(item->entryname, entryname);
  172.  
  173. list_del(pos);
  174. list_add_tail(pos,&entry_list);
  175. printk(KERN_ALERT "Entrada %s creada correctamente", entryname);
  176. return item;
  177. }
  178.  
  179.  
  180. /*  Implementation of kifs() system call
  181.  * == Return Value ==
  182.  * -EINVAL Unsupported operation (NULL callback) or Entry not exists
  183.  * -EFAULT Any other error (e.g: copy_from_user(), copy_to_user(),...)
  184.  * otherwise: Number of chars read/written (Usually maxchars value)
  185.  */
  186.  
  187. asmlinkage long sys_kifs(const char* entry_name,unsigned int op_mode, char* user_buffer,unsigned int maxchars){
  188.  
  189. struct list_head* pos;// = entry_list.next;
  190. kifs_entry_t* item;// = list_entry(pos, kifs_entry_t, links);
  191. kifs_entry_t* itemFound = NULL;
  192. int ret = 0;
  193. //char usrBfr[512];
  194.  
  195. printk(KERN_ALERT "Entrado a sys_kifs");
  196. /* Se comprueba que la llamada has sido correcta */
  197. list_for_each(pos, &entry_list){
  198. item = list_entry(pos, kifs_entry_t, links);
  199. if (strcmp(item->entryname,entry_name) ==0){
  200. itemFound = item;
  201. break;
  202. }
  203. }
  204.  
  205. if (itemFound == NULL){
  206. printk(KERN_ALERT "La entrada %s no existe", entry_name);
  207. return -EINVAL;
  208. }
  209.  
  210. /* copy_from_user(usrBfr, user_buffer, maxchars);
  211. usrBfr[maxchars]='\0';
  212.  
  213. printk(KERN_ALERT "Se ha copiado el parametro %s de la entrada %s",usrBfr, entry_name);
  214.  
  215. printk(KERN_ALERT "Hay items en la lista");
  216. */
  217. /* llamadas que dependen del valor de lectura/escritura */
  218. if(op_mode == KIFS_READ_OP &&  item->read_kifs!=NULL ){
  219. ret = itemFound->read_kifs(user_buffer,maxchars,NULL);
  220. //printk(KERN_ALERT "El item utilizado es %s, en el método de lectura",user_buffer);
  221. }else if(op_mode == KIFS_WRITE_OP &&  item->write_kifs!=NULL ){
  222. ret = itemFound->write_kifs(user_buffer,maxchars,NULL); //No sé qué pasar de valor aquí
  223. //printk(KERN_ALERT "El item utilizado es %s, en el método de escritura",usrBfr);
  224. }else{
  225. ret=-EINVAL;
  226. printk(KERN_ALERT "Algo va mal");
  227. }
  228. return ret;
  229. }
  230.  
  231. /* Remove kifs entry
  232.  * == Return Value ==
  233.  * -1 Entry does not exist
  234.  *  0 success
  235.  * */
  236. int remove_kifs_entry(const char* entry_name){
  237.  
  238. struct list_head* pos = entry_list.next;
  239. kifs_entry_t* item = list_entry(pos, kifs_entry_t, links);
  240. kifs_entry_t* itemFound = NULL;
  241. printk(KERN_ALERT "Intentando eliminar entrada de Kifs");
  242.  
  243. list_for_each(pos, &entry_list){
  244. item = list_entry(pos, kifs_entry_t, links);
  245. if (strcmp(item->entryname,entry_name) ==0){
  246. itemFound = item;
  247. break;
  248. }
  249. }
  250. if (itemFound == NULL) {
  251. printk(KERN_ALERT "La lista de kifs está vacía");
  252. return -EINVAL;
  253. }
  254.  
  255. list_del(pos);
  256. item->data = NULL;
  257. strcpy(item->entryname,"");
  258. item->read_kifs = NULL;
  259. item->write_kifs = NULL;
  260. list_add_tail(pos,&free_list);
  261. printk(KERN_ALERT "Entrada eliminada correctamente");
  262. return 0;
  263. }
  264.  

Y por si acaso también subo el .h de kifs, mi llamada al sistema.

Código
  1. #ifndef KIFS_H
  2. #define KIFS_H
  3. #include <linux/list.h> /* list_head */
  4.  
  5. #define MAX_KIFS_ENTRY_NAME_SIZE 50
  6.  
  7. /* Callback prototypes for kifs entries */
  8. typedef int (read_kifs_t)(char *user_buffer, unsigned int maxchars, void *data);
  9. typedef int (write_kifs_t)(const char *user_buffer, unsigned int maxchars, void *data);
  10.  
  11.  
  12. /* Descriptor interface for the entries */
  13. typedef struct
  14. {
  15. char entryname[MAX_KIFS_ENTRY_NAME_SIZE];
  16. read_kifs_t *read_kifs;
  17. write_kifs_t *write_kifs;
  18. void *data;
  19. struct list_head links; /* Set of links in kifs */
  20. }kifs_entry_t;
  21.  
  22. enum {
  23. KIFS_READ_OP=0,
  24. KIFS_WRITE_OP,
  25. KIFS_NR_OPS};
  26.  
  27.  
  28. /* This fuction must ensure that no entry will be created as long as another entry with the same name already exists.
  29.  * == Return Value ==
  30.  * NULL Entry name already exists or No space is availables
  31.  * Pointer to the kifs entry
  32.  * */
  33. kifs_entry_t* create_kifs_entry(const char* entryname,
  34. read_kifs_t *read_kifs,
  35. write_kifs_t *write_kifs,
  36. void* data);
  37.  
  38.  
  39. /* Remove kifs entry
  40.  * == Return Value ==
  41.  * -1 Entry does not exist
  42.  *  0 success
  43.  * */
  44. int remove_kifs_entry(const char* entry_name);
  45.  
  46. /*  Implementation of kifs() system call
  47.  * == Return Value ==
  48.  * -EINVAL Unsupported operation (NULL callback) or Entry not exists
  49.  * -EFAULT Any other error (e.g: copy_from_user(), copy_to_user(),...)
  50.  * otherwise: Number of chars read/written (Usually maxchars value)
  51.  */
  52. asmlinkage long sys_kifs(const char* entry_name,unsigned int op_mode, char* user_buffer,unsigned int maxchars);
  53.  
  54. /* KIFS's global initialization */
  55. void init_kifs_entry_set(void);
  56.  
  57.  
  58. #endif

Muchas gracias por vuestro tiempo



Para ser concretos el mensaje del sistema es:
Citar


make -C /lib/modules/2.6.39.4.mikernel/build M=/home/dsouser/Escritorio/FuturaEntrega/ModuloUsaKifs modules
make[1]: se ingresa al directorio `/usr/src/linux-headers-2.6.39.4.mikernel'
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "create_kifs_entry" [/home/dsouser/Escritorio/FuturaEntrega/ModuloUsaKifs/ModuloUsaKifs.ko] undefined!
WARNING: "remove_kifs_entry" [/home/dsouser/Escritorio/FuturaEntrega/ModuloUsaKifs/ModuloUsaKifs.ko] undefined!
make[1]: se sale del directorio `/usr/src/linux-headers-2.6.39.4.mikernel'


2  Programación / Programación C/C++ / Intersección de recta y punto en: 21 Noviembre 2013, 17:30 pm
Buenas, estoy trabajando en informática gráfica, concretamente usando OpenGL aunque eso da igual. Tengo un vector bidimensional (i,j) y puntos bidimensionales(x,y). con ellos genero un triángulo de tres puntos (ABC), que también indican cuál es la cara externa (El vector perpendicular hacia fuera de los puntos AB, BC y CA), aparte tengo un punto que avanza por la escena con una velocidad que marca un tercer vector (vec).

Necesito calcular:

a) Si vec interseca con alguna de las aristas del triángulo ABC

b) Si interseca, en qué punto se produce la intersección.

Muchas gracias
3  Programación / Programación C/C++ / List iterator not decrementable en: 2 Noviembre 2013, 11:54 am
Buenas, estoy haciendo un programa que crea un objeto, y cuando se pulsa una tecla, anida dos objetos por cada uno de los objetos creados en el último anidamiento, de modo que en el nivel 1 tendré 1 objeto, en el 2, 3 objetos, en el 3, tendré 7...

de modo que cada iteración tiene (iteraciónAnterior*2) objetos, y tengo un problema, pues a la hora de desanidar habiendo objetos, me salta un error

El error que me da es
Debug Assertion Failed!

Program: [archivoPrograma]\Debug\freeglut project 2D.exe(mi archivo)
File: c:\visual studio 2010\vc\include\list (cuando yo utilizo 2012, aunque tengo instalado el 2010)
line 256

Expression: list iterator not decrementable


[...]

El código es el siguiente

Código:
void Arbol::desanidar(void){
int i = -1;
while(!poranidar.empty()){
poranidar.pop_front();
i++;
}
if (i!= -1){
for (int j=0;j<=i/2;i++){
poranidar.push_front(archivados.back());
archivados.pop_back();
}
}
}
4  Programación / Programación C/C++ / Error al coger coordenadas del ratón con FreeGlut en: 29 Octubre 2013, 19:30 pm
Buenas, estoy haciendo un proyecto 2d en FreeGlut con C++ y tengo un problema, cuando hago click en una zona, las coordenadas que coge no son las que debería, son de unos 10 píxeles más abajo, pero la cosa es que cuando redimensiono el área visible de la escena haciendo zoom, se descuadra la selección. Estoy calculándola mediante porcentajes, pero no doy con ello, mi código es este:

Código:
void mouse(int button, int state, int x, int y) {
    if (button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) {
// trasladarEscena('N',10);
//repaint();
//Si no había iniciado, se inicia
if (!started){
  pintarInicial(x,y);
  repaint();
//   glutPostRedisplay();

} else{
square_x = xLeft + (x)*(abs(xRight)+abs(xLeft))/WIDTH;
square_y = yBot + (HEIGHT-y)* abs(yTop)+abs(yBot))/HEIGHT;
selection = Punto(square_x,square_y);
selection_enabled = true;
}
}
   
}

Gracias.
5  Programación / Programación C/C++ / Problemas con Proc en el kernel de linux en: 24 Octubre 2013, 19:16 pm
Buenas, estoy haciendo un módulo que sea una lista de enteros que se actualice cada vez que se actualiza una entrada en proc en concreto /proc/mimod. El caso es que compila y lo instalo en el kernel, y cuando quiero utilizar un comando, (Sólo acepta dos, add y remove), de la forma

Código:
echo add 10 > /proc/mimod

Estalla(NullPointerException). No sé muy bien cómo funciona aún. Aquí asigno los callback

Código:
static int addProcEditor(void){
    clipboard = (char *)vmalloc( BUFFER_LENGTH );
    if (!clipboard) {
      ret = -ENOMEM;
    } else {
      memset( clipboard, 0, BUFFER_LENGTH );
      proc_entry = create_proc_entry("mimod",0777, NULL);
      if (proc_entry == NULL) {
        ret = -ENOMEM;
        vfree(clipboard);
        printk(KERN_INFO "modlist: No puedo crear la entrada en proc\n");
      } else {
        posicionactual=0;
       [glow=red,2,300] proc_entry->read_proc = procWritten;
        proc_entry->write_proc = procIsRead;[/glow]
        printk(KERN_INFO "modlist: Cargado el Modulo.\n");
      }
    }
    return 0;
}

Aquí hago las lecturas y escrituras:

Código:
//Reconoce el cambio del proc y ejecuta este programa
int procWritten( struct file *punterofichero, const char __user *bufferusuario,
unsigned long longitud, void *data){
  char* str;
  int espaciodisponible = (BUFFER_LENGTH-posicionactual)+1;

  if (longitud > espaciodisponible) {
    printk(KERN_INFO "mimod: el buffer esta lleno!\n");
    return -ENOSPC;
  }
  if (copy_from_user( &str[0], bufferusuario, longitud )) {
    return -EFAULT;
  }
  clipboard[longitud] = 0;
  int num;
  int i = reconocedor(clipboard,&num);
  switch(i){
  case 1://add
 add(num);
 break;
  case 2://remove
 myremove(num);
 break;
  }

  return longitud;

}
//Escribe en proc lo que deseemos
int procIsRead( char *buffer, char **bufferlocation, off_t offset,
                   int buffer_lenghth, int *eof, void *data )

{
  int len;

  if (offset > 0) {
    /* hemos llegado al final */
    *eof = 1;
    len =0;
  } else {
 len = cats(buffer);
 int num;
  }
  return len;
}

Cuando va a utilizar cats (lo único que hace es copiar una lista al buffer, peta) y cuando tiene que añadir también. No sé muy bien qué falla. ¿Alguna idea? Lo que puedo suponer es que la cadena recibida no se pasa bien o algo así, pero no tengo ni idea.

Gracias
6  Programación / Programación C/C++ / Comparación de cadenas en: 24 Octubre 2013, 09:43 am
Buenas, este es mi primero mensaje y espero que no el último. Llevo tiempo programando en java y me pasé hace muy poco  a c++ y c, por que mi carrera me lo exigía, así que ahora estoy haciendo mi primer módulo para el kernel de un debian 6, Es una práctica para la universidad y se trata de una lista que guarde y borre elementos de proc y en la que, si se modifica un archivo de  /proc  tiene que reconocerlo y ejecutar el código correspondiente, digamos que se debe añadir un número a la lista, pues el usuario escribirá: echo add 10 > /proc/mymodule. Aún soy muy inexperto con C y tengo un error que seguro es de principiante.

¿Cómo puedo estar seguro de que el formato de una cadena es del tipo: "add 144" o "remove 4"?

Gracias.
Páginas: [1]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines