Resumen de IPC en Hubris
- Hubris usa un kernel pequeño que no depende de la aplicación, y la mayor parte del código (drivers, lógica de aplicación, stack de red, etc.) existe en tareas aisladas compiladas por separado
- Estas tareas pueden comunicarse entre sí usando un sistema de mensajería entre tareas (IPC)
- El IPC de Hubris está compuesto por 3 operaciones fundamentales implementadas en el kernel (RECV, SEND, REPLY)
- RECV: recoge el mensaje entrante de mayor prioridad, o bloquea hasta que llegue un mensaje
- SEND: transfiere un mensaje y el control a la tarea receptora y suspende al llamador. El llamador pasa a estado de espera hasta recibir una respuesta
- REPLY: entrega una respuesta a la tarea que antes usó SEND para que pueda continuar
Modos de falla nuevos e interesantes
- Como el IPC cruza los límites entre tareas y las tareas de Hubris son programas compilados por separado, hay que tener cuidado al hacer en IPC el mismo tipo de suposiciones que el compilador hace en una llamada de función
- Todas las tareas que actúan como servidores IPC en Hubris deben manejar errores potenciales como los siguientes:
- recibir un mensaje con una interfaz y un código de operación inapropiados
- recibir, en lugar del tipo de mensaje esperado, un conjunto de bytes imposible de interpretar, o un mensaje demasiado corto o demasiado largo
- no recibir la memoria necesaria (como memoria escribible)
En programas normales y correctos estas situaciones no ocurren
- En un programa normal de Hubris, las situaciones mencionadas arriba no ocurren
- Las tareas quedan conectadas entre sí por la configuración del sistema de build, así que es difícil confundirlas
- Cliente y servidor usan código Rust generado, por lo que se puede asumir que el sistema de tipos funciona a través de los límites entre tareas
El kernel no permite ninguna tontería
- En Unix, si se violan las precondiciones de una system call, se devuelve un código de error al llamador; en Hubris, la tarea es destruida de inmediato
- El kernel de Hubris entrega errores a las tareas que violan las reglas del kernel mediante el concepto de fallas sintéticas (Synthetic Fault)
- En Hubris, cuando ocurre una falla de hardware o una falla sintética, la tarea se detiene inmediatamente y no puede recuperarse
El servidor tampoco permite ninguna tontería
- Mediante la decimotercera y más extraña system call, REPLY_FAULT, el servidor puede entregar un error al cliente
- REPLY_FAULT es similar a REPLY, pero en vez de entregar un mensaje y dejar la tarea en estado ejecutable, entrega un error y detiene la tarea
- REPLY_FAULT permite evitar manejo innecesario de errores de IPC. Los programas normales actúan como si el problema no pudiera ocurrir, y los programas anormales ni siquiera tienen oportunidad de manejar el error
- REPLY_FAULT ofrece una nueva forma de definir e implementar errores específicos de la aplicación, como reglas de control de acceso
Opinión de GN⁺
- REPLY_FAULT es un mecanismo potente con el que el servidor puede provocar un
panic! entre procesos en el cliente sin cooperación del lado del cliente. Gracias a esto, Hubris se vuelve un sistema muy hostil frente a programas maliciosos
- La desventaja de REPLY_FAULT es que las pruebas de fuzzing se vuelven muy difíciles. Una tarea de ingeniería del caos que genere IPC o system calls aleatorias se reinicia de inmediato en casi cualquier comportamiento
- Sin embargo, como las tareas normales de Hubris no generan mensajes IPC de forma dinámica, pueden funcionar sin siquiera ser conscientes de la existencia de REPLY_FAULT
- Con REPLY_FAULT, el servidor puede hacer que al cliente le ocurra un error de forma arbitraria, pero la evaluación de esto todavía no está completamente cerrada
- El manejo agresivo de errores de Hubris ayuda a detectar errores en etapas tempranas del desarrollo y, a diferencia de los códigos de error, hace imposible ignorarlos
- Usar una forma universal de manejar errores de IPC puede introducir sobrecarga innecesaria incluso en programas normales. REPLY_FAULT parece una solución elegante que evita eso y al mismo tiempo responde con dureza ante programas anormales
1 comentarios
Opinión de Hacker News
En resumen, se plantea lo siguiente:
Se expresa preocupación sobre si
REPLY_FAULTse propaga en cadena y sobre las vulnerabilidades que eso podría causarREPLY_FAULT, A también termina junto con los demásSENDtiene una estructura cíclica, incluso podría terminar matándose a sí mismo sin quererREPLY_FAULTofrece una forma de definir e implementar errores específicos de la aplicación, como el control de accesoEn sistemas donde un solo equipo escribe todo el código, eliminar clientes sospechosos puede acelerar la velocidad de iteración
Hubris puede verse como un kernel que permite que el servidor realice efectos que el cliente no puede manejar
Hubris y Humility son tecnologías en las que uno querría profundizar, pero es difícil por las limitaciones de tiempo y obligaciones
En un RFC del Día de los Inocentes sobre HTTP, se propone el código de estado HTTP 499 con el significado de "deberías avergonzarte"
Citando la frase de Einstein, "tan simple como sea posible, pero no más simple", se señala que el diseño de Hubris viola esta última parte
Humility es un nombre excelente para un depurador
En Linux, no es posible terminar directamente otros programas solo con sockets, pero con privilegios de
rootsí se puede matar otros procesos o incluso reiniciar el sistemarootson comunes, así que este riesgo existeEsto entra un poco en conflicto con la sabiduría tradicional de los sistemas de red: "sé liberal al aceptar y estricto al emitir"