|
Diseño
|
En
Lisex 0.0 tratamos de respetar el diseño del núcleo de Linux tanto
como fue posible. Sin embargo, debido a las nuevas características
de seguridad, fue necesario agregar y modificar ciertas estructuras
y funciones del núcleo. Al hacerlo aplicamos nuestro criterio. En
lo que sigue daremos una visión general sobre el diseño del núcleo
de Lisex 0.0 y su relación con el diseño del núcleo de Linux.
El
documento
sobre diseño incluye esta página y la relación que hay entre
cada llamada
al sistema y cada operación del modelo formal; además se puede encontrar
información más detallada sobre el diseño en el manual del programador.
|
Introducción
|
Linux
respeta la arquitectura básica de la mayoría de los sistemas operativos:
un estrato, capa o componente reune el software a nivel de usuario
o software de aplicación, y otro estrato contiene el software del
núcleo del sistema operativo (ver figura). Estas dos capas se comunican mediante llamada a procedimiento
y memoria compartida. La capa superior (software de usuario) solicita
servicios a la capa inferior (núcleo) por medio de la ejecución
de llamadas al sistema. El núcleo ejecuta en modo protegido,
es decir, el hardware impide que programas en la capa superior accedan
a software o datos en la capa inferior de forma arbitraria. Cualquier
interacción iniciada en la capa superior debe hacerse ejecutando
llamadas al sistema. Lisex 0.0 respeta este modelo arquitectónico.
El
núcleo puede dividirse en sub-sistemas (administración de memoria,
administración de procesos, sistema de archivos, etc.) los que se
forman dividiendo en grupos o conjuntos las llamadas al sistema.
Esta división en algunos casos no es clara ni precisa (por ejemplo,
algunas funciones de administración de procesos pueden accederse
a través del sistema de archivos). A nivel de código fuente, estos
sub-sistemas se representan por medio de uno o más archivos .c
y .h , en algunas ocasiones ubicados en diferentes directorios
(por ejemplo, el directorio fs contiene todos los archivos
.c y .h relativos al sistema de archivos).
En
el interior de cualquiera de estos sub-sistemas, es decir inaccesibles
de forma directa desde el espacio de usuario, encontramos funciones
auxiliares y estructuras de datos. Las estructuras de datos rara
vez están ocultas detrás de una interfaz abstracta (en general por
cuestiones de eficiencia aunque en varias ocasiones ambas cualidades,
eficiencia y abstracción, podrían combinarse).
|
|
|
|
Esquema
de los componentes del diseño del núcleo de Linux. Se muestran
los TADs incluidos en el desarrollo de Lisex. Las flechas
indican los patrones más usuales de llamadas a funciones.
El esquema no pretende ser completo sino sólo mostrar los
componentes de interés para el presente documento.
|
|
|
El
sistema de archivos2> |
Como
ya hemos dicho, Lisex 0.0 es una modificación del núcleo de Linux
restringida al sistema de archivos por lo que nos concentraremos
es este sub-sistema específico.
El
sistema de archivos de Linux puede dividirse en varios componentes:
VFS y un componente por cada sistema de archivos registrado ante
el VFS (ver figura). Uno de los tipos principales de sistemas de archivos
que se registran ante el VFS está constituido por los sistemas de
archivos reales o físicos. Otros, pueden ser sistemas
de archivos como /proc que usan el poder de VFS para
organizar y hacer accesible información que no será, en general,
persistente. El sistema de archivos real o físico más usando en
Linux es EXT2.
En
términos generales, los sistemas de archivos físicos o reales se
encargan de la administración de archivos y directorios a bajo nivel
en contacto directo con los dispositivos de almacenamiento, mientras
que el VFS se encarga de mostrar una representación e interfaz común
de todos los sistemas de archivos que se han registrado (por ejemplo,
abrir un archivo almacenado en un sistema de archivos tipo FAT es,
para las aplicaciones, indistinto de abrir un archivo almacenado
en EXT2 pues en ambos casos la aplicación se comunica con VFS y
no con cada sistema de archivos particular).
El
conector que conecta VFS con los sistemas de archivos reales es
llamada a procedimiento y en menor medida memoria compartida.
Lisex
0.0 introdujo cambios a nivel de VFS y EXT2. Estos cambios incluyen
adición y modificación de llamadas al sistema, funciones auxiliares,
y estructuras de datos. En las secciones siguientes se hará referencia
únicamente a las adiciones pues son estas las que alteran el diseño;
las modificaciones a componentes existentes se describen con detalle
en el manual del programador.
|
Nuevas
llamadas al sistema |
Lisex
0.0 expande el sistema de archivos agregando
las siguientes llamadas al sistema:
|
sys_acladd() , agrega permisos
a un usuario o grupo en la ACL de un archivo o directorio.
|
|
sys_acldel() , elimina permisos
de un usuario o grupo en la ACL de un archivo o directorio.
|
|
sys_oscstat() , retorna la
clase de acceso de un archivo o directorio.
|
|
sys_chobjsc() , modifica la
clase de acceso de un archivo o directorio.
|
|
sys_aclstat() , retorna la
ACL de un archivo o directorio.
|
|
sys_aclfstat() , retorna la
ACL de un archivo o directorio abierto.
|
|
sys_chsubsc() , cambia la
clase de acceso de un usuario.
|
|
sys_sscstat() ,
retorna la clase de acceso de un usuario.
|
Para
más detalles ver: el capítulo 2 del documento sobre diseño,
la especificación, y el manual del programador.
|
Nuevas
funciones auxiliares |
No
se agregaron funciones auxiliares a nivel de EXT2. Las funciones
auxiliares a nivel de VFS que se agregaron son las siguientes:
|
may_open() ,
determina si un archivo puede ser abierto por un proceso o no,
usa permission()
y mac_permission() ; es usada por do_execve() ,
may_delete() ,
may_create() , sys_setuid() y
open_namei() .
|
|
acl_chmod_ok() , calcula si
se puede realizar sys_chmod() ;
es usada por
sys_chmod() .
|
|
is_open() , determina si un
archivo está abierto o no; es usada por sys_acladd() ,
sys_acldel() , sys_hobjsc() , sys_chmod() ,
sys_chown() y sys_lchown() .
|
|
mac_permission() , implementa
seguridad MAC y MLS; es usada por
may_open() .
|
|
cp_aclstat() , carga en una
estructura los datos de la ACL de un archivo o directorio; es
usada por sys_aclstat()
y sys_aclfstat() .
|
|
logged() , determina si un
usuario está corriendo algún proceso o no; es usada por sys_chsubsc() .
|
Más
detalles se pueden encontrar en el
manual del programador. Además se debe tener en cuenta que se
agregaron otras funciones auxiliares como parte de varios tipos
abstractos de datos que se detallan en la sección siguiente.
|
Nuevos
TADs y estructuras de datos |
Lisex
0.0 introduce cuatro tipos abstractos de datos que se detallan más
abajo. Por TAD entendemos una estructura de datos mas un conjunto
de sub-programas; la estructura sólo puede ser accedida por los
sub-programas. La estructura de datos suele denominarse el secreto
del TAD y los sub-programas la interfaz; se dice que este
estilo de diseño impone el principio de ocultación de la información
(information hiding). Dado que el lenguaje de implementación del
núcleo de Linux es C no es posible imponer el principio de ocultación
de información en tiempo de compilación, como se haría en C++ por
ejemplo. En otras palabras, es posible escribir código que modificara
o consultara el estado del secreto de un TAD sin usar la interfaz.
La única forma de imponer el principio es con disciplina de programación,
es decir, los programadores acuerdan usar la interfaz y sólo esta
para acceder los secretos de los TADs.
Los
TAD que se definieron son los siguientes:
|
vfs-acl ,
cuyo secreto es la implementación de las ACL a nivel del VFS
y provee funciones para calcular el modo UNIX a partir de una
ACL, inicializar una ACL, establecer los permisos de un usuario
o grupo, etc.
|
|
sc ,
que oculta la representación de las clases de acceso y provee
funciones para obtener y establecer el nivel y las categorías
de una clase de acceso, comparar dos clases de acceso, etc.
|
|
acl_entry ,
cuyo secreto es la representación de la terna
(U_G_ID, type, mode) a
nivel de VFS, cada una de las cuales codifica el modo
(mode) de un usuario (U_G_ID)
o grupo (U_G_ID) según lo indica type; y provee funciones para alterar y consultar
el estado de cada terna.
|
|
subjectsc ,
que oculta la forma precisa en que se almacenan las clases de
acceso de los usuarios y provee funciones para inicializar una
clase de acceso, obtener y establecer la clase de acceso de
un usuario, etc.
|
|
ext2_acl_entry ,
semejante a acl_entry pero
a nivel de EXT2.
|
Más
detalles pueden encontrarse en el manual del programador.
|
|