[Previo por Fecha] [Siguiente por Fecha] [Previo por Hilo] [Siguiente por Hilo]
[Hilos de Discusión] [Fecha] [Tema] [Autor]A QUIEN CORRESPONDA Quisiera que me dijeran, por favor, en donde puedo obtener ayuda especifica sobre problemas que tengo al modificar las funciones sys_open y sys_close de /usr/src/linux/fs/open.c . A continuacion describo el problema especifico de que se trata. Distribucion: RedHat 6.2 Kernel: 2.2.16-3 Estoy tratando de hacer algunas modificaciones en las funciones sys_open y sys_close en /usr/src/linux/fs/open.c . Curiosamente, no tengo problemas en hacer las modificaciones que necesito en sys_open, pero no se me permiten en sys_close. Concretamente se trata de lo siguiente: /* * linux/fs/open.c * * Copyright (C) 1991, 1992 Linus Torvalds */ #include <linux/mm.h> #include <linux/utime.h> #include <linux/file.h> #include <linux/smp_lock.h> #include <linux/quotaops.h> #include <asm/uaccess.h> #include <linux/un.h> #define FILE_UNIX "/tmp/file_unix" struct peticion { /* peticion.tipo_msj : 1=peticion de open; 2=aviso de close; 3=fin de sincronia */ int tipo_msj; int proceso; int file; char file_name [250]; }; asmlinkage int sys_open(const char * filename, int flags, int mode) { char * tmp; int fd, error; /* ------------------------------------------------------------------------------ */ struct sockaddr_un serv_addr; int sock_id, serv_addr_len; struct peticion * request; int * respuesta; if ( sys_getuid() >= 1000 && ((flags & O_APPEND) || (flags & O_CREAT) || (flags & O_RDWR) || (flags & O_SYNC) || (flags & O_TRUNC) || (flags & O_WRONLY)) ) { respuesta = (int *) vmalloc (sizeof(int)); request = (struct peticion *) vmalloc (sizeof(struct peticion)); tmp = getname(filename); *respuesta = 0; request->tipo_msj = 1; request->proceso = sys_getpid(); strcpy (request->file_name, tmp); serv_addr.sun_family = AF_UNIX; strcpy (serv_addr.sun_path, FILE_UNIX); serv_addr_len = strlen (serv_addr.sun_path) + sizeof (serv_addr.sun_family); if ( (sock_id = sys_socket (AF_UNIX, SOCK_STREAM, 0)) == -1 ) goto pre_error; if ( sys_connect (sock_id, (struct sockaddr *) &serv_addr, serv_addr_len) == -1 ) goto pre_error; if ( sys_sendto (sock_id, request, sizeof (request), 0, (struct sockkaddr *) &serv_addr, sizeof (serv_addr)) != sizeof (request) ) goto pre_error; if ( sys_recvfrom (sock_id, respuesta, sizeof (int), 0, NULL, NULL) == -1 ) goto pre_error; /* si la respuesta es cero ==> fue negado el acceso al archivo */ if ( *respuesta == 0) goto pre_error; else goto salida_ok; pre_error: sys_close (sock_id); vfree (respuesta); vfree (request); error=-EACCES; fd = -1; return fd; salida_ok: sys_close (sock_id); vfree (respuesta); vfree (request); } /* ------------------------------------------------------------------------------ */ tmp = getname(filename); fd = PTR_ERR(tmp); if (!IS_ERR(tmp)) { lock_kernel(); fd = get_unused_fd(); if (fd >= 0) { struct file * f = filp_open(tmp, flags, mode); error = PTR_ERR(f); if (IS_ERR(f)) goto out_error; fd_install(fd, f); } out: unlock_kernel(); putname(tmp); } return fd; out_error: put_unused_fd(fd); fd = error; goto out; } asmlinkage int sys_close(unsigned int fd) { int error; struct file * filp; struct sockaddr_un serv_addr; int sock_id, serv_addr_len; struct peticion * request; unsigned int fd_back; int archivo=0; fd_back = fd; /* si lo siguiente se cumple entonces se trata de un archivo, no de un socket */ if ( current->files->fd[fd]->f_dentry->d_inode->i_dev != 0 ) archivo =1; lock_kernel(); error = -EBADF; filp = fcheck(fd); if (filp) { struct files_struct * files = current->files; files->fd[fd] = NULL; put_unused_fd(fd); FD_CLR(fd, files->close_on_exec); error = filp_close(filp, files); } unlock_kernel(); /* ------------------------------------------------------------------------------ */ if ( sys_getuid() >= 1000 && (archivo==1) ) { request = (struct peticion *) vmalloc (sizeof(struct peticion)); request->tipo_msj = 2; request->proceso = sys_getpid(); request->file = fd_back; strcpy (request->file_name, current->files->fd[fd]->f_dentry->d_name.name); serv_addr.sun_family = AF_UNIX; strcpy (serv_addr.sun_path, FILE_UNIX); serv_addr_len = strlen (serv_addr.sun_path) + sizeof (serv_addr.sun_family); if ( (sock_id = sys_socket (AF_UNIX, SOCK_STREAM, 0)) != -1 ) if ( sys_connect (sock_id, (struct sockaddr *) &serv_addr, serv_addr_len) != -1 ) sys_sendto (sock_id, request, sizeof (request), 0, (struct sockkaddr *) &serv_addr, sizeof (serv_addr)); new_close (sock_id); vfree (request); } /* ------------------------------------------------------------------------------ */ return error; } El problema no viene en la compilacion, sino en la ejecucion. Esto es, a la hora de arrancar el sistema operativo se queda bloqueado con el siguiente mensaje en la pantalla: ------------------------------------------------------------------------------------------ VFS: Mounted root (ext2 filesystem) readonly. Freeing unused kernel memory: 64 k freed. Unable to handle kernel NULL pointer dereference at virtual adress 00000008 current->tss.cr3 = 07e4c000, %cr3 = 07e4c000 *pde = 00000000 Oops: 0000 CPU: 0 EIP: 0010:[<c0126525>] EFLAGS: 00010286 ------------------------------------------------------------------------------------------ y continua un dump de los registros del procesador y otras cosas. Si se ejecuta lo que se indica en /usr/src/linux/README: nm vmlinux | sort | less se encuentra que la funcion que marca error ( c0126525 ) es efectivamente sys_close. Por otro lado, he intentado hacer pruebas con una seccion de codigo mucho mas sencillo en sys_close, como la siguiente: /* ------------------------------------------------------------------------------ */ if ( sys_getuid() >= 1000 && (archivo==1) ) { char prueba [250]; prueba [0] = 2; } /* ------------------------------------------------------------------------------ */ y esto basta para marcar el mismo problema. No se si ustedes ya hayan tenido alguna experiencia similar y pudieran orientarme al respecto. Gracias. Atantamente Jorge Ramirez Banco de Mexico. _______________________________________________ Ayuda mailing list Ayuda en linux org mx