1 // Copyright (c) 2024 Huawei Technologies Co.,Ltd. All rights reserved.
2 //
3 // StratoVirt is licensed under Mulan PSL v2.
4 // You can use this software according to the terms and conditions of the Mulan
5 // PSL v2.
6 // You may obtain a copy of Mulan PSL v2 at:
7 //         http://license.coscl.org.cn/MulanPSL2
8 // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
9 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
10 // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 // See the Mulan PSL v2 for more details.
12 
13 use std::ffi::CString;
14 
15 use anyhow::{bail, Result};
16 use libc::{c_int, c_ulong, prctl};
17 use nix::errno::errno;
18 
19 #[allow(non_camel_case_types)]
20 enum PrctlOption {
21     PR_SET_DUMPABLE = 4,
22     PR_SET_KEEPCAPS = 8,
23     PR_SET_NAME = 15,
24     PR_SET_NO_NEW_PRIVS = 38,
25 }
26 
set_dumpable(dumpable: bool) -> Result<()>27 pub fn set_dumpable(dumpable: bool) -> Result<()> {
28     // SAFETY: FFI call with valid arguments.
29     let ret = unsafe {
30         prctl(
31             PrctlOption::PR_SET_DUMPABLE as c_int,
32             dumpable as c_ulong,
33             0,
34             0,
35             0,
36         )
37     };
38     if ret != 0 {
39         bail!("errno {}", errno());
40     }
41     Ok(())
42 }
43 
set_keep_capabilities(keep_capabilities: bool) -> Result<()>44 pub fn set_keep_capabilities(keep_capabilities: bool) -> Result<()> {
45     // SAFETY: FFI call with valid arguments.
46     let ret = unsafe {
47         prctl(
48             PrctlOption::PR_SET_KEEPCAPS as c_int,
49             keep_capabilities as c_ulong,
50             0,
51             0,
52             0,
53         )
54     };
55     if ret != 0 {
56         bail!("errno {}", errno());
57     }
58     Ok(())
59 }
60 
set_no_new_privileges(new_privileges: bool) -> Result<()>61 pub fn set_no_new_privileges(new_privileges: bool) -> Result<()> {
62     // SAFETY: FFI call with valid arguments.
63     let ret = unsafe {
64         prctl(
65             PrctlOption::PR_SET_NO_NEW_PRIVS as c_int,
66             new_privileges as c_ulong,
67             0,
68             0,
69             0,
70         )
71     };
72     if ret != 0 {
73         bail!("errno {}", errno());
74     }
75     Ok(())
76 }
77 
set_name(name: &str) -> Result<()>78 pub fn set_name(name: &str) -> Result<()> {
79     let binding = CString::new(name).unwrap();
80     // SAFETY: FFI call with valid arguments.
81     let ret = unsafe {
82         prctl(
83             PrctlOption::PR_SET_NAME as c_int,
84             binding.as_ptr() as c_ulong,
85             0,
86             0,
87             0,
88         )
89     };
90     if ret != 0 {
91         bail!("errno {}", errno());
92     }
93     Ok(())
94 }
95