]>
Commit | Line | Data |
---|---|---|
6cd4f635 WB |
1 | #![allow(dead_code)] |
2 | ||
3 | use std::future::Future; | |
4 | use std::io; | |
5 | use std::pin::Pin; | |
6 | use std::task::{Context, Poll}; | |
7 | ||
8 | // from /usr/include/linux/magic.h | |
9 | // and from casync util.h | |
10 | #[rustfmt::skip] | |
11 | #[allow(clippy::unreadable_literal)] | |
12 | mod consts { | |
13 | pub const BINFMTFS_MAGIC : i64 = 0x42494e4d; | |
14 | pub const CGROUP2_SUPER_MAGIC : i64 = 0x63677270; | |
15 | pub const CGROUP_SUPER_MAGIC : i64 = 0x0027e0eb; | |
16 | pub const CONFIGFS_MAGIC : i64 = 0x62656570; | |
17 | pub const DEBUGFS_MAGIC : i64 = 0x64626720; | |
18 | pub const DEVPTS_SUPER_MAGIC : i64 = 0x00001cd1; | |
19 | pub const EFIVARFS_MAGIC : i64 = 0xde5e81e4; | |
20 | pub const FUSE_CTL_SUPER_MAGIC: i64 = 0x65735543; | |
21 | pub const HUGETLBFS_MAGIC : i64 = 0x958458f6; | |
22 | pub const MQUEUE_MAGIC : i64 = 0x19800202; | |
23 | pub const NFSD_MAGIC : i64 = 0x6e667364; | |
24 | pub const PROC_SUPER_MAGIC : i64 = 0x00009fa0; | |
25 | pub const PSTOREFS_MAGIC : i64 = 0x6165676C; | |
26 | pub const RPCAUTH_GSSMAGIC : i64 = 0x67596969; | |
27 | pub const SECURITYFS_MAGIC : i64 = 0x73636673; | |
28 | pub const SELINUX_MAGIC : i64 = 0xf97cff8c; | |
29 | pub const SMACK_MAGIC : i64 = 0x43415d53; | |
30 | pub const RAMFS_MAGIC : i64 = 0x858458f6; | |
31 | pub const TMPFS_MAGIC : i64 = 0x01021994; | |
32 | pub const SYSFS_MAGIC : i64 = 0x62656572; | |
33 | pub const MSDOS_SUPER_MAGIC : i64 = 0x00004d44; | |
34 | pub const BTRFS_SUPER_MAGIC : i64 = 0x9123683E; | |
35 | pub const FUSE_SUPER_MAGIC : i64 = 0x65735546; | |
36 | pub const EXT4_SUPER_MAGIC : i64 = 0x0000EF53; | |
37 | pub const XFS_SUPER_MAGIC : i64 = 0x58465342; | |
38 | pub const ZFS_SUPER_MAGIC : i64 = 0x2FC12FC1; | |
39 | } | |
40 | ||
41 | pub fn is_virtual_file_system(magic: i64) -> bool { | |
42 | match magic { | |
43 | consts::BINFMTFS_MAGIC | |
44 | | consts::CGROUP2_SUPER_MAGIC | |
45 | | consts::CGROUP_SUPER_MAGIC | |
46 | | consts::CONFIGFS_MAGIC | |
47 | | consts::DEBUGFS_MAGIC | |
48 | | consts::DEVPTS_SUPER_MAGIC | |
49 | | consts::EFIVARFS_MAGIC | |
50 | | consts::FUSE_CTL_SUPER_MAGIC | |
51 | | consts::HUGETLBFS_MAGIC | |
52 | | consts::MQUEUE_MAGIC | |
53 | | consts::NFSD_MAGIC | |
54 | | consts::PROC_SUPER_MAGIC | |
55 | | consts::PSTOREFS_MAGIC | |
56 | | consts::RPCAUTH_GSSMAGIC | |
57 | | consts::SECURITYFS_MAGIC | |
58 | | consts::SELINUX_MAGIC | |
59 | | consts::SMACK_MAGIC | |
60 | | consts::SYSFS_MAGIC => true, | |
61 | _ => false, | |
62 | } | |
63 | } | |
64 | ||
65 | /// Helper function to extract file names from binary archive. | |
66 | pub fn read_os_string(buffer: &[u8]) -> std::ffi::OsString { | |
67 | use std::os::unix::ffi::OsStrExt; | |
68 | std::ffi::OsStr::from_bytes(if buffer.ends_with(&[0]) { | |
69 | &buffer[..(buffer.len() - 1)] | |
70 | } else { | |
71 | buffer | |
72 | }) | |
73 | .into() | |
74 | } | |
75 | ||
76 | #[inline] | |
77 | pub fn vec_new(size: usize) -> Vec<u8> { | |
78 | let mut data = Vec::with_capacity(size); | |
79 | unsafe { | |
80 | data.set_len(size); | |
81 | } | |
82 | data | |
83 | } | |
84 | ||
85 | pub fn io_err_other<E: std::fmt::Display>(err: E) -> io::Error { | |
86 | io::Error::new(io::ErrorKind::Other, err.to_string()) | |
87 | } | |
88 | ||
89 | pub fn poll_result_once<T, R>(mut fut: T) -> io::Result<R> | |
90 | where | |
91 | T: Future<Output = io::Result<R>>, | |
92 | { | |
93 | let waker = std::task::RawWaker::new(std::ptr::null(), &WAKER_VTABLE); | |
94 | let waker = unsafe { std::task::Waker::from_raw(waker) }; | |
95 | let mut cx = Context::from_waker(&waker); | |
96 | unsafe { | |
97 | match Pin::new_unchecked(&mut fut).poll(&mut cx) { | |
98 | Poll::Pending => Err(io_err_other("got Poll::Pending synchronous context")), | |
99 | Poll::Ready(r) => r, | |
100 | } | |
101 | } | |
102 | } | |
103 | ||
104 | const WAKER_VTABLE: std::task::RawWakerVTable = | |
105 | std::task::RawWakerVTable::new(forbid_clone, forbid_wake, forbid_wake, ignore_drop); | |
106 | ||
107 | unsafe fn forbid_clone(_: *const ()) -> std::task::RawWaker { | |
108 | panic!("tried to clone waker for synchronous task"); | |
109 | } | |
110 | ||
111 | unsafe fn forbid_wake(_: *const ()) { | |
112 | panic!("tried to wake synchronous task"); | |
113 | } | |
114 | ||
115 | unsafe fn ignore_drop(_: *const ()) {} | |
f3ac1c51 | 116 | |
ec0761f9 FG |
117 | pub const MAX_PATH_LEN:u64 = 4 * 1024; |
118 | // let's play it safe | |
119 | pub const MAX_FILENAME_LEN:u64 = MAX_PATH_LEN; | |
120 | // name + attr | |
121 | pub const MAX_XATTR_LEN:u64 = 255 + 64*1024; | |
122 | ||
f3ac1c51 WB |
123 | pub fn validate_filename(name: &[u8]) -> io::Result<()> { |
124 | if name.is_empty() { | |
125 | io_bail!("illegal path found (empty)"); | |
126 | } | |
127 | ||
128 | if name.contains(&b'/') { | |
129 | io_bail!("illegal path found (contains slashes, this is a security concern)"); | |
130 | } | |
131 | ||
132 | if name == b"." { | |
133 | io_bail!("illegal path found: '.'"); | |
134 | } | |
135 | ||
136 | if name == b".." { | |
137 | io_bail!("illegal path found: '..'"); | |
138 | } | |
139 | ||
ec0761f9 FG |
140 | if (name.len() as u64) > MAX_FILENAME_LEN { |
141 | io_bail!("filename too long (> {})", MAX_FILENAME_LEN); | |
142 | } | |
143 | ||
f3ac1c51 WB |
144 | Ok(()) |
145 | } |