1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
//! This library provides a simple, architecture independent way to detect the current privilege level (CPL).
//!
//! # Example
//!
//! ```rust
//! use privilege_level::{privilege_level, PrivilegeLevel};
//!
//! # fn main() {
//! match privilege_level() {
//! PrivilegeLevel::Hypervisor => println!("Currently a hypervisor"),
//! PrivilegeLevel::Kernel => println!("Currently in kernel space"),
//! PrivilegeLevel::Driver => println!("Currently in a driver"),
//! PrivilegeLevel::User => println!("Currently in user space"),
//! }
//! # }
//! ```
//!
//! # Details
//!
//! The main entrypoint into this crate is through the [`privilege_level`] function.
//! That will use the architecture dependent code necessary to determine the current privilege level then converts it into the common API.
//!
//! The common API ([`PrivilegeLevel`]) is meant to be usable on any platform.
//! It contains generic privilege levels that are common on most architectures.
//! However, it's not always possible to include support for _every_ architecture.
//! As a compromise, depending on the target architecture, certain functions will be made available that return architecture-specific structures.
//!
//! If you only want the raw privilege level number rather than a symbolic structure, you can also use the [`raw_privilege_level`] function.
//! It uses architecture specific code to read the privilege level, converts it into a u16, then returns it.
//! It's important to note that it doesn't do anything to make the output common in any way!
/// Represents a generic CPU privilege level.
///
/// This creates a common interface for privilege levels.
/// It abstracts away architecture independent structure and allows you to test if you're in specific contexts.
///
/// Hopefully this enum can provide you with everything you need from privilege levels, however it is very possible that it might not.
/// In that case, architecture specific functions are provided to let you get the architecture specific privilege level information.
///
/// # Example
///
/// ```rust
/// # use privilege_level::{privilege_level, PrivilegeLevel};
/// # fn main() {
/// match privilege_level() {
/// PrivilegeLevel::Hypervisor => println!("Hypervisor specific"),
/// PrivilegeLevel::Kernel => println!("Kernel specific"),
/// PrivilegeLevel::Driver => println!("Driver specific"),
/// PrivilegeLevel::User => println!("User specific"),
/// }
/// # }
/// ```
/// This is a test
///
/// # Example
///
/// ```rust
/// fn main() {
/// println!("here");
/// }
/// ```
/// Gets the current privilege level.
///
/// This will check the target architecture and call the correct architecture-specific function to get its corresponding privilege level.
/// After that, it simply wraps it in the [`PrivilegeLevel`] enum for convenience.
/// For more information about architecture-specific functions, take a look at the root module for architecture-specific functions.
///
/// # Example
///
/// ```rust
/// # use privilege_level::privilege_level;
/// # fn main() {
/// println!("Currently running at privilege level: {:?}", privilege_level());
/// # }
/// ```
// TODO: potentially move these sorts of functions to a separate module and just export them?
pub use PrivilegeLevel as x86_64PrivilegeLevel;
// TODO: potentially move these sorts of functions to a separate module and just export them?
// TODO: potentially move these sorts of functions to a separate module and just export them?
/// Gets the current privilege level for `x86_64` systems.
///
/// This will get the raw privilege level from [`raw_privilege_level`] then convert it into the x86_64 privilege level enum.
/// The [`x86_64PrivilegeLevel`] enum is actually a reexport of the privilege level enum from the [`x86_64`] crate.
/// It is added for convenience so that you don't have to worry about including that crate in your project.
///
/// # Example
///
/// ```rust
/// # use privilege_level::{x86_64_privilege_level, x86_64PrivilegeLevel};
/// # fn main() {
/// assert_eq!(x86_64_privilege_level(), x86_64PrivilegeLevel::Ring0, "This must be running in ring 0!");
/// # }
/// ```
/// Gets the current privilege level as a raw number.
///
/// This will detect the target architecture then use architecture-specific code to read the current privilege level and return it.
/// No effort is made to convert the resulting number into anything common or architecture independent.
/// If you want that functionality, use [`privilege_level`] instead.
///
/// **Note:** since this function does no conversion into a common format, things can break on different architectures.
/// Please take that into consideration when using this function!
/// If you need to represent a privilege level as a number, [`PrivilegeLevel`] can be converted into a `usize`.
///
/// # Example
///
/// ```rust
/// # use privilege_level::raw_privilege_level;
/// # fn main() {
/// println!("Raw privilege level is {}", raw_privilege_level());
/// # }
/// ```