Skip to content

Commit 92a0553

Browse files
authored
Add safe getpwuid (#267)
1 parent 73dcbd7 commit 92a0553

5 files changed

Lines changed: 424 additions & 0 deletions

File tree

‎libcc2rs/src/libc_shims/pwd.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ impl Passwd {
3333
pw_shell: mk(u.shell.as_os_str().as_encoded_bytes()),
3434
}
3535
}
36+
37+
pub fn from_user_in(u: &nix::unistd::User, strings: &[Ptr<u8>]) -> Self {
38+
Self {
39+
pw_name: Rc::new(RefCell::new(strings[0].clone())),
40+
pw_passwd: Rc::new(RefCell::new(strings[1].clone())),
41+
pw_uid: Rc::new(RefCell::new(u.uid.as_raw())),
42+
pw_gid: Rc::new(RefCell::new(u.gid.as_raw())),
43+
pw_gecos: Rc::new(RefCell::new(strings[2].clone())),
44+
pw_dir: Rc::new(RefCell::new(strings[3].clone())),
45+
pw_shell: Rc::new(RefCell::new(strings[4].clone())),
46+
}
47+
}
3648
}
3749

3850
impl Clone for Passwd {

‎rules/pwd/tgt_refcount.rs‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,52 @@ fn t1() -> libcc2rs::Passwd {
77
Default::default()
88
}
99

10+
fn f2(a0: u32, a1: Ptr<Passwd>, a2: Ptr<u8>, a3: usize, a4: Ptr<Ptr<Passwd>>) -> i32 {
11+
let __pwbuf = a1.clone();
12+
let __buf = a2.clone();
13+
let __buflen = a3;
14+
let __out = a4.clone();
15+
match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(a0)) {
16+
Ok(Some(__u)) => {
17+
let __strs: [Vec<u8>; 5] = [
18+
__u.name.as_bytes().to_vec(),
19+
__u.passwd.as_bytes().to_vec(),
20+
__u.gecos.as_bytes().to_vec(),
21+
__u.dir.as_os_str().as_encoded_bytes().to_vec(),
22+
__u.shell.as_os_str().as_encoded_bytes().to_vec(),
23+
];
24+
let __needed: usize = __strs.iter().map(|__s| __s.len() + 1).sum();
25+
if __needed > __buflen {
26+
__out.write(Ptr::null());
27+
::libc::ERANGE
28+
} else {
29+
let mut __ptrs: Vec<Ptr<u8>> = Vec::new();
30+
let mut __off: usize = 0;
31+
for __s in &__strs {
32+
__ptrs.push(__buf.offset(__off));
33+
let __end = __s.len();
34+
__buf.offset(__off).with_slice_mut(__end + 1, |__sl| {
35+
__sl[..__end].copy_from_slice(__s);
36+
__sl[__end] = 0;
37+
});
38+
__off += __end + 1;
39+
}
40+
__pwbuf.with_mut(|__pw| *__pw = Passwd::from_user_in(&__u, &__ptrs));
41+
__out.write(__pwbuf.clone());
42+
0
43+
}
44+
}
45+
Ok(None) => {
46+
__out.write(Ptr::null());
47+
0
48+
}
49+
Err(__e) => {
50+
__out.write(Ptr::null());
51+
__e as i32
52+
}
53+
}
54+
}
55+
1056
fn f1(a0: u32) -> Ptr<Passwd> {
1157
match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(a0)) {
1258
Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)),

‎tests/unit/out/refcount/pwd.rs‎

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub fn test_getpwuid_0() {
10+
let pw: Value<Ptr<libcc2rs::Passwd>> = Rc::new(RefCell::new(
11+
match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(
12+
nix::unistd::geteuid().as_raw(),
13+
)) {
14+
Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)),
15+
Ok(None) => Ptr::null(),
16+
Err(__e) => {
17+
libcc2rs::cpp2rust_errno().write(__e as i32);
18+
Ptr::null()
19+
}
20+
},
21+
));
22+
assert!((((!((*pw.borrow()).is_null())) as i32) != 0));
23+
assert!(
24+
((({
25+
let _lhs = (*(*(*pw.borrow()).upgrade().deref()).pw_uid.borrow());
26+
_lhs == nix::unistd::geteuid().as_raw()
27+
}) as i32)
28+
!= 0)
29+
);
30+
assert!(
31+
((((*(*(*pw.borrow()).upgrade().deref()).pw_name.borrow())
32+
.to_c_string_iterator()
33+
.count()
34+
> 0_usize) as i32)
35+
!= 0)
36+
);
37+
assert!((((!((*(*(*pw.borrow()).upgrade().deref()).pw_dir.borrow()).is_null())) as i32) != 0));
38+
println!(
39+
"{}",
40+
(*(*(*pw.borrow()).upgrade().deref()).pw_name.borrow())
41+
);
42+
}
43+
pub fn test_getpwuid_missing_1() {
44+
libcc2rs::cpp2rust_errno().write(0);
45+
let pw: Value<Ptr<libcc2rs::Passwd>> = Rc::new(RefCell::new(
46+
match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(2147483646_u32)) {
47+
Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)),
48+
Ok(None) => Ptr::null(),
49+
Err(__e) => {
50+
libcc2rs::cpp2rust_errno().write(__e as i32);
51+
Ptr::null()
52+
}
53+
},
54+
));
55+
assert!(((((*pw.borrow()).is_null()) as i32) != 0));
56+
assert!(((((libcc2rs::cpp2rust_errno().read()) == 0) as i32) != 0));
57+
}
58+
pub fn test_getpwuid_r_2() {
59+
let pw: Value<libcc2rs::Passwd> = Rc::new(RefCell::new(Default::default()));
60+
let buf: Value<Box<[u8]>> = Rc::new(RefCell::new(
61+
(0..4096).map(|_| <u8>::default()).collect::<Box<[u8]>>(),
62+
));
63+
let result: Value<Ptr<libcc2rs::Passwd>> =
64+
Rc::new(RefCell::new(Ptr::<libcc2rs::Passwd>::null()));
65+
assert!(
66+
((({
67+
let __pwbuf = (pw.as_pointer()).clone();
68+
let __buf = (buf.as_pointer() as Ptr<u8>).clone();
69+
let __buflen = ::std::mem::size_of::<[u8; 4096]>();
70+
let __out = (result.as_pointer()).clone();
71+
match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(
72+
nix::unistd::geteuid().as_raw(),
73+
)) {
74+
Ok(Some(__u)) => {
75+
let __strs: [Vec<u8>; 5] = [
76+
__u.name.as_bytes().to_vec(),
77+
__u.passwd.as_bytes().to_vec(),
78+
__u.gecos.as_bytes().to_vec(),
79+
__u.dir.as_os_str().as_encoded_bytes().to_vec(),
80+
__u.shell.as_os_str().as_encoded_bytes().to_vec(),
81+
];
82+
let __needed: usize = __strs.iter().map(|__s| __s.len() + 1).sum();
83+
if __needed > __buflen {
84+
__out.write(Ptr::null());
85+
::libc::ERANGE
86+
} else {
87+
let mut __ptrs: Vec<Ptr<u8>> = Vec::new();
88+
let mut __off: usize = 0;
89+
for __s in &__strs {
90+
__ptrs.push(__buf.offset(__off));
91+
let __end = __s.len();
92+
__buf.offset(__off).with_slice_mut(__end + 1, |__sl| {
93+
__sl[..__end].copy_from_slice(__s);
94+
__sl[__end] = 0;
95+
});
96+
__off += __end + 1;
97+
}
98+
__pwbuf.with_mut(|__pw| *__pw = Passwd::from_user_in(&__u, &__ptrs));
99+
__out.write(__pwbuf.clone());
100+
0
101+
}
102+
}
103+
Ok(None) => {
104+
__out.write(Ptr::null());
105+
0
106+
}
107+
Err(__e) => {
108+
__out.write(Ptr::null());
109+
__e as i32
110+
}
111+
}
112+
} == 0) as i32)
113+
!= 0)
114+
);
115+
assert!(
116+
((({
117+
let _lhs = (*result.borrow()).clone();
118+
_lhs == (pw.as_pointer())
119+
}) as i32)
120+
!= 0)
121+
);
122+
assert!(((((*(*pw.borrow()).pw_uid.borrow()) == nix::unistd::geteuid().as_raw()) as i32) != 0));
123+
assert!(
124+
((((*(*pw.borrow()).pw_name.borrow())
125+
.to_c_string_iterator()
126+
.count()
127+
> 0_usize) as i32)
128+
!= 0)
129+
);
130+
let pw2: Value<Ptr<libcc2rs::Passwd>> = Rc::new(RefCell::new(
131+
match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(
132+
nix::unistd::geteuid().as_raw(),
133+
)) {
134+
Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)),
135+
Ok(None) => Ptr::null(),
136+
Err(__e) => {
137+
libcc2rs::cpp2rust_errno().write(__e as i32);
138+
Ptr::null()
139+
}
140+
},
141+
));
142+
assert!((((!((*pw2.borrow()).is_null())) as i32) != 0));
143+
assert!(
144+
((({
145+
let mut __it1 = (*(*pw.borrow()).pw_name.borrow()).to_c_string_iterator();
146+
let mut __it2 =
147+
(*(*(*pw2.borrow()).upgrade().deref()).pw_name.borrow()).to_c_string_iterator();
148+
loop {
149+
let __c1 = __it1.next();
150+
let __c2 = __it2.next();
151+
if __c1 != __c2 {
152+
break (__c1.unwrap_or(0) as i32) - (__c2.unwrap_or(0) as i32);
153+
}
154+
if __c1.is_none() {
155+
break 0;
156+
}
157+
}
158+
} == 0) as i32)
159+
!= 0)
160+
);
161+
println!("{}", (*(*pw.borrow()).pw_name.borrow()));
162+
}
163+
pub fn test_getpwuid_r_erange_3() {
164+
let pw: Value<libcc2rs::Passwd> = Rc::new(RefCell::new(Default::default()));
165+
let tiny: Value<Box<[u8]>> = Rc::new(RefCell::new(
166+
(0..1).map(|_| <u8>::default()).collect::<Box<[u8]>>(),
167+
));
168+
let result: Value<Ptr<libcc2rs::Passwd>> =
169+
Rc::new(RefCell::new(Ptr::<libcc2rs::Passwd>::null()));
170+
assert!(
171+
((({
172+
let __pwbuf = (pw.as_pointer()).clone();
173+
let __buf = (tiny.as_pointer() as Ptr<u8>).clone();
174+
let __buflen = ::std::mem::size_of::<[u8; 1]>();
175+
let __out = (result.as_pointer()).clone();
176+
match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(
177+
nix::unistd::geteuid().as_raw(),
178+
)) {
179+
Ok(Some(__u)) => {
180+
let __strs: [Vec<u8>; 5] = [
181+
__u.name.as_bytes().to_vec(),
182+
__u.passwd.as_bytes().to_vec(),
183+
__u.gecos.as_bytes().to_vec(),
184+
__u.dir.as_os_str().as_encoded_bytes().to_vec(),
185+
__u.shell.as_os_str().as_encoded_bytes().to_vec(),
186+
];
187+
let __needed: usize = __strs.iter().map(|__s| __s.len() + 1).sum();
188+
if __needed > __buflen {
189+
__out.write(Ptr::null());
190+
::libc::ERANGE
191+
} else {
192+
let mut __ptrs: Vec<Ptr<u8>> = Vec::new();
193+
let mut __off: usize = 0;
194+
for __s in &__strs {
195+
__ptrs.push(__buf.offset(__off));
196+
let __end = __s.len();
197+
__buf.offset(__off).with_slice_mut(__end + 1, |__sl| {
198+
__sl[..__end].copy_from_slice(__s);
199+
__sl[__end] = 0;
200+
});
201+
__off += __end + 1;
202+
}
203+
__pwbuf.with_mut(|__pw| *__pw = Passwd::from_user_in(&__u, &__ptrs));
204+
__out.write(__pwbuf.clone());
205+
0
206+
}
207+
}
208+
Ok(None) => {
209+
__out.write(Ptr::null());
210+
0
211+
}
212+
Err(__e) => {
213+
__out.write(Ptr::null());
214+
__e as i32
215+
}
216+
}
217+
} == 34) as i32)
218+
!= 0)
219+
);
220+
assert!(((((*result.borrow()).is_null()) as i32) != 0));
221+
}
222+
pub fn main() {
223+
std::process::exit(main_0());
224+
}
225+
fn main_0() -> i32 {
226+
({ test_getpwuid_0() });
227+
({ test_getpwuid_missing_1() });
228+
({ test_getpwuid_r_2() });
229+
({ test_getpwuid_r_erange_3() });
230+
return 0;
231+
}

‎tests/unit/out/unsafe/pwd.rs‎

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub unsafe fn test_getpwuid_0() {
10+
let mut pw: *mut ::libc::passwd = libc::getpwuid(libc::geteuid());
11+
assert!((((!((pw).is_null())) as i32) != 0));
12+
assert!((((((*pw).pw_uid) == (libc::geteuid())) as i32) != 0));
13+
assert!(((((libc::strlen(((*pw).pw_name).cast_const())) > (0_usize)) as i32) != 0));
14+
assert!((((!(((*pw).pw_dir).is_null())) as i32) != 0));
15+
printf(
16+
(c"%s\n".as_ptr().cast_mut()).cast_const() as *const i8,
17+
(*pw).pw_name,
18+
);
19+
}
20+
pub unsafe fn test_getpwuid_missing_1() {
21+
(*libcc2rs::cpp2rust_errno_unsafe()) = 0;
22+
let mut pw: *mut ::libc::passwd = libc::getpwuid(2147483646_u32);
23+
assert!(((((pw).is_null()) as i32) != 0));
24+
assert!(((((*libcc2rs::cpp2rust_errno_unsafe()) == (0)) as i32) != 0));
25+
}
26+
pub unsafe fn test_getpwuid_r_2() {
27+
let mut pw: ::libc::passwd = unsafe { std::mem::zeroed() };
28+
let mut buf: [libc::c_char; 4096] = [(0 as libc::c_char); 4096];
29+
let mut result: *mut ::libc::passwd = std::ptr::null_mut();
30+
assert!(
31+
((((libc::getpwuid_r(
32+
libc::geteuid(),
33+
(&mut pw as *mut ::libc::passwd),
34+
buf.as_mut_ptr(),
35+
::std::mem::size_of::<[libc::c_char; 4096]>(),
36+
(&mut result as *mut *mut ::libc::passwd)
37+
)) == (0)) as i32)
38+
!= 0)
39+
);
40+
assert!(((((result) == (&mut pw as *mut ::libc::passwd)) as i32) != 0));
41+
assert!(((((pw.pw_uid) == (libc::geteuid())) as i32) != 0));
42+
assert!(((((libc::strlen((pw.pw_name).cast_const())) > (0_usize)) as i32) != 0));
43+
let mut pw2: *mut ::libc::passwd = libc::getpwuid(libc::geteuid());
44+
assert!((((!((pw2).is_null())) as i32) != 0));
45+
assert!(
46+
((((libc::strcmp((pw.pw_name).cast_const(), ((*pw2).pw_name).cast_const())) == (0))
47+
as i32)
48+
!= 0)
49+
);
50+
printf(
51+
(c"%s\n".as_ptr().cast_mut()).cast_const() as *const i8,
52+
pw.pw_name,
53+
);
54+
}
55+
pub unsafe fn test_getpwuid_r_erange_3() {
56+
let mut pw: ::libc::passwd = unsafe { std::mem::zeroed() };
57+
let mut tiny: [libc::c_char; 1] = [(0 as libc::c_char); 1];
58+
let mut result: *mut ::libc::passwd = std::ptr::null_mut();
59+
assert!(
60+
((((libc::getpwuid_r(
61+
libc::geteuid(),
62+
(&mut pw as *mut ::libc::passwd),
63+
tiny.as_mut_ptr(),
64+
::std::mem::size_of::<[libc::c_char; 1]>(),
65+
(&mut result as *mut *mut ::libc::passwd)
66+
)) == (34)) as i32)
67+
!= 0)
68+
);
69+
assert!(((((result).is_null()) as i32) != 0));
70+
}
71+
pub fn main() {
72+
unsafe {
73+
std::process::exit(main_0() as i32);
74+
}
75+
}
76+
unsafe fn main_0() -> i32 {
77+
(unsafe { test_getpwuid_0() });
78+
(unsafe { test_getpwuid_missing_1() });
79+
(unsafe { test_getpwuid_r_2() });
80+
(unsafe { test_getpwuid_r_erange_3() });
81+
return 0;
82+
}

0 commit comments

Comments
 (0)