all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Christoph Heiss <c.heiss@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH installer 2/6] common: pinning: make interface name checks stricter
Date: Thu, 13 Nov 2025 14:49:50 +0100	[thread overview]
Message-ID: <20251113135023.1038305-3-c.heiss@proxmox.com> (raw)
In-Reply-To: <20251113135023.1038305-1-c.heiss@proxmox.com>

According to our `pve-iface` schema, names must be at least two
characters long and start with a (latin) letter.

Reported-by: Stoiko Ivanov <s.ivanov@proxmox.com>
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
 proxmox-installer-common/src/lib.rs     |  7 ++--
 proxmox-installer-common/src/options.rs | 46 ++++++++++++++++++++-----
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/proxmox-installer-common/src/lib.rs b/proxmox-installer-common/src/lib.rs
index a85d5f8..b380f1c 100644
--- a/proxmox-installer-common/src/lib.rs
+++ b/proxmox-installer-common/src/lib.rs
@@ -11,8 +11,11 @@ pub mod http;
 pub mod cli;
 
 pub mod net {
-    /// Maximum length of the (primary) name of a network interface
-    pub const MAX_IFNAME_LEN: usize = 15; // IFNAMSIZ - 1 to account for NUL byte
+    /// As dictated by the `pve-iface` schema.
+    pub const MIN_IFNAME_LEN: usize = 2;
+    /// Maximum length of the (primary) name of a network interface.
+    /// IFNAMSIZ - 1 to account for NUL byte
+    pub const MAX_IFNAME_LEN: usize = 15;
 }
 
 pub const RUNTIME_DIR: &str = "/run/proxmox-installer";
diff --git a/proxmox-installer-common/src/options.rs b/proxmox-installer-common/src/options.rs
index 0d72f54..a07fe58 100644
--- a/proxmox-installer-common/src/options.rs
+++ b/proxmox-installer-common/src/options.rs
@@ -8,7 +8,7 @@ use std::sync::OnceLock;
 use std::{cmp, fmt};
 
 use crate::disk_checks::check_raid_min_disks;
-use crate::net::MAX_IFNAME_LEN;
+use crate::net::{MAX_IFNAME_LEN, MIN_IFNAME_LEN};
 use crate::setup::{LocaleInfo, NetworkInfo, RuntimeInfo, SetupInfo};
 use crate::utils::{CidrAddress, Fqdn};
 
@@ -504,8 +504,10 @@ impl NetworkInterfacePinningOptions {
     pub fn verify(&self) -> Result<()> {
         let mut reverse_mapping = HashMap::<String, String>::new();
         for (mac, name) in self.mapping.iter() {
-            if name.is_empty() {
-                bail!("interface name for '{mac}' cannot be empty");
+            if name.len() < MIN_IFNAME_LEN {
+                bail!(
+                    "interface name for '{mac}' must be at least {MIN_IFNAME_LEN} characters long"
+                );
             }
 
             if name.len() > MAX_IFNAME_LEN {
@@ -522,9 +524,9 @@ impl NetworkInterfacePinningOptions {
             }
 
             // Mimicking the `pve-iface` schema verification
-            if name.starts_with(|c: char| c.is_ascii_digit()) {
+            if !name.starts_with(|c: char| c.is_ascii_alphabetic()) {
                 bail!(
-                    "interface name '{name}' for '{mac}' is invalid: name must not start with a number"
+                    "interface name '{name}' for '{mac}' is invalid: name must start with a letter"
                 );
             }
 
@@ -943,7 +945,22 @@ mod tests {
         assert!(res.is_err());
         assert_eq!(
             res.unwrap_err().to_string(),
-            "interface name for 'ab:cd:ef:12:34:56' cannot be empty"
+            "interface name for 'ab:cd:ef:12:34:56' must be at least 2 characters long"
+        )
+    }
+
+    #[test]
+    fn network_interface_pinning_options_fail_on_too_short_name() {
+        let mut options = NetworkInterfacePinningOptions::default();
+        options
+            .mapping
+            .insert("ab:cd:ef:12:34:56".to_owned(), "a".to_owned());
+
+        let res = options.verify();
+        assert!(res.is_err());
+        assert_eq!(
+            res.unwrap_err().to_string(),
+            "interface name for 'ab:cd:ef:12:34:56' must be at least 2 characters long"
         )
     }
 
@@ -1000,7 +1017,7 @@ mod tests {
     }
 
     #[test]
-    fn network_interface_pinning_options_fail_on_name_starting_with_number() {
+    fn network_interface_pinning_options_fail_on_nonletter_first_char() {
         let mut options = NetworkInterfacePinningOptions::default();
         options
             .mapping
@@ -1010,8 +1027,19 @@ mod tests {
         assert!(res.is_err());
         assert_eq!(
             res.unwrap_err().to_string(),
-            "interface name '0nic' for 'ab:cd:ef:12:34:56' is invalid: name must not start with a number"
-        )
+            "interface name '0nic' for 'ab:cd:ef:12:34:56' is invalid: name must start with a letter"
+        );
+
+        options
+            .mapping
+            .insert("ab:cd:ef:12:34:56".to_owned(), "_a".to_owned());
+
+        let res = options.verify();
+        assert!(res.is_err());
+        assert_eq!(
+            res.unwrap_err().to_string(),
+            "interface name '_a' for 'ab:cd:ef:12:34:56' is invalid: name must start with a letter"
+        );
     }
 
     #[test]
-- 
2.51.0



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  parent reply	other threads:[~2025-11-13 13:50 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-13 13:49 [pve-devel] [PATCH installer 0/6] interface name pinning followups Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 1/6] sys: net: pinning: make interface name checks stricter Christoph Heiss
2025-11-13 13:49 ` Christoph Heiss [this message]
2025-11-13 13:49 ` [pve-devel] [PATCH installer 3/6] test: validate-link-pin-map: give all tests a name Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 4/6] gui: network: only display pinnable devices in pinning options dialog Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 5/6] tui: " Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 6/6] tree-wide: run cargo fmt Christoph Heiss
2025-11-13 20:00 ` [pve-devel] applied: [PATCH installer 0/6] interface name pinning followups Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251113135023.1038305-3-c.heiss@proxmox.com \
    --to=c.heiss@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal