Skip to content

Commit 897a16c

Browse files
committed
Avoid CodeQL command and path findings
1 parent 9d75ca6 commit 897a16c

2 files changed

Lines changed: 63 additions & 80 deletions

File tree

scripts/build_fluxheim_rpm.py

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,24 @@ def run_container_build(
9494
build_type: str,
9595
rpm_release: str,
9696
) -> None:
97-
print(
98-
"Executing: "
99-
+ shlex.join(
97+
common_args = [
98+
"run",
99+
"--rm",
100+
"-v",
101+
f"{work_dir}:/workspace:Z",
102+
container_image,
103+
"bash",
104+
"/workspace/build_in_container.sh",
105+
version_tag,
106+
build_type,
107+
rpm_release,
108+
]
109+
if container_tool == "podman":
110+
command = ["podman", *common_args]
111+
print("Executing: " + shlex.join(command))
112+
subprocess.run(
100113
[
101-
container_tool,
114+
"podman",
102115
"run",
103116
"--rm",
104117
"-v",
@@ -109,25 +122,30 @@ def run_container_build(
109122
version_tag,
110123
build_type,
111124
rpm_release,
112-
]
125+
],
126+
check=True,
113127
)
114-
)
115-
subprocess.run(
116-
[
117-
container_tool,
118-
"run",
119-
"--rm",
120-
"-v",
121-
f"{work_dir}:/workspace:Z",
122-
container_image,
123-
"bash",
124-
"/workspace/build_in_container.sh",
125-
version_tag,
126-
build_type,
127-
rpm_release,
128-
],
129-
check=True,
130-
)
128+
elif container_tool == "docker":
129+
command = ["docker", *common_args]
130+
print("Executing: " + shlex.join(command))
131+
subprocess.run(
132+
[
133+
"docker",
134+
"run",
135+
"--rm",
136+
"-v",
137+
f"{work_dir}:/workspace:Z",
138+
container_image,
139+
"bash",
140+
"/workspace/build_in_container.sh",
141+
version_tag,
142+
build_type,
143+
rpm_release,
144+
],
145+
check=True,
146+
)
147+
else:
148+
raise SystemExit(f"error: unsupported container tool: {container_tool}")
131149

132150

133151
def choose_target(target: str | None) -> tuple[str, str]:

src/web.rs

Lines changed: 23 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -117,24 +117,20 @@ impl StaticFileServer {
117117
}
118118

119119
fn resolve_relative_candidate(&self, relative: &SafeRelativePath) -> io::Result<ResolveResult> {
120-
if path_contains_symlink(&self.root, relative)? {
121-
return Ok(ResolveResult::NotFound);
122-
}
123-
124120
let candidate = self.root.join(relative.as_path());
125-
let candidate = match candidate.canonicalize() {
121+
let canonical = match candidate.canonicalize() {
126122
Ok(path) => path,
127123
Err(error) if error.kind() == io::ErrorKind::NotFound => {
128124
return Ok(ResolveResult::NotFound);
129125
}
130126
Err(error) => return Err(error),
131127
};
132128

133-
if !candidate.starts_with(&self.root) {
129+
if !canonical.starts_with(&self.root) || canonical != candidate {
134130
return Ok(ResolveResult::NotFound);
135131
}
136132

137-
let candidate_metadata = match candidate.metadata() {
133+
let candidate_metadata = match canonical.metadata() {
138134
Ok(metadata) => metadata,
139135
Err(error) if error.kind() == io::ErrorKind::NotFound => {
140136
return Ok(ResolveResult::NotFound);
@@ -144,14 +140,14 @@ impl StaticFileServer {
144140

145141
if candidate_metadata.is_dir() {
146142
for index in &self.index_files {
147-
let index_candidate = candidate.join(index);
143+
let index_candidate = canonical.join(index);
148144
if let Some(file) = self.static_file(&index_candidate)? {
149145
return Ok(ResolveResult::Found(file));
150146
}
151147
}
152148

153149
if self.directory_listing.enabled {
154-
return self.directory_listing(&candidate);
150+
return self.directory_listing(&canonical);
155151
}
156152

157153
return Ok(ResolveResult::NotFound);
@@ -167,17 +163,15 @@ impl StaticFileServer {
167163
let Some(relative) = SafeRelativePath::from_rooted(&self.root, candidate) else {
168164
return Ok(None);
169165
};
170-
if path_contains_symlink(&self.root, &relative)? {
171-
return Ok(None);
172-
}
173166

167+
let expected = self.root.join(relative.as_path());
174168
let canonical = match candidate.canonicalize() {
175169
Ok(path) => path,
176170
Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(None),
177171
Err(error) => return Err(error),
178172
};
179173

180-
if !canonical.starts_with(&self.root) {
174+
if !canonical.starts_with(&self.root) || canonical != expected {
181175
return Ok(None);
182176
}
183177

@@ -208,7 +202,7 @@ impl StaticFileServer {
208202
let Some(relative) = SafeRelativePath::from_rooted(&self.root, directory) else {
209203
return Ok(ResolveResult::NotFound);
210204
};
211-
if path_contains_symlink(&self.root, &relative)? {
205+
if directory != self.root.join(relative.as_path()) {
212206
return Ok(ResolveResult::NotFound);
213207
}
214208
let mut entries = Vec::new();
@@ -293,56 +287,27 @@ impl SafeRelativePath {
293287
}
294288
}
295289

296-
fn normal_component(component: &std::ffi::OsStr) -> Option<&std::ffi::OsStr> {
297-
let mut components = Path::new(component).components();
298-
match (components.next(), components.next()) {
299-
(Some(std::path::Component::Normal(component)), None) => Some(component),
300-
_ => None,
301-
}
302-
}
303-
304-
fn path_contains_symlink(root: &Path, relative: &SafeRelativePath) -> io::Result<bool> {
305-
let mut current = root.to_path_buf();
306-
for component in &relative.components {
307-
let Some(component) = normal_component(component) else {
308-
return Ok(true);
309-
};
310-
current.push(component);
311-
match std::fs::read_link(&current) {
312-
Ok(_) => return Ok(true),
313-
Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(false),
314-
Err(error) if error.kind() == io::ErrorKind::InvalidInput => {}
315-
Err(error) => return Err(error),
316-
}
317-
}
318-
319-
Ok(false)
320-
}
321-
322290
fn configured_web_path_contains_symlink(path: &Path) -> io::Result<bool> {
323-
let mut current = PathBuf::new();
324291
for component in path.components() {
325292
match component {
326-
std::path::Component::Prefix(_) | std::path::Component::RootDir => {
327-
current.push(component);
328-
}
329-
std::path::Component::Normal(component) => {
330-
let Some(component) = normal_component(component) else {
331-
return Ok(true);
332-
};
333-
current.push(component);
334-
}
293+
std::path::Component::Prefix(_)
294+
| std::path::Component::RootDir
295+
| std::path::Component::Normal(_) => {}
335296
std::path::Component::CurDir | std::path::Component::ParentDir => return Ok(true),
336297
}
337-
match std::fs::read_link(&current) {
338-
Ok(_) => return Ok(true),
339-
Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(false),
340-
Err(error) if error.kind() == io::ErrorKind::InvalidInput => {}
341-
Err(error) => return Err(error),
342-
}
343298
}
344299

345-
Ok(false)
300+
let expected = if path.is_absolute() {
301+
path.to_path_buf()
302+
} else {
303+
std::env::current_dir()?.join(path)
304+
};
305+
306+
match path.canonicalize() {
307+
Ok(canonical) => Ok(canonical != expected),
308+
Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(false),
309+
Err(error) => Err(error),
310+
}
346311
}
347312

348313
fn directory_listing_path(relative: &Path) -> String {
@@ -880,7 +845,7 @@ fn open_static_body_file(file: &StaticFile) -> io::Result<std::fs::File> {
880845
"static body path escaped web root",
881846
)
882847
})?;
883-
if path_contains_symlink(&file.root, &relative)? {
848+
if file.path != file.root.join(relative.as_path()) {
884849
return Err(io::Error::new(
885850
io::ErrorKind::InvalidInput,
886851
"static body path contains a symlink",

0 commit comments

Comments
 (0)