GNU/Linux >> Tutoriales Linux >  >> Linux

¿Puede eBPF modificar el valor de retorno o los parámetros de una llamada al sistema?

Creo que adjuntar eBPF a kprobes/kretprobes le da acceso de lectura a los argumentos de la función y valores de retorno, pero no puede alterarlos. NO estoy 100% seguro; buenos lugares para pedir confirmación serían la lista de correo del proyecto IO Visor o el canal IRC (#iovisor en irc.oftc.net).

Como solución alternativa, sé que al menos puede cambiar el valor de retorno de una llamada al sistema con strace, con el -e opción. Citando la página del manual:

-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr]
       Perform syscall tampering for the specified set of syscalls.

Además, hubo una presentación sobre esto y la inyección de fallas en Fosdem 2017, si es de su interés. Aquí hay un comando de ejemplo de las diapositivas:

strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt

Editar: Como dijo Ben, eBPF en kprobes y puntos de seguimiento definitivamente es de solo lectura, para casos de uso de seguimiento y monitoreo. También recibí confirmación sobre esto en IRC.


Dentro de las sondas del kernel (kprobes), la máquina virtual eBPF tiene acceso de solo lectura a los parámetros de llamada al sistema y al valor devuelto.

Sin embargo, el programa eBPF tendrá un código de retorno propio. Es posible aplicar un perfil seccomp que atrape los códigos de retorno BPF (NO eBPF; gracias @qeole) e interrumpa la llamada al sistema durante la ejecución.

Las modificaciones de tiempo de ejecución permitidas son:

  • SECCOMP_RET_KILL :Eliminación inmediata con SIGSYS
  • SECCOMP_RET_TRAP :envía un SIGSYS atrapable , dando la oportunidad de emular el syscall
  • SECCOMP_RET_ERRNO :Forzar errno valor
  • SECCOMP_RET_TRACE :Ceder la decisión a ptracer o establecer errno a -ENOSYS
  • SECCOMP_RET_ALLOW :Permitir

https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt

El SECCOMP_RET_TRACE El método permite modificar la llamada al sistema realizada, los argumentos o el valor de retorno. Esto depende de la arquitectura y la modificación de las referencias externas obligatorias puede causar un error ENOSYS.

Lo hace pasando la ejecución a un ptrace de espacio de usuario en espera, que tiene la capacidad de modificar la memoria del proceso rastreado, los registros y los descriptores de archivos.

El rastreador debe llamar a ptrace y luego a waitpid. Un ejemplo:

ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP);
waitpid(tracee_pid, &status, 0);

http://man7.org/linux/man-pages/man2/ptrace.2.html

Cuando waitpid devuelve, dependiendo del contenido de status , uno puede recuperar el valor de retorno de seccomp usando el PTRACE_GETEVENTMSG operación ptrace. Esto recuperará el seccomp SECCOMP_RET_DATA valor, que es un campo de 16 bits establecido por el programa BPF. Ejemplo:

ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);

Los argumentos de Syscall se pueden modificar en la memoria antes de continuar con la operación. Puede realizar una sola entrada o salida de llamada al sistema con el PTRACE_SYSCALL paso. Los valores de retorno de Syscall se pueden modificar en el espacio de usuario antes de reanudar la ejecución; el programa subyacente no podrá ver que los valores de retorno de syscall se han modificado.

Una implementación de ejemplo:filtrar y modificar llamadas del sistema con seccomp y ptrace


Linux
  1. ¿Solo devolver la cadena coincidente en Sed?

  2. ¿El valor máximo de la identificación del proceso?

  3. ¿Cuál es la magia de - (un guión) en los parámetros de la línea de comandos?

  4. Java no se puede conectar al servidor de ventanas X11 usando 'localhost:10.0' como el valor de la variable DISPLAY

  5. Valor de retorno de x =os.system(..)

3 cosas útiles que puedes hacer con la herramienta IP en Linux

Cómo modificar los repositorios de Proxmox

Solucione el error que no puede encontrar el comando hwmatch en Grub

¿Qué prioridad en tiempo real es la prioridad más alta en Linux?

¿No puede encontrar .so en el mismo directorio que el ejecutable?

La variable 'general_log_file' no se puede establecer en el valor de '/var/lib/msyql/ubuntu.log'