base: Add missing P35-P43 boot-hardening patches

Graceful init patches for fbcond, graphics scheme, smolnetd, vesad,
PCI interrupt allocation, BAR probing, common init, inputd fallback,
and dhcpd hard dependency ordering.
This commit is contained in:
2026-05-20 13:57:47 +03:00
parent 8f8c69a04e
commit 40ba2caaf6
9 changed files with 845 additions and 0 deletions
@@ -0,0 +1,12 @@
--- a/drivers/graphics/fbbootlogd/Cargo.toml
+++ b/drivers/graphics/fbbootlogd/Cargo.toml
@@ -15,0 +16 @@ scheme-utils = { path = "../../../scheme-utils" }
+common = { path = "../../common" }
--- a/drivers/graphics/fbbootlogd/src/main.rs
+++ b/drivers/graphics/fbbootlogd/src/main.rs
@@ -23,0 +24 @@ fn main() {
+ common::init();
--- a/drivers/graphics/fbcond/src/main.rs
+++ b/drivers/graphics/fbcond/src/main.rs
@@ -18,0 +19 @@ fn main() {
+ common::init();
@@ -0,0 +1,106 @@
diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs
index eab0be9c..b6683686 100644
--- a/drivers/graphics/driver-graphics/src/lib.rs
+++ b/drivers/graphics/driver-graphics/src/lib.rs
@@ -138 +138 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- pub fn new(mut adapter: T, scheme_name: String, early: bool) -> Self {
+ pub fn new(mut adapter: T, scheme_name: String, early: bool) -> io::Result<Self> {
@@ -140 +140,6 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- let socket = Socket::nonblock().expect("failed to create graphics scheme");
+ let socket = Socket::nonblock().map_err(|e| {
+ io::Error::new(
+ io::ErrorKind::Other,
+ format!("failed to create graphics scheme socket: {e}"),
+ )
+ })?;
@@ -143,2 +148,6 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- File::open("/scheme/debug/disable-graphical-debug")
- .expect("vesad: Failed to open /scheme/debug/disable-graphical-debug"),
+ File::open("/scheme/debug/disable-graphical-debug").map_err(|e| {
+ io::Error::new(
+ io::ErrorKind::Other,
+ format!("failed to open /scheme/debug/disable-graphical-debug: {e}"),
+ )
+ })?,
@@ -164,3 +173,12 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- let cap_id = inner.scheme_root().expect("failed to get this scheme root");
- register_scheme_inner(&inner.socket, &inner.scheme_name, cap_id)
- .expect("failed to register graphics scheme root");
+ let cap_id = inner.scheme_root().map_err(|e| {
+ io::Error::new(
+ io::ErrorKind::Other,
+ format!("failed to get scheme root: {e}"),
+ )
+ })?;
+ register_scheme_inner(&inner.socket, &inner.scheme_name, cap_id).map_err(|e| {
+ io::Error::new(
+ io::ErrorKind::Other,
+ format!("failed to register graphics scheme root: {e}"),
+ )
+ })?;
@@ -169 +187,6 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- DisplayHandle::new_early(&inner.scheme_name).unwrap()
+ DisplayHandle::new_early(&inner.scheme_name).map_err(|e| {
+ io::Error::new(
+ io::ErrorKind::Other,
+ format!("failed to create early display handle: {e}"),
+ )
+ })?
@@ -171 +194,6 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- DisplayHandle::new(&inner.scheme_name).unwrap()
+ DisplayHandle::new(&inner.scheme_name).map_err(|e| {
+ io::Error::new(
+ io::ErrorKind::Other,
+ format!("failed to create display handle: {e}"),
+ )
+ })?
@@ -174 +202 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- Self {
+ Ok(Self {
@@ -178 +206 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- }
+ })
diff --git a/drivers/graphics/ihdgd/src/main.rs b/drivers/graphics/ihdgd/src/main.rs
index a8b6cc60..990706c2 100644
--- a/drivers/graphics/ihdgd/src/main.rs
+++ b/drivers/graphics/ihdgd/src/main.rs
@@ -43 +43,8 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
- let mut scheme = GraphicsScheme::new(device, format!("display.ihdg.{}", name), false);
+ let mut scheme = match GraphicsScheme::new(device, format!("display.ihdg.{}", name), false) {
+ Ok(s) => s,
+ Err(e) => {
+ eprintln!("ihdgd: failed to create GraphicsScheme: {} — exiting", e);
+ daemon.ready();
+ std::process::exit(0);
+ }
+ };
diff --git a/drivers/graphics/vesad/src/main.rs b/drivers/graphics/vesad/src/main.rs
index 5e9526fe..acbcb3fa 100644
--- a/drivers/graphics/vesad/src/main.rs
+++ b/drivers/graphics/vesad/src/main.rs
@@ -137,2 +137,8 @@ fn daemon(daemon: daemon::Daemon) -> ! {
- let mut scheme =
- GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned(), true);
+ let mut scheme = match GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned(), true) {
+ Ok(s) => s,
+ Err(e) => {
+ eprintln!("vesad: failed to create GraphicsScheme: {} — exiting", e);
+ daemon.ready();
+ std::process::exit(0);
+ }
+ };
diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs
index 22a985ee..96d8f964 100644
--- a/drivers/graphics/virtio-gpud/src/scheme.rs
+++ b/drivers/graphics/virtio-gpud/src/scheme.rs
@@ -1,0 +2 @@ use std::fmt;
+use std::io;
@@ -511 +512 @@ impl<'a> GpuScheme {
- ) -> Result<GraphicsScheme<VirtGpuAdapter<'a>>, Error> {
+ ) -> io::Result<GraphicsScheme<VirtGpuAdapter<'a>>> {
@@ -522 +523 @@ impl<'a> GpuScheme {
- Ok(GraphicsScheme::new(
+ GraphicsScheme::new(
@@ -526 +527 @@ impl<'a> GpuScheme {
- ))
+ )
@@ -0,0 +1,10 @@
diff --git a/netstack/src/main.rs b/netstack/src/main.rs
index b18f3226..0e4c1486 100644
--- a/netstack/src/main.rs
+++ b/netstack/src/main.rs
@@ -103,2 +102,0 @@ fn run(daemon: daemon::Daemon) -> Result<()> {
- daemon.ready();
-
@@ -160,0 +159,2 @@ fn run(daemon: daemon::Daemon) -> Result<()> {
+ daemon.ready();
+
@@ -0,0 +1,28 @@
diff --git a/drivers/graphics/vesad/src/main.rs b/drivers/graphics/vesad/src/main.rs
index acbcb3fa..6f55913b 100644
--- a/drivers/graphics/vesad/src/main.rs
+++ b/drivers/graphics/vesad/src/main.rs
@@ -137,9 +136,0 @@ fn daemon(daemon: daemon::Daemon) -> ! {
- let mut scheme = match GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned(), true) {
- Ok(s) => s,
- Err(e) => {
- eprintln!("vesad: failed to create GraphicsScheme: {} — exiting", e);
- daemon.ready();
- std::process::exit(0);
- }
- };
-
@@ -152,0 +144,2 @@ fn daemon(daemon: daemon::Daemon) -> ! {
+ // EventQueue MUST be created before GraphicsScheme::new to avoid a deadlock with initnsmgr.
+ // See ihdgd fix (P0-driver-api-migration-fixes) for the same issue.
@@ -160,0 +154,10 @@ fn daemon(daemon: daemon::Daemon) -> ! {
+
+ let mut scheme = match GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned(), true) {
+ Ok(s) => s,
+ Err(e) => {
+ eprintln!("vesad: failed to create GraphicsScheme: {} — exiting", e);
+ daemon.ready();
+ std::process::exit(0);
+ }
+ };
+
@@ -0,0 +1,217 @@
diff --git a/drivers/audio/ihdad/src/main.rs b/drivers/audio/ihdad/src/main.rs
index a9315902..75981cd9 100755
--- a/drivers/audio/ihdad/src/main.rs
+++ b/drivers/audio/ihdad/src/main.rs
@@ -40,7 +40,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize;
- let irq_file = pci_allocate_interrupt_vector(&mut pcid_handle, "ihdad");
+ let irq_file = match pci_allocate_interrupt_vector(&mut pcid_handle, "ihdad") {
+ Some(iv) => iv,
+ None => {
+ log::error!("ihdad: no interrupt vector available, exiting");
+ std::process::exit(1);
+ }
+ };
{
let vend_prod: u32 = ((pci_config.func.full_device_id.vendor_id as u32) << 16)
diff --git a/drivers/graphics/ihdgd/src/main.rs b/drivers/graphics/ihdgd/src/main.rs
index 990706c2..4aa21caa 100644
--- a/drivers/graphics/ihdgd/src/main.rs
+++ b/drivers/graphics/ihdgd/src/main.rs
@@ -32,7 +32,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
let device = Device::new(&mut pcid_handle, &pci_config.func)
.expect("ihdgd: failed to initialize device");
- let irq_file = pci_allocate_interrupt_vector(&mut pcid_handle, "ihdgd");
+ let irq_file = match pci_allocate_interrupt_vector(&mut pcid_handle, "ihdgd") {
+ Some(iv) => iv,
+ None => {
+ log::error!("ihdgd: no interrupt vector available, exiting");
+ std::process::exit(1);
+ }
+ };
// Needs to be before GraphicsScheme::new to avoid a deadlock due to initnsmgr blocking on
// /scheme/event as it is already blocked on opening /scheme/display.ihdg.*.
diff --git a/drivers/net/rtl8139d/src/main.rs b/drivers/net/rtl8139d/src/main.rs
index d470e814..e372feda 100644
--- a/drivers/net/rtl8139d/src/main.rs
+++ b/drivers/net/rtl8139d/src/main.rs
@@ -57,7 +57,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
let bar = map_bar(&mut pcid_handle);
- let irq_file = pci_allocate_interrupt_vector(&mut pcid_handle, "rtl8139d");
+ let irq_file = match pci_allocate_interrupt_vector(&mut pcid_handle, "rtl8139d") {
+ Some(iv) => iv,
+ None => {
+ log::error!("rtl8139d: no interrupt vector available, exiting");
+ std::process::exit(1);
+ }
+ };
let mut scheme = NetworkScheme::new(
move || unsafe {
diff --git a/drivers/net/rtl8168d/src/main.rs b/drivers/net/rtl8168d/src/main.rs
index 06d9ff58..29ebf799 100644
--- a/drivers/net/rtl8168d/src/main.rs
+++ b/drivers/net/rtl8168d/src/main.rs
@@ -57,7 +57,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
let bar = map_bar(&mut pcid_handle);
- let irq_file = pci_allocate_interrupt_vector(&mut pcid_handle, "rtl8168d");
+ let irq_file = match pci_allocate_interrupt_vector(&mut pcid_handle, "rtl8168d") {
+ Some(iv) => iv,
+ None => {
+ log::error!("rtl8168d: no interrupt vector available, exiting");
+ std::process::exit(1);
+ }
+ };
let mut scheme = NetworkScheme::new(
move || unsafe {
diff --git a/drivers/pcid/src/driver_interface/irq_helpers.rs b/drivers/pcid/src/driver_interface/irq_helpers.rs
index 39b0b048..f62cc055 100644
--- a/drivers/pcid/src/driver_interface/irq_helpers.rs
+++ b/drivers/pcid/src/driver_interface/irq_helpers.rs
@@ -24,11 +24,13 @@ pub fn read_bsp_apic_id() -> io::Result<usize> {
buffer[0], buffer[1], buffer[2], buffer[3],
]))
} else {
- panic!(
- "`/scheme/irq` scheme responded with {} bytes, expected {}",
- bytes_read,
- std::mem::size_of::<usize>()
- );
+ return Err(io::Error::new(
+ io::ErrorKind::InvalidData,
+ format!(
+ "`/scheme/irq/bsp` responded with {} bytes, expected 4 or 8",
+ bytes_read
+ ),
+ ));
})
.or(Err(io::Error::new(
io::ErrorKind::InvalidData,
@@ -83,7 +85,9 @@ pub fn allocate_aligned_interrupt_vectors(
alignment: NonZeroU8,
count: u8,
) -> io::Result<Option<(u8, Vec<File>)>> {
- let cpu_id = u8::try_from(cpu_id).expect("usize cpu ids not implemented yet");
+ let cpu_id = u8::try_from(cpu_id).map_err(|_| {
+ io::Error::new(io::ErrorKind::InvalidInput, "cpu_id does not fit in u8")
+ })?;
if count == 0 {
return Ok(None);
}
@@ -298,7 +302,7 @@ impl InterruptVector {
pub fn pci_allocate_interrupt_vector(
pcid_handle: &mut crate::driver_interface::PciFunctionHandle,
driver: &str,
-) -> InterruptVector {
+) -> Option<InterruptVector> {
let features = pcid_handle.fetch_all_features();
let has_msi = features.iter().any(|feature| feature.is_msi());
@@ -307,7 +311,10 @@ pub fn pci_allocate_interrupt_vector(
if has_msix {
let msix_info = match pcid_handle.feature_info(super::PciFeature::MsiX) {
super::PciFeatureInfo::MsiX(msix) => msix,
- _ => unreachable!(),
+ _ => {
+ log::warn!("{driver}: MSI-X feature info mismatch, falling back");
+ return None;
+ }
};
let mut info = unsafe { msix_info.map_and_mask_all(pcid_handle) };
@@ -327,11 +334,11 @@ pub fn pci_allocate_interrupt_vector(
pcid_handle.enable_feature(crate::driver_interface::PciFeature::MsiX);
- return InterruptVector {
+ return Some(InterruptVector {
irq_handle,
vector: 0,
kind: InterruptVectorKind::MsiX { table_entry: entry },
- };
+ });
}
log::warn!("{driver}: MSI-X vector allocation failed, falling back");
// fall through to MSI
@@ -339,25 +346,26 @@ pub fn pci_allocate_interrupt_vector(
if has_msi {
if let Some(irq_handle) = allocate_first_msi_interrupt_on_bsp(pcid_handle) {
- return InterruptVector {
+ return Some(InterruptVector {
irq_handle,
vector: 0,
kind: InterruptVectorKind::Msi,
- };
+ });
}
log::warn!("{driver}: MSI allocation failed, falling back to legacy");
}
if let Some(irq) = pcid_handle.config().func.legacy_interrupt_line {
// INTx# pin based interrupts.
- return InterruptVector {
+ return Some(InterruptVector {
irq_handle: irq.irq_handle(driver),
vector: 0,
kind: InterruptVectorKind::Legacy,
- };
+ });
}
- panic!("{driver}: no interrupts supported at all")
+ log::warn!("{driver}: no interrupts supported at all");
+ None
}
// FIXME support MSI on non-x86 systems
@@ -365,15 +373,16 @@ pub fn pci_allocate_interrupt_vector(
pub fn pci_allocate_interrupt_vector(
pcid_handle: &mut crate::driver_interface::PciFunctionHandle,
driver: &str,
-) -> InterruptVector {
+) -> Option<InterruptVector> {
if let Some(irq) = pcid_handle.config().func.legacy_interrupt_line {
// INTx# pin based interrupts.
- InterruptVector {
+ Some(InterruptVector {
irq_handle: irq.irq_handle(driver),
vector: 0,
kind: InterruptVectorKind::Legacy,
- }
+ })
} else {
- panic!("{driver}: no interrupts supported at all")
+ log::warn!("{driver}: no interrupts supported at all");
+ None
}
}
diff --git a/drivers/storage/nvmed/src/main.rs b/drivers/storage/nvmed/src/main.rs
index beb1b689..59887186 100644
--- a/drivers/storage/nvmed/src/main.rs
+++ b/drivers/storage/nvmed/src/main.rs
@@ -77,7 +77,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
let address = unsafe { pcid_handle.map_bar(0).ptr };
- let interrupt_vector = irq_helpers::pci_allocate_interrupt_vector(&mut pcid_handle, "nvmed");
+ let interrupt_vector = match irq_helpers::pci_allocate_interrupt_vector(&mut pcid_handle, "nvmed") {
+ Some(iv) => iv,
+ None => {
+ log::error!("nvmed: no interrupt vector available, exiting");
+ std::process::exit(1);
+ }
+ };
let iv = interrupt_vector.vector();
let irq_handle = interrupt_vector.irq_handle().try_clone().unwrap();
@@ -0,0 +1,195 @@
diff --git a/drivers/audio/ac97d/src/main.rs b/drivers/audio/ac97d/src/main.rs
index 641e3ef2..5878bf2d 100644
--- a/drivers/audio/ac97d/src/main.rs
+++ b/drivers/audio/ac97d/src/main.rs
@@ -22,8 +22,20 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
let mut name = pci_config.func.name();
name.push_str("_ac97");
- let bar0 = pci_config.func.bars[0].expect_port();
- let bar1 = pci_config.func.bars[1].expect_port();
+ let bar0 = match pci_config.func.bars[0].try_port() {
+ Some(port) => port,
+ None => {
+ eprintln!("ac97d: BAR 0 is not a port BAR");
+ std::process::exit(1);
+ }
+ };
+ let bar1 = match pci_config.func.bars[1].try_port() {
+ Some(port) => port,
+ None => {
+ eprintln!("ac97d: BAR 1 is not a port BAR");
+ std::process::exit(1);
+ }
+ };
let irq = pci_config
.func
diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs
index ced9dd56..0423c617 100644
--- a/drivers/graphics/ihdgd/src/device/mod.rs
+++ b/drivers/graphics/ihdgd/src/device/mod.rs
@@ -246,7 +246,7 @@ impl Device {
};
let gttmm = {
- let (phys, size) = func.bars[0].expect_mem();
+ let (phys, size) = func.bars[0].try_mem().ok_or_else(|| Error::new(ENODEV))?;
Arc::new(MmioRegion::new(
phys,
size,
@@ -255,7 +255,7 @@ impl Device {
};
log::info!("GTTMM {:X?}", gttmm);
let gm = {
- let (phys, size) = func.bars[2].expect_mem();
+ let (phys, size) = func.bars[2].try_mem().ok_or_else(|| Error::new(ENODEV))?;
MmioRegion::new(phys, size, common::MemoryType::WriteCombining)?
};
log::info!("GM {:X?}", gm);
diff --git a/drivers/pcid/src/driver_interface/bar.rs b/drivers/pcid/src/driver_interface/bar.rs
index b2c1d35b..dea0dce4 100644
--- a/drivers/pcid/src/driver_interface/bar.rs
+++ b/drivers/pcid/src/driver_interface/bar.rs
@@ -29,27 +29,22 @@ impl PciBar {
}
}
- pub fn expect_port(&self) -> u16 {
+ pub fn try_port(&self) -> Option<u16> {
match *self {
- PciBar::Port(port) => port,
- PciBar::Memory32 { .. } | PciBar::Memory64 { .. } => {
- panic!("expected port BAR, found memory BAR");
- }
- PciBar::None => panic!("expected BAR to exist"),
+ PciBar::Port(port) => Some(port),
+ _ => None,
}
}
- pub fn expect_mem(&self) -> (usize, usize) {
+ pub fn try_mem(&self) -> Option<(usize, usize)> {
match *self {
- PciBar::Memory32 { addr, size } => (addr as usize, size as usize),
- PciBar::Memory64 { addr, size } => (
- addr.try_into()
- .expect("conversion from 64bit BAR to usize failed"),
- size.try_into()
- .expect("conversion from 64bit BAR size to usize failed"),
- ),
- PciBar::Port(_) => panic!("expected memory BAR, found port BAR"),
- PciBar::None => panic!("expected BAR to exist"),
+ PciBar::Memory32 { addr, size } => Some((addr as usize, size as usize)),
+ PciBar::Memory64 { addr, size } => {
+ let addr_usize = addr.try_into().ok()?;
+ let size_usize = size.try_into().ok()?;
+ Some((addr_usize, size_usize))
+ }
+ _ => None,
}
}
}
diff --git a/drivers/pcid/src/driver_interface/mod.rs b/drivers/pcid/src/driver_interface/mod.rs
index 7cecaa56..8776dd4a 100644
--- a/drivers/pcid/src/driver_interface/mod.rs
+++ b/drivers/pcid/src/driver_interface/mod.rs
@@ -457,7 +457,13 @@ impl PciFunctionHandle {
if let Some(mapped_bar) = mapped_bar {
mapped_bar
} else {
- let (bar, bar_size) = self.config.func.bars[bir as usize].expect_mem();
+ let (bar, bar_size) = match self.config.func.bars[bir as usize].try_mem() {
+ Some(bar) => bar,
+ None => {
+ log::error!("pcid: BAR {bir} is not a memory BAR");
+ process::exit(1);
+ }
+ };
let ptr = match unsafe {
common::physmap(
diff --git a/drivers/pcid/src/driver_interface/msi.rs b/drivers/pcid/src/driver_interface/msi.rs
index 0ca68ec5..e7e3f082 100644
--- a/drivers/pcid/src/driver_interface/msi.rs
+++ b/drivers/pcid/src/driver_interface/msi.rs
@@ -80,8 +80,20 @@ impl MsixInfo {
let pba_offset = self.pba_offset as usize;
let pba_min_length = table_size.div_ceil(8);
- let (_, table_bar_size) = bars[self.table_bar as usize].expect_mem();
- let (_, pba_bar_size) = bars[self.pba_bar as usize].expect_mem();
+ let (_, table_bar_size) = match bars[self.table_bar as usize].try_mem() {
+ Some(bar) => bar,
+ None => {
+ log::error!("MSI-X table BAR {} is not a memory BAR", self.table_bar);
+ return;
+ }
+ };
+ let (_, pba_bar_size) = match bars[self.pba_bar as usize].try_mem() {
+ Some(bar) => bar,
+ None => {
+ log::error!("MSI-X PBA BAR {} is not a memory BAR", self.pba_bar);
+ return;
+ }
+ };
// Ensure that the table and PBA are within the BAR.
diff --git a/drivers/storage/ided/src/main.rs b/drivers/storage/ided/src/main.rs
index 4197217d..9615710b 100644
--- a/drivers/storage/ided/src/main.rs
+++ b/drivers/storage/ided/src/main.rs
@@ -43,7 +43,13 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
// Get controller DMA capable
let dma = pci_config.func.full_device_id.interface & 0x80 != 0;
- let busmaster_base = pci_config.func.bars[4].expect_port();
+ let busmaster_base = match pci_config.func.bars[4].try_port() {
+ Some(port) => port,
+ None => {
+ log::error!("ided: BAR 4 is not a port BAR");
+ std::process::exit(1);
+ }
+ };
let (primary, primary_irq) = if pci_config.func.full_device_id.interface & 1 != 0 {
panic!("TODO: IDE primary channel is PCI native");
} else {
diff --git a/drivers/vboxd/src/main.rs b/drivers/vboxd/src/main.rs
index bcb9bb15..52328e79 100644
--- a/drivers/vboxd/src/main.rs
+++ b/drivers/vboxd/src/main.rs
@@ -199,7 +199,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
let mut name = pci_config.func.name();
name.push_str("_vbox");
- let bar0 = pci_config.func.bars[0].expect_port();
+ let bar0 = match pci_config.func.bars[0].try_port() {
+ Some(port) => port,
+ None => {
+ eprintln!("vboxd: BAR 0 is not a port BAR");
+ std::process::exit(1);
+ }
+ };
let irq = pci_config
.func
diff --git a/drivers/virtio-core/src/probe.rs b/drivers/virtio-core/src/probe.rs
index 5631ef67..06f0ba1a 100644
--- a/drivers/virtio-core/src/probe.rs
+++ b/drivers/virtio-core/src/probe.rs
@@ -55,7 +55,13 @@ pub fn probe_device(pcid_handle: &mut PciFunctionHandle) -> Result<Device, Error
_ => continue,
}
- let (addr, _) = pci_config.func.bars[capability.bar as usize].expect_mem();
+ let (addr, _) = match pci_config.func.bars[capability.bar as usize].try_mem() {
+ Some(bar) => bar,
+ None => {
+ log::warn!("virtio-core: BAR {} is not a memory BAR, skipping capability", capability.bar);
+ continue;
+ }
+ };
let address = unsafe {
let addr = addr + capability.offset as usize;
@@ -0,0 +1,176 @@
diff --git a/drivers/acpid/src/main.rs b/drivers/acpid/src/main.rs
index b05102f6..a9d47e09 100644
--- a/drivers/acpid/src/main.rs
+++ b/drivers/acpid/src/main.rs
@@ -204,6 +204,6 @@ fn daemon(daemon: daemon::Daemon) -> ! {
}
fn main() {
- common::init();
+ if let Err(err) = common::init() { eprintln!("acpid: failed to initialize common: {err}"); std::process::exit(1); }
daemon::Daemon::new(daemon);
}
diff --git a/drivers/common/src/lib.rs b/drivers/common/src/lib.rs
index b6661e3a..a55014b9 100644
--- a/drivers/common/src/lib.rs
+++ b/drivers/common/src/lib.rs
@@ -29,22 +29,13 @@ use std::sync::OnceLock;
static MEMORY_ROOT_FD: OnceLock<libredox::Fd> = OnceLock::new();
/// Initializes a file descriptor to be used as the root memory for a driver.
-///
-/// # Panics
-///
-/// This function will panic if:
-/// - `libredox` is unable to open a file descriptor.
-/// - The memory root file descriptor has already been set (this function has already been called).
-pub fn init() {
- if MEMORY_ROOT_FD
- .set(
- libredox::Fd::open("/scheme/memory/scheme-root", 0, 0)
- .expect("drivers common: failed to open memory root fd"),
- )
- .is_err()
- {
- panic!("drivers common: failed to set memory root fd");
- }
+pub fn init() -> std::io::Result<()> {
+ let fd = libredox::Fd::open("/scheme/memory/scheme-root", 0, 0)
+ .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, format!("failed to open memory root fd: {err}")))?;
+ MEMORY_ROOT_FD
+ .set(fd)
+ .map_err(|_| std::io::Error::new(std::io::ErrorKind::AlreadyExists, "memory root fd already initialized"))?;
+ Ok(())
}
/// Gets the memory root file descriptor.
diff --git a/drivers/gpio/intel-gpiod/src/main.rs b/drivers/gpio/intel-gpiod/src/main.rs
index aa651713..e9671068 100644
--- a/drivers/gpio/intel-gpiod/src/main.rs
+++ b/drivers/gpio/intel-gpiod/src/main.rs
@@ -95,7 +95,7 @@ fn daemon_runner(daemon: daemon::Daemon) -> ! {
}
fn daemon_main(daemon: daemon::Daemon) -> Result<()> {
- common::init();
+ common::init().map_err(|err| anyhow::anyhow!("failed to initialize common: {err}"))?;
let controllers =
discover_controllers(SUPPORTED_IDS).context("failed to discover Intel GPIO controllers")?;
diff --git a/drivers/graphics/fbbootlogd/src/main.rs b/drivers/graphics/fbbootlogd/src/main.rs
index 055e1db6..b8ad2294 100644
--- a/drivers/graphics/fbbootlogd/src/main.rs
+++ b/drivers/graphics/fbbootlogd/src/main.rs
@@ -21,7 +21,7 @@ use crate::scheme::FbbootlogScheme;
mod scheme;
fn main() {
- common::init();
+ if let Err(err) = common::init() { eprintln!("fbbootlogd: failed to initialize common: {err}"); std::process::exit(1); }
daemon::SchemeDaemon::new(daemon);
}
fn daemon(daemon: daemon::SchemeDaemon) -> ! {
diff --git a/drivers/graphics/fbcond/src/main.rs b/drivers/graphics/fbcond/src/main.rs
index 2e428353..003527ba 100644
--- a/drivers/graphics/fbcond/src/main.rs
+++ b/drivers/graphics/fbcond/src/main.rs
@@ -16,7 +16,7 @@ mod scheme;
mod text;
fn main() {
- common::init();
+ if let Err(err) = common::init() { eprintln!("fbcond: failed to initialize common: {err}"); std::process::exit(1); }
daemon::SchemeDaemon::new(daemon);
}
fn daemon(daemon: daemon::SchemeDaemon) -> ! {
diff --git a/drivers/graphics/vesad/src/main.rs b/drivers/graphics/vesad/src/main.rs
index 6f55913b..5fee9041 100644
--- a/drivers/graphics/vesad/src/main.rs
+++ b/drivers/graphics/vesad/src/main.rs
@@ -12,7 +12,7 @@ use crate::scheme::{FbAdapter, FrameBuffer};
mod scheme;
fn main() {
- common::init();
+ if let Err(err) = common::init() { eprintln!("vesad: failed to initialize common: {err}"); std::process::exit(1); }
daemon::Daemon::new(daemon);
}
fn daemon(daemon: daemon::Daemon) -> ! {
diff --git a/drivers/i2c/dw-acpi-i2cd/src/main.rs b/drivers/i2c/dw-acpi-i2cd/src/main.rs
index 796d0ed3..f3491103 100644
--- a/drivers/i2c/dw-acpi-i2cd/src/main.rs
+++ b/drivers/i2c/dw-acpi-i2cd/src/main.rs
@@ -80,7 +80,7 @@ fn daemon_runner(daemon: daemon::Daemon) -> ! {
}
fn daemon_main(daemon: daemon::Daemon) -> Result<()> {
- common::init();
+ common::init().map_err(|err| anyhow::anyhow!("failed to initialize common: {err}"))?;
let controllers = discover_controllers(SUPPORTED_IDS)
.context("failed to discover DesignWare ACPI I2C controllers")?;
diff --git a/drivers/i2c/intel-lpss-i2cd/src/main.rs b/drivers/i2c/intel-lpss-i2cd/src/main.rs
index 7b29d737..e651610b 100644
--- a/drivers/i2c/intel-lpss-i2cd/src/main.rs
+++ b/drivers/i2c/intel-lpss-i2cd/src/main.rs
@@ -80,7 +80,7 @@ fn daemon_runner(daemon: daemon::Daemon) -> ! {
}
fn daemon_main(daemon: daemon::Daemon) -> Result<()> {
- common::init();
+ common::init().map_err(|err| anyhow::anyhow!("failed to initialize common: {err}"))?;
let controllers = discover_controllers(SUPPORTED_IDS)
.context("failed to discover Intel LPSS ACPI I2C controllers")?;
diff --git a/drivers/pcid/src/driver_interface/mod.rs b/drivers/pcid/src/driver_interface/mod.rs
index 8776dd4a..3b6a98a1 100644
--- a/drivers/pcid/src/driver_interface/mod.rs
+++ b/drivers/pcid/src/driver_interface/mod.rs
@@ -491,7 +491,7 @@ impl PciFunctionHandle {
pub fn pci_daemon<F: FnOnce(Daemon, PciFunctionHandle) -> !>(f: F) -> ! {
Daemon::new(|daemon| {
- common::init();
+ if let Err(err) = common::init() { eprintln!("pci_daemon: failed to initialize common: {err}"); std::process::exit(1); }
let pcid_handle = PciFunctionHandle::connect_default();
f(daemon, pcid_handle)
})
diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs
index bda473e4..e844249f 100644
--- a/drivers/pcid/src/main.rs
+++ b/drivers/pcid/src/main.rs
@@ -245,7 +245,7 @@ fn enable_function(
}
fn main() {
- common::init();
+ if let Err(err) = common::init() { eprintln!("pcid: failed to initialize common: {err}"); std::process::exit(1); }
daemon::Daemon::new(daemon);
}
diff --git a/drivers/usb/usbctl/src/main.rs b/drivers/usb/usbctl/src/main.rs
index 9b5773d9..51a63f75 100644
--- a/drivers/usb/usbctl/src/main.rs
+++ b/drivers/usb/usbctl/src/main.rs
@@ -2,7 +2,7 @@ use clap::{Arg, Command};
use xhcid_interface::{PortId, XhciClientHandle};
fn main() {
- common::init();
+ if let Err(err) = common::init() { eprintln!("usbctl: failed to initialize common: {err}"); std::process::exit(1); }
let matches = Command::new("usbctl")
.arg(
Arg::new("SCHEME")
diff --git a/drivers/usb/usbhubd/src/main.rs b/drivers/usb/usbhubd/src/main.rs
index 2c8b9876..7e69842a 100644
--- a/drivers/usb/usbhubd/src/main.rs
+++ b/drivers/usb/usbhubd/src/main.rs
@@ -6,7 +6,7 @@ use xhcid_interface::{
};
fn main() {
- common::init();
+ if let Err(err) = common::init() { eprintln!("usbhubd: failed to initialize common: {err}"); std::process::exit(1); }
let mut args = env::args().skip(1);
const USAGE: &'static str = "usbhubd <scheme> <port> <interface>";
@@ -0,0 +1,87 @@
diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs
index b6683686..cd064ae6 100644
--- a/drivers/graphics/driver-graphics/src/lib.rs
+++ b/drivers/graphics/driver-graphics/src/lib.rs
@@ -133 +133 @@ pub struct GraphicsScheme<T: GraphicsAdapter> {
- inputd_handle: DisplayHandle,
+ inputd_handle: Option<DisplayHandle>,
@@ -187,6 +187 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- DisplayHandle::new_early(&inner.scheme_name).map_err(|e| {
- io::Error::new(
- io::ErrorKind::Other,
- format!("failed to create early display handle: {e}"),
- )
- })?
+ DisplayHandle::new_early(&inner.scheme_name)
@@ -194,6 +189,13 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- DisplayHandle::new(&inner.scheme_name).map_err(|e| {
- io::Error::new(
- io::ErrorKind::Other,
- format!("failed to create display handle: {e}"),
- )
- })?
+ DisplayHandle::new(&inner.scheme_name)
+ };
+
+ let inputd_handle = match display_handle {
+ Ok(handle) => Some(handle),
+ Err(err) => {
+ log::warn!(
+ "{}: display input handle unavailable ({}), continuing without VT input",
+ inner.scheme_name,
+ err
+ );
+ None
+ }
@@ -204 +206 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- inputd_handle: display_handle,
+ inputd_handle,
@@ -213,2 +215,2 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- pub fn inputd_event_handle(&self) -> BorrowedFd<'_> {
- self.inputd_handle.inner()
+ pub fn inputd_event_handle(&self) -> Option<BorrowedFd<'_>> {
+ self.inputd_handle.as_ref().map(|h| h.inner())
@@ -238,2 +240,5 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
- while let Some(vt_event) = self
- .inputd_handle
+ let inputd_handle = match self.inputd_handle.as_mut() {
+ Some(h) => h,
+ None => return,
+ };
+ while let Some(vt_event) = inputd_handle
diff --git a/drivers/graphics/ihdgd/src/main.rs b/drivers/graphics/ihdgd/src/main.rs
index 4aa21caa..964510f5 100644
--- a/drivers/graphics/ihdgd/src/main.rs
+++ b/drivers/graphics/ihdgd/src/main.rs
@@ -65,0 +66 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
+ if let Some(inputd_fd) = scheme.inputd_event_handle() {
@@ -68 +69 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
- scheme.inputd_event_handle().as_raw_fd() as usize,
+ inputd_fd.as_raw_fd() as usize,
@@ -72,0 +74 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
+ }
diff --git a/drivers/graphics/vesad/src/main.rs b/drivers/graphics/vesad/src/main.rs
index 6f55913b..c19629aa 100644
--- a/drivers/graphics/vesad/src/main.rs
+++ b/drivers/graphics/vesad/src/main.rs
@@ -163,0 +164 @@ fn daemon(daemon: daemon::Daemon) -> ! {
+ if let Some(inputd_fd) = scheme.inputd_event_handle() {
@@ -165 +166 @@ fn daemon(daemon: daemon::Daemon) -> ! {
- scheme.inputd_event_handle().as_raw_fd() as usize,
+ inputd_fd.as_raw_fd() as usize,
@@ -172,0 +174 @@ fn daemon(daemon: daemon::Daemon) -> ! {
+ }
diff --git a/drivers/graphics/virtio-gpud/src/main.rs b/drivers/graphics/virtio-gpud/src/main.rs
index b27f4c56..3aa41c74 100644
--- a/drivers/graphics/virtio-gpud/src/main.rs
+++ b/drivers/graphics/virtio-gpud/src/main.rs
@@ -552,0 +553 @@ fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow:
+ if let Some(inputd_fd) = scheme.inputd_event_handle() {
@@ -555 +556 @@ fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow:
- scheme.inputd_event_handle().as_raw_fd() as usize,
+ inputd_fd.as_raw_fd() as usize,
@@ -559,0 +561 @@ fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow:
+ }
@@ -0,0 +1,14 @@
diff --git a/init.d/10_dhcpd.service b/init.d/10_dhcpd.service
index daba3bd1..494fb536 100644
--- a/init.d/10_dhcpd.service
+++ b/init.d/10_dhcpd.service
@@ -3 +3 @@ description = "Configure network using DHCP"
-requires_weak = [
+requires = [
diff --git a/init.initfs.d/61_dhcpd.service b/init.initfs.d/61_dhcpd.service
index 37379761..858bc297 100644
--- a/init.initfs.d/61_dhcpd.service
+++ b/init.initfs.d/61_dhcpd.service
@@ -3 +3 @@ description = "DHCP Client"
-requires_weak = ["60_smolnetd.service"]
+requires = ["60_smolnetd.service"]