Ejecutar un comando Linux desde un Modulo Kernel

Imagen de MaxR
0 puntos

Que tal!

Estoy desarrollando un modulo kernel que cree un archivo en /proc y que al hacer una lectura del mismo ("cat /proc/archivo") me muestre por consola un mensaje ("Hola") y sus respectivos usuarios (en consola se muestra con "who -u" creo...)

Solo se me complica con mostrar el usuario...en NO modo kernel con system,popen o exec podia ejecutar un comando Linux... pero no se porqué en modo Kernel no me deja y me tira error al compilarlo...acá les dejo el código...

Agradeceria que me explicaran como ejecutar un comando de Linux desde modo kernel...

GRACIAS!!!

#include 	//Indica q estamos desarrollando un modulo

#include 	//Indica q estamos trabajando en modo kernel

#include 	//necesario porque estamos trabajando con proc





#define procfs_name "archivo"   //Definimos como "archivo" al nombre del proc file

int CANT = 1;



//Esta estructura tiene informacion de nuestro archivo

 

struct proc_dir_entry *Our_Proc_File;





/*

  

  Argumentos:

  

  1. El buffer donde se insertan los datos

  2. Un puntero a un puntero de caracteres. Sirve si no se quiere utilizar el buffer alocado en el kernel

  3. La posicion actual del archivo

  4. El tamaño del buffer en el primer argumento

  5. Aqui hay q escribir 1 para indicar EOF

  6. Un puntero a los datos. Util en caso de una llamada read en comun para multiples /proc entradas

*/





int procfile_read(char *buffer,char **buffer_location,off_t offset, int buffer_length, int *eof, void *data) //Sucede cuando en consola escribo un comando de lectura tal como: "cat /proc/archivo"

{

	int ret=0;	

	

	printk(KERN_INFO "procfile_read (/proc/%s) llamado\n", procfs_name); //KERN_INFO es para decirle que es un mensaje de informacion del kernel, hay tambien por ejemplo KERN_ERR para decirle a printk que el mensaje a imprimir es un mensaje de error del kernel.

	

	if (offset > 0) {//Terminó la lectura del buffer	

		*eof=1; //Fin del archivo

		return ret; //no hay informacion disponible (ret==0)

	} else {

		//devuelve el buffer

		ret = sprintf(buffer, "Esto es Linux --llamada numero %i -- usuario\n", CANT++); //sprintf en este caso agrega una cadena al buffer devolviendo su valor de retorno...

                //ACA TENDRIA QUE INDICAR EL USER!!! 
		return ret; //se retorna el numero de bytes escritos en buffer

	}



	

}



int init_module() //Sucede cuando en consola escribo: "insmod procread.ko"

{
	

	Our_Proc_File = create_proc_entry(procfs_name, 0644, NULL);

	

	if (Our_Proc_File == NULL) {

		remove_proc_entry(procfs_name, &proc_root);

		printk(KERN_ALERT "Error: No se pudo inicializar /proc/%s\n",

		       procfs_name);

		return -ENOMEM;

	}



	Our_Proc_File->read_proc = procfile_read; //Handler de lectura

	Our_Proc_File->owner 	 = THIS_MODULE; //Indica que procfs esta siendo utilizado desde un modulo (Modulo duenio)

	Our_Proc_File->mode 	 = S_IFREG | S_IRUGO; //Permisos

	Our_Proc_File->uid 	 = 0; //Owner id del archivo

	Our_Proc_File->gid 	 = 0; //Owner Group id del archivo

	Our_Proc_File->size 	 = 37; //Tamanio del archivo



	printk(KERN_INFO "/proc/%s creado\n", procfs_name);	

	return 0;	

}



void cleanup_module() //Sucede cuando escribo en consola: "rmmod procread.ko"

{

	remove_proc_entry(procfs_name, &proc_root);

	printk(KERN_INFO "/proc/%s removido\n", procfs_name);

}
Imagen de ricreis
+1
0
-1

Hola, no tengo mucha idea de esto, pero me parece que no puedes llamar a popen y demás porque
son funciones de librería que se ejecutan en modo usuario y desde un módulo solo puedes llamar
a las funciones del núcleo.
Eso sí, el comando who y la función popen trabajan haciendo llamadas al sistema segurísimo y eso
si que lo tienes disponible desde tu módulo.

Actualizado:
He buscado un poquito y al parecer puedes usar la llamada do_execve(); de los
parámetros y como se usa no te se decir nada.

+1
0
-1
Imagen de MaxR
+1
0
-1

Voy a seguir averiguando sobre la llamada do_execve para ver como funciona

+1
0
-1