194 lines
6.1 KiB
Diff
194 lines
6.1 KiB
Diff
From 8123dcec5160b0d29e541cec1c9a027a1dd42c48 Mon Sep 17 00:00:00 2001
|
|
From: licunlong <licunlong1@huawei.com>
|
|
Date: Wed, 14 Jun 2023 15:52:40 +0800
|
|
Subject: [PATCH] fix: check if the given unit name is valid before we prepare
|
|
the unit
|
|
|
|
---
|
|
core/bin/unit/base/load.rs | 8 -----
|
|
core/bin/unit/manager.rs | 8 ++++-
|
|
core/bin/unit/uload.rs | 6 +++-
|
|
core/lib/unit/base.rs | 70 ++++++++++++++++++++++++++++++++++++++
|
|
core/lib/unit/mod.rs | 3 +-
|
|
5 files changed, 84 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/core/bin/unit/base/load.rs b/core/bin/unit/base/load.rs
|
|
index 2281d06..700237d 100644
|
|
--- a/core/bin/unit/base/load.rs
|
|
+++ b/core/bin/unit/base/load.rs
|
|
@@ -10,14 +10,6 @@
|
|
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
// See the Mulan PSL v2 for more details.
|
|
|
|
-#[allow(dead_code)]
|
|
-enum UnitNameFlags {
|
|
- Plain = 1,
|
|
- Instance = 2,
|
|
- Template = 4,
|
|
- Any = 1 | 2 | 4,
|
|
-}
|
|
-
|
|
#[allow(dead_code)]
|
|
enum UnitFileState {
|
|
Enabled,
|
|
diff --git a/core/bin/unit/manager.rs b/core/bin/unit/manager.rs
|
|
index 4b3f4fb..cb5d957 100644
|
|
--- a/core/bin/unit/manager.rs
|
|
+++ b/core/bin/unit/manager.rs
|
|
@@ -50,7 +50,10 @@ use sysmaster::error::*;
|
|
use sysmaster::exec::ExecParameters;
|
|
use sysmaster::exec::{ExecCommand, ExecContext};
|
|
use sysmaster::rel::{ReStation, ReStationKind, ReliLastFrame, Reliability};
|
|
-use sysmaster::unit::{UmIf, UnitActiveState, UnitDependencyMask, UnitStatus, UnitType};
|
|
+use sysmaster::unit::{
|
|
+ unit_name_is_valid, UmIf, UnitActiveState, UnitDependencyMask, UnitNameFlags, UnitStatus,
|
|
+ UnitType,
|
|
+};
|
|
use unit_submanager::UnitSubManagers;
|
|
|
|
//#[derive(Debug)]
|
|
@@ -525,6 +528,9 @@ impl UnitManager {
|
|
|
|
///
|
|
pub fn units_get(&self, name: &str) -> Option<Rc<Unit>> {
|
|
+ if !unit_name_is_valid(name, UnitNameFlags::PLAIN | UnitNameFlags::INSTANCE) {
|
|
+ return None;
|
|
+ }
|
|
self.db.units_get(name).map(|uxr| uxr.unit())
|
|
}
|
|
|
|
diff --git a/core/bin/unit/uload.rs b/core/bin/unit/uload.rs
|
|
index d972fb4..d6fea43 100644
|
|
--- a/core/bin/unit/uload.rs
|
|
+++ b/core/bin/unit/uload.rs
|
|
@@ -22,7 +22,7 @@ use crate::utils::table::{TableOp, TableSubscribe};
|
|
use basic::path_lookup::LookupPaths;
|
|
use std::cell::RefCell;
|
|
use std::rc::{Rc, Weak};
|
|
-use sysmaster::unit::UnitType;
|
|
+use sysmaster::unit::{unit_name_is_valid, UnitNameFlags, UnitType};
|
|
|
|
//#[derive(Debug)]
|
|
pub(super) struct UnitLoad {
|
|
@@ -100,6 +100,10 @@ impl UnitLoadData {
|
|
}
|
|
|
|
pub(self) fn prepare_unit(&self, name: &str) -> Option<Rc<UnitX>> {
|
|
+ if !unit_name_is_valid(name, UnitNameFlags::PLAIN | UnitNameFlags::INSTANCE) {
|
|
+ return None;
|
|
+ }
|
|
+
|
|
if let Some(u) = self.db.units_get(name) {
|
|
if u.load_state() != UnitLoadState::NotFound {
|
|
return Some(Rc::clone(&u));
|
|
diff --git a/core/lib/unit/base.rs b/core/lib/unit/base.rs
|
|
index f066ed7..555bb69 100644
|
|
--- a/core/lib/unit/base.rs
|
|
+++ b/core/lib/unit/base.rs
|
|
@@ -14,10 +14,14 @@ use super::super::rel::ReStation;
|
|
use super::kill::{KillContext, KillOperation};
|
|
use super::state::{UnitActiveState, UnitNotifyFlags};
|
|
use super::umif::UnitMngUtil;
|
|
+use super::UnitType;
|
|
use crate::error::*;
|
|
+use bitflags::bitflags;
|
|
use nix::sys::wait::WaitStatus;
|
|
use nix::{sys::socket::UnixCredentials, unistd::Pid};
|
|
use std::any::Any;
|
|
+use std::num::ParseIntError;
|
|
+use std::str::FromStr;
|
|
use std::{collections::HashMap, path::PathBuf, rc::Rc};
|
|
|
|
///The trait Defining Shared Behavior from Base Unit to SUB unit
|
|
@@ -206,3 +210,69 @@ macro_rules! declure_unitobj_plugin_with_param {
|
|
}
|
|
};
|
|
}
|
|
+
|
|
+bitflags! {
|
|
+ /// used to when check the given unit name is valid
|
|
+ pub struct UnitNameFlags: u8 {
|
|
+ /// Allow foo.service
|
|
+ const PLAIN = 1 << 0;
|
|
+ /// Allow foo@.service
|
|
+ const TEMPLATE = 1 << 1;
|
|
+ /// Allow foo@123.service
|
|
+ const INSTANCE = 1 << 2;
|
|
+ /// Any of the above
|
|
+ const ANY = Self::PLAIN.bits() | Self::TEMPLATE.bits() | Self::INSTANCE.bits();
|
|
+ }
|
|
+}
|
|
+
|
|
+/// The maximum length of a valid unit name
|
|
+const UNIT_NAME_MAX: usize = 255;
|
|
+
|
|
+/// check if the given unit name is valid
|
|
+pub fn unit_name_is_valid(name: &str, flag: UnitNameFlags) -> bool {
|
|
+ if name.is_empty() {
|
|
+ return false;
|
|
+ }
|
|
+ if name.len() > UNIT_NAME_MAX {
|
|
+ return false;
|
|
+ }
|
|
+ /* Take foo@123.service for example, "foo@123" is its first_name,
|
|
+ * "foo" is prefix, "service" is its last_name, suffix, or type. */
|
|
+ let (first_name, last_name) = match name.split_once('.') {
|
|
+ None => return false,
|
|
+ Some(v) => (v.0, v.1),
|
|
+ };
|
|
+
|
|
+ let unit_type = match unit_type_from_string(last_name) {
|
|
+ Err(_) => return false,
|
|
+ Ok(v) => v,
|
|
+ };
|
|
+
|
|
+ if unit_type == UnitType::UnitTypeInvalid {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ match first_name.split_once('@') {
|
|
+ None => flag.contains(UnitNameFlags::PLAIN),
|
|
+ Some(v) => {
|
|
+ /* "@" is the first character */
|
|
+ if v.0.is_empty() {
|
|
+ return false;
|
|
+ }
|
|
+ /* "@" is the last character */
|
|
+ if v.1.is_empty() {
|
|
+ return flag.contains(UnitNameFlags::TEMPLATE);
|
|
+ }
|
|
+ /* there is more than one "@" */
|
|
+ if v.1.contains('@') {
|
|
+ return false;
|
|
+ }
|
|
+ flag.contains(UnitNameFlags::INSTANCE)
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/// convert the type string of one unit to UnitType
|
|
+pub fn unit_type_from_string(type_string: &str) -> Result<UnitType, ParseIntError> {
|
|
+ UnitType::from_str(type_string)
|
|
+}
|
|
diff --git a/core/lib/unit/mod.rs b/core/lib/unit/mod.rs
|
|
index 7211aec..1eb565c 100644
|
|
--- a/core/lib/unit/mod.rs
|
|
+++ b/core/lib/unit/mod.rs
|
|
@@ -11,11 +11,12 @@
|
|
// See the Mulan PSL v2 for more details.
|
|
|
|
//!
|
|
-pub use base::{SubUnit, UnitBase};
|
|
+pub use base::{unit_name_is_valid, SubUnit, UnitBase, UnitNameFlags};
|
|
pub use deps::{UnitDependencyMask, UnitRelationAtom, UnitRelations, UnitType};
|
|
pub use kill::{KillContext, KillMode, KillOperation};
|
|
pub use state::{UnitActiveState, UnitNotifyFlags, UnitStatus};
|
|
pub use umif::{UmIf, UnitManagerObj, UnitMngUtil};
|
|
+
|
|
mod base;
|
|
mod deps;
|
|
mod kill;
|
|
--
|
|
2.30.2
|
|
|