(subdir: &str)
| 1247 | } |
| 1248 | |
| 1249 | fn secure_socket_base(subdir: &str) -> Result<PathBuf, String> { |
| 1250 | let base = std::env::var_os("XDG_RUNTIME_DIR").map_or_else( |
| 1251 | || { |
| 1252 | let fallback = PathBuf::from("/tmp"); |
| 1253 | if fallback.is_dir() { |
| 1254 | fallback |
| 1255 | } else { |
| 1256 | std::env::temp_dir() |
| 1257 | } |
| 1258 | }, |
| 1259 | PathBuf::from, |
| 1260 | ); |
| 1261 | let dir = base.join(subdir); |
| 1262 | |
| 1263 | if dir.exists() { |
| 1264 | let meta = dir |
| 1265 | .symlink_metadata() |
| 1266 | .map_err(|e| format!("lstat {}: {e}", dir.display()))?; |
| 1267 | if meta.file_type().is_symlink() { |
| 1268 | return Err(format!( |
| 1269 | "socket directory {} is a symlink; refusing to use it", |
| 1270 | dir.display() |
| 1271 | )); |
| 1272 | } |
| 1273 | #[cfg(unix)] |
| 1274 | { |
| 1275 | use std::os::unix::fs::MetadataExt as _; |
| 1276 | let uid = unsafe { libc::getuid() }; |
| 1277 | if meta.uid() != uid { |
| 1278 | return Err(format!( |
| 1279 | "socket directory {} is owned by uid {} but we are uid {}", |
| 1280 | dir.display(), |
| 1281 | meta.uid(), |
| 1282 | uid |
| 1283 | )); |
| 1284 | } |
| 1285 | } |
| 1286 | } else { |
| 1287 | std::fs::create_dir_all(&dir) |
| 1288 | .map_err(|e| format!("create socket dir {}: {e}", dir.display()))?; |
| 1289 | #[cfg(unix)] |
| 1290 | { |
| 1291 | use std::os::unix::fs::PermissionsExt as _; |
| 1292 | let _ = std::fs::set_permissions(&dir, std::fs::Permissions::from_mode(0o700)); |
| 1293 | } |
| 1294 | } |
| 1295 | |
| 1296 | Ok(dir) |
| 1297 | } |
| 1298 | |
| 1299 | fn gvproxy_socket_base(overlay_disk: &Path) -> Result<PathBuf, String> { |
| 1300 | Ok(secure_socket_base("osd-gv")?.join(hash_path_id(overlay_disk))) |
no test coverage detected