Skip to content

Commit 5902dc0

Browse files
authored
Merge pull request #320 from zaheerm/ephemeral-storage-mnt-prefix
Allow bind mounts prefixed with /mnt/ for ephemeral storage
2 parents f837568 + 8e028ee commit 5902dc0

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

sources/api/apiserver/src/server/ephemeral_storage.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ static EPHEMERAL_MNT: &str = ".ephemeral";
2323
static RAID_DEVICE_DIR: &str = "/dev/md/";
2424
static RAID_DEVICE_NAME: &str = "ephemeral";
2525

26+
pub struct BindDirs {
27+
pub allowed_exact: HashSet<&'static str>,
28+
pub allowed_prefixes: HashSet<&'static str>,
29+
pub disallowed_contains: HashSet<&'static str>,
30+
}
31+
2632
/// initialize prepares the ephemeral storage for formatting and formats it. For multiple disks
2733
/// preparation is the creation of a RAID0 array, for a single disk this is a no-op. The array or disk
2834
/// is then formatted with the specified filesystem (default=xfs) if not formatted already.
@@ -116,8 +122,17 @@ pub fn bind(variant: &str, dirs: Vec<String>) -> Result<()> {
116122
let mount_point = Path::new(&mount_point);
117123
let allowed_dirs = allowed_bind_dirs(variant);
118124
for dir in &dirs {
125+
let exact_match = allowed_dirs.allowed_exact.contains(dir.as_str());
126+
let prefix_match = allowed_dirs
127+
.allowed_prefixes
128+
.iter()
129+
.any(|prefix| dir.starts_with(prefix));
130+
let disallowed_match = allowed_dirs
131+
.disallowed_contains
132+
.iter()
133+
.any(|contains| dir.contains(contains));
119134
ensure!(
120-
allowed_dirs.contains(dir.as_str()),
135+
exact_match || (prefix_match && !disallowed_match),
121136
error::InvalidParameterSnafu {
122137
parameter: dir,
123138
reason: "specified bind directory not in allow list",
@@ -269,18 +284,26 @@ pub fn ephemeral_devices() -> Result<Vec<String>> {
269284
}
270285

271286
/// allowed_bind_dirs returns a set of the directories that can be bound to ephemeral storage, which
272-
/// varies based on the variant
273-
pub fn allowed_bind_dirs(variant: &str) -> HashSet<&'static str> {
274-
let mut allowed = HashSet::from(["/var/lib/containerd", "/var/lib/host-containerd"]);
287+
/// varies based on the variant, a set of the prefixes of directories that are allowed to be bound.
288+
/// and a set of substrings that are disallowed in the directory name.
289+
pub fn allowed_bind_dirs(variant: &str) -> BindDirs {
290+
let mut allowed_exact = HashSet::from(["/var/lib/containerd", "/var/lib/host-containerd"]);
275291
if variant.contains("k8s") {
276-
allowed.insert("/var/lib/kubelet");
277-
allowed.insert("/var/log/pods");
292+
allowed_exact.insert("/var/lib/kubelet");
293+
allowed_exact.insert("/var/log/pods");
278294
}
279295
if variant.contains("ecs") {
280-
allowed.insert("/var/lib/docker");
281-
allowed.insert("/var/log/ecs");
296+
allowed_exact.insert("/var/lib/docker");
297+
allowed_exact.insert("/var/log/ecs");
298+
}
299+
let allowed_prefixes = HashSet::from(["/mnt/"]);
300+
let disallowed_contains = HashSet::from(["..", "/mnt/.ephemeral"]);
301+
302+
BindDirs {
303+
allowed_exact,
304+
allowed_prefixes,
305+
disallowed_contains,
282306
}
283-
allowed
284307
}
285308

286309
/// scans the raid array to identify if it has been created already

sources/api/apiserver/src/server/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,18 +703,22 @@ async fn list_ephemeral_storage_dirs(
703703
) -> Result<HttpResponse> {
704704
let os_info = controller::get_os_info()?;
705705

706-
let allowed = ephemeral_storage::allowed_bind_dirs(&os_info.variant_id);
706+
let allowed_dirs = ephemeral_storage::allowed_bind_dirs(&os_info.variant_id);
707707
let mut text_response = String::new();
708-
for dir in &allowed {
708+
for dir in &allowed_dirs.allowed_exact {
709709
text_response.push_str(dir);
710710
text_response.push('\n');
711711
}
712712

713-
let allowed: Vec<String> = allowed.iter().map(|x| String::from(*x)).collect();
713+
let allowed: Vec<String> = allowed_dirs
714+
.allowed_exact
715+
.iter()
716+
.map(|x| String::from(*x))
717+
.collect();
714718
list_ephemeral_response(req, query, allowed, text_response).await
715719
}
716720

717-
// Responds to a list request with the text or JSON resposne depending on the query format.
721+
// Responds to a list request with the text or JSON response depending on the query format.
718722
async fn list_ephemeral_response(
719723
req: HttpRequest,
720724
query: web::Query<HashMap<String, String>>,

0 commit comments

Comments
 (0)