Expand description
Confinement d’un ring (Temps 3f) — sous-module
air-sys-syscall::io_uring::sandbox. Matérialise la décision de soundness
S3 : un ring qui ne peut émettre que les opérations explicitement mises
en liste blanche, imposé par le kernel.
Référence normative : docs/specs/layer-0/io-uring-3f-sandbox.md.
§Pourquoi
io_uring exécute des opérations (read, openat2, connect…) qui ne
passent pas par l’interface syscall classique : un filtre seccomp qui
bloque le syscall openat2 n’empêche pas un IORING_OP_OPENAT2 soumis
via le ring — voie de contournement historique des bacs à sable. La réponse :
restreindre le ring lui-même. Les restrictions io_uring complètent
seccomp/Landlock (family-security), en défense en profondeur ; elles ne les
remplacent pas. C’est la brique io_uring du modèle de capabilities d’Air
(ADR-001 AirCom, ADR-010 entitlements signés) — la couche 0 fournit le
mécanisme, la politique vit en couche 5.
§Le flux en trois temps (imposé kernel, reflété par l’API)
- Créer désactivé :
IoUringBuilder::restrictcrée le ringIORING_SETUP_R_DISABLEDet applique la liste blanche (REGISTER_RESTRICTIONS) — possible uniquement tant qu’il est désactivé. - Activer :
IoUring::enable(REGISTER_ENABLE_RINGS). - Immuable ensuite : après
enable, les restrictions ne peuvent plus être assouplies (imposé kernel) ; toute soumission avantenableest refusée.
Default-deny : dès qu’un opcode est mis en liste blanche, le kernel refuse
tout le reste (-EACCES).
use air_sys_syscall::io_uring::{IoUringOpcode, RegisterOp, RestrictionSet, SqeFlagSet};
// Un service AirCom « réseau seul » : le ring ne pourra jamais émettre
// openat2, unlinkat, etc. — garanti kernel.
let policy = RestrictionSet::new()
.allow_op(IoUringOpcode::Socket)
.allow_op(IoUringOpcode::Connect)
.allow_op(IoUringOpcode::Send)
.allow_op(IoUringOpcode::Recv)
.allow_op(IoUringOpcode::Close)
.allow_register(RegisterOp::ProvidedBuffers)
.require_sqe_flags(SqeFlagSet::new().fixed_file());
assert_eq!(policy.as_slice().len(), 7);
// let mut ring = IoUringBuilder::new(entries).restrict(policy.as_slice()).build()?;
// ring.enable()?; // à partir d'ici, tout opcode hors liste échoue.Structs§
- Restriction
Set - Liste blanche de ce qu’un ring confiné pourra faire (décision S3).
Default-deny : ce qui n’est pas explicitement autorisé est refusé par le
kernel. Construite par combinateurs, puis passée à
IoUringBuilder::restrictviaas_slice. - SqeFlag
Set - Ensemble de drapeaux
IOSQE_*pour les restrictions de drapeaux SQE (RestrictionSet::allow_sqe_flags/RestrictionSet::require_sqe_flags).Default= aucun drapeau. Builder chaînable. Partage la représentation des drapeaux avecSubmitOptions.
Enums§
- Register
Op - Register opcode qu’un ring confiné peut être autorisé à effectuer
(
RESTRICTION_REGISTER_OP). Newtype typé plutôt qu’unu8magique (ADR-021 conv. 3 : chaque opération est une variante nommée).#[non_exhaustive]: de futurs kernels peuvent en ajouter.