diff --git a/libcc2rs/src/libc_shims/pwd.rs b/libcc2rs/src/libc_shims/pwd.rs index a18be065..9798c022 100644 --- a/libcc2rs/src/libc_shims/pwd.rs +++ b/libcc2rs/src/libc_shims/pwd.rs @@ -33,6 +33,18 @@ impl Passwd { pw_shell: mk(u.shell.as_os_str().as_encoded_bytes()), } } + + pub fn from_user_in(u: &nix::unistd::User, strings: &[Ptr]) -> Self { + Self { + pw_name: Rc::new(RefCell::new(strings[0].clone())), + pw_passwd: Rc::new(RefCell::new(strings[1].clone())), + pw_uid: Rc::new(RefCell::new(u.uid.as_raw())), + pw_gid: Rc::new(RefCell::new(u.gid.as_raw())), + pw_gecos: Rc::new(RefCell::new(strings[2].clone())), + pw_dir: Rc::new(RefCell::new(strings[3].clone())), + pw_shell: Rc::new(RefCell::new(strings[4].clone())), + } + } } impl Clone for Passwd { diff --git a/rules/pwd/tgt_refcount.rs b/rules/pwd/tgt_refcount.rs index 8257ef1b..6f7dde52 100644 --- a/rules/pwd/tgt_refcount.rs +++ b/rules/pwd/tgt_refcount.rs @@ -7,6 +7,52 @@ fn t1() -> libcc2rs::Passwd { Default::default() } +fn f2(a0: u32, a1: Ptr, a2: Ptr, a3: usize, a4: Ptr>) -> i32 { + let __pwbuf = a1.clone(); + let __buf = a2.clone(); + let __buflen = a3; + let __out = a4.clone(); + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(a0)) { + Ok(Some(__u)) => { + let __strs: [Vec; 5] = [ + __u.name.as_bytes().to_vec(), + __u.passwd.as_bytes().to_vec(), + __u.gecos.as_bytes().to_vec(), + __u.dir.as_os_str().as_encoded_bytes().to_vec(), + __u.shell.as_os_str().as_encoded_bytes().to_vec(), + ]; + let __needed: usize = __strs.iter().map(|__s| __s.len() + 1).sum(); + if __needed > __buflen { + __out.write(Ptr::null()); + ::libc::ERANGE + } else { + let mut __ptrs: Vec> = Vec::new(); + let mut __off: usize = 0; + for __s in &__strs { + __ptrs.push(__buf.offset(__off)); + let __end = __s.len(); + __buf.offset(__off).with_slice_mut(__end + 1, |__sl| { + __sl[..__end].copy_from_slice(__s); + __sl[__end] = 0; + }); + __off += __end + 1; + } + __pwbuf.with_mut(|__pw| *__pw = Passwd::from_user_in(&__u, &__ptrs)); + __out.write(__pwbuf.clone()); + 0 + } + } + Ok(None) => { + __out.write(Ptr::null()); + 0 + } + Err(__e) => { + __out.write(Ptr::null()); + __e as i32 + } + } +} + fn f1(a0: u32) -> Ptr { match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(a0)) { Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), diff --git a/tests/unit/out/refcount/pwd.rs b/tests/unit/out/refcount/pwd.rs new file mode 100644 index 00000000..f10f3138 --- /dev/null +++ b/tests/unit/out/refcount/pwd.rs @@ -0,0 +1,231 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn test_getpwuid_0() { + let pw: Value> = Rc::new(RefCell::new( + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw( + nix::unistd::geteuid().as_raw(), + )) { + Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), + Ok(None) => Ptr::null(), + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + Ptr::null() + } + }, + )); + assert!((((!((*pw.borrow()).is_null())) as i32) != 0)); + assert!( + ((({ + let _lhs = (*(*(*pw.borrow()).upgrade().deref()).pw_uid.borrow()); + _lhs == nix::unistd::geteuid().as_raw() + }) as i32) + != 0) + ); + assert!( + ((((*(*(*pw.borrow()).upgrade().deref()).pw_name.borrow()) + .to_c_string_iterator() + .count() + > 0_usize) as i32) + != 0) + ); + assert!((((!((*(*(*pw.borrow()).upgrade().deref()).pw_dir.borrow()).is_null())) as i32) != 0)); + println!( + "{}", + (*(*(*pw.borrow()).upgrade().deref()).pw_name.borrow()) + ); +} +pub fn test_getpwuid_missing_1() { + libcc2rs::cpp2rust_errno().write(0); + let pw: Value> = Rc::new(RefCell::new( + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(2147483646_u32)) { + Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), + Ok(None) => Ptr::null(), + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + Ptr::null() + } + }, + )); + assert!(((((*pw.borrow()).is_null()) as i32) != 0)); + assert!(((((libcc2rs::cpp2rust_errno().read()) == 0) as i32) != 0)); +} +pub fn test_getpwuid_r_2() { + let pw: Value = Rc::new(RefCell::new(Default::default())); + let buf: Value> = Rc::new(RefCell::new( + (0..4096).map(|_| ::default()).collect::>(), + )); + let result: Value> = + Rc::new(RefCell::new(Ptr::::null())); + assert!( + ((({ + let __pwbuf = (pw.as_pointer()).clone(); + let __buf = (buf.as_pointer() as Ptr).clone(); + let __buflen = ::std::mem::size_of::<[u8; 4096]>(); + let __out = (result.as_pointer()).clone(); + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw( + nix::unistd::geteuid().as_raw(), + )) { + Ok(Some(__u)) => { + let __strs: [Vec; 5] = [ + __u.name.as_bytes().to_vec(), + __u.passwd.as_bytes().to_vec(), + __u.gecos.as_bytes().to_vec(), + __u.dir.as_os_str().as_encoded_bytes().to_vec(), + __u.shell.as_os_str().as_encoded_bytes().to_vec(), + ]; + let __needed: usize = __strs.iter().map(|__s| __s.len() + 1).sum(); + if __needed > __buflen { + __out.write(Ptr::null()); + ::libc::ERANGE + } else { + let mut __ptrs: Vec> = Vec::new(); + let mut __off: usize = 0; + for __s in &__strs { + __ptrs.push(__buf.offset(__off)); + let __end = __s.len(); + __buf.offset(__off).with_slice_mut(__end + 1, |__sl| { + __sl[..__end].copy_from_slice(__s); + __sl[__end] = 0; + }); + __off += __end + 1; + } + __pwbuf.with_mut(|__pw| *__pw = Passwd::from_user_in(&__u, &__ptrs)); + __out.write(__pwbuf.clone()); + 0 + } + } + Ok(None) => { + __out.write(Ptr::null()); + 0 + } + Err(__e) => { + __out.write(Ptr::null()); + __e as i32 + } + } + } == 0) as i32) + != 0) + ); + assert!( + ((({ + let _lhs = (*result.borrow()).clone(); + _lhs == (pw.as_pointer()) + }) as i32) + != 0) + ); + assert!(((((*(*pw.borrow()).pw_uid.borrow()) == nix::unistd::geteuid().as_raw()) as i32) != 0)); + assert!( + ((((*(*pw.borrow()).pw_name.borrow()) + .to_c_string_iterator() + .count() + > 0_usize) as i32) + != 0) + ); + let pw2: Value> = Rc::new(RefCell::new( + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw( + nix::unistd::geteuid().as_raw(), + )) { + Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), + Ok(None) => Ptr::null(), + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + Ptr::null() + } + }, + )); + assert!((((!((*pw2.borrow()).is_null())) as i32) != 0)); + assert!( + ((({ + let mut __it1 = (*(*pw.borrow()).pw_name.borrow()).to_c_string_iterator(); + let mut __it2 = + (*(*(*pw2.borrow()).upgrade().deref()).pw_name.borrow()).to_c_string_iterator(); + loop { + let __c1 = __it1.next(); + let __c2 = __it2.next(); + if __c1 != __c2 { + break (__c1.unwrap_or(0) as i32) - (__c2.unwrap_or(0) as i32); + } + if __c1.is_none() { + break 0; + } + } + } == 0) as i32) + != 0) + ); + println!("{}", (*(*pw.borrow()).pw_name.borrow())); +} +pub fn test_getpwuid_r_erange_3() { + let pw: Value = Rc::new(RefCell::new(Default::default())); + let tiny: Value> = Rc::new(RefCell::new( + (0..1).map(|_| ::default()).collect::>(), + )); + let result: Value> = + Rc::new(RefCell::new(Ptr::::null())); + assert!( + ((({ + let __pwbuf = (pw.as_pointer()).clone(); + let __buf = (tiny.as_pointer() as Ptr).clone(); + let __buflen = ::std::mem::size_of::<[u8; 1]>(); + let __out = (result.as_pointer()).clone(); + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw( + nix::unistd::geteuid().as_raw(), + )) { + Ok(Some(__u)) => { + let __strs: [Vec; 5] = [ + __u.name.as_bytes().to_vec(), + __u.passwd.as_bytes().to_vec(), + __u.gecos.as_bytes().to_vec(), + __u.dir.as_os_str().as_encoded_bytes().to_vec(), + __u.shell.as_os_str().as_encoded_bytes().to_vec(), + ]; + let __needed: usize = __strs.iter().map(|__s| __s.len() + 1).sum(); + if __needed > __buflen { + __out.write(Ptr::null()); + ::libc::ERANGE + } else { + let mut __ptrs: Vec> = Vec::new(); + let mut __off: usize = 0; + for __s in &__strs { + __ptrs.push(__buf.offset(__off)); + let __end = __s.len(); + __buf.offset(__off).with_slice_mut(__end + 1, |__sl| { + __sl[..__end].copy_from_slice(__s); + __sl[__end] = 0; + }); + __off += __end + 1; + } + __pwbuf.with_mut(|__pw| *__pw = Passwd::from_user_in(&__u, &__ptrs)); + __out.write(__pwbuf.clone()); + 0 + } + } + Ok(None) => { + __out.write(Ptr::null()); + 0 + } + Err(__e) => { + __out.write(Ptr::null()); + __e as i32 + } + } + } == 34) as i32) + != 0) + ); + assert!(((((*result.borrow()).is_null()) as i32) != 0)); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + ({ test_getpwuid_0() }); + ({ test_getpwuid_missing_1() }); + ({ test_getpwuid_r_2() }); + ({ test_getpwuid_r_erange_3() }); + return 0; +} diff --git a/tests/unit/out/unsafe/pwd.rs b/tests/unit/out/unsafe/pwd.rs new file mode 100644 index 00000000..b7aac3b1 --- /dev/null +++ b/tests/unit/out/unsafe/pwd.rs @@ -0,0 +1,82 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn test_getpwuid_0() { + let mut pw: *mut ::libc::passwd = libc::getpwuid(libc::geteuid()); + assert!((((!((pw).is_null())) as i32) != 0)); + assert!((((((*pw).pw_uid) == (libc::geteuid())) as i32) != 0)); + assert!(((((libc::strlen(((*pw).pw_name).cast_const())) > (0_usize)) as i32) != 0)); + assert!((((!(((*pw).pw_dir).is_null())) as i32) != 0)); + printf( + (c"%s\n".as_ptr().cast_mut()).cast_const() as *const i8, + (*pw).pw_name, + ); +} +pub unsafe fn test_getpwuid_missing_1() { + (*libcc2rs::cpp2rust_errno_unsafe()) = 0; + let mut pw: *mut ::libc::passwd = libc::getpwuid(2147483646_u32); + assert!(((((pw).is_null()) as i32) != 0)); + assert!(((((*libcc2rs::cpp2rust_errno_unsafe()) == (0)) as i32) != 0)); +} +pub unsafe fn test_getpwuid_r_2() { + let mut pw: ::libc::passwd = unsafe { std::mem::zeroed() }; + let mut buf: [libc::c_char; 4096] = [(0 as libc::c_char); 4096]; + let mut result: *mut ::libc::passwd = std::ptr::null_mut(); + assert!( + ((((libc::getpwuid_r( + libc::geteuid(), + (&mut pw as *mut ::libc::passwd), + buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 4096]>(), + (&mut result as *mut *mut ::libc::passwd) + )) == (0)) as i32) + != 0) + ); + assert!(((((result) == (&mut pw as *mut ::libc::passwd)) as i32) != 0)); + assert!(((((pw.pw_uid) == (libc::geteuid())) as i32) != 0)); + assert!(((((libc::strlen((pw.pw_name).cast_const())) > (0_usize)) as i32) != 0)); + let mut pw2: *mut ::libc::passwd = libc::getpwuid(libc::geteuid()); + assert!((((!((pw2).is_null())) as i32) != 0)); + assert!( + ((((libc::strcmp((pw.pw_name).cast_const(), ((*pw2).pw_name).cast_const())) == (0)) + as i32) + != 0) + ); + printf( + (c"%s\n".as_ptr().cast_mut()).cast_const() as *const i8, + pw.pw_name, + ); +} +pub unsafe fn test_getpwuid_r_erange_3() { + let mut pw: ::libc::passwd = unsafe { std::mem::zeroed() }; + let mut tiny: [libc::c_char; 1] = [(0 as libc::c_char); 1]; + let mut result: *mut ::libc::passwd = std::ptr::null_mut(); + assert!( + ((((libc::getpwuid_r( + libc::geteuid(), + (&mut pw as *mut ::libc::passwd), + tiny.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 1]>(), + (&mut result as *mut *mut ::libc::passwd) + )) == (34)) as i32) + != 0) + ); + assert!(((((result).is_null()) as i32) != 0)); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + (unsafe { test_getpwuid_0() }); + (unsafe { test_getpwuid_missing_1() }); + (unsafe { test_getpwuid_r_2() }); + (unsafe { test_getpwuid_r_erange_3() }); + return 0; +} diff --git a/tests/unit/pwd.c b/tests/unit/pwd.c new file mode 100644 index 00000000..9b9ad427 --- /dev/null +++ b/tests/unit/pwd.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include +#include + +static void test_getpwuid(void) { + struct passwd *pw = getpwuid(geteuid()); + assert(pw != NULL); + assert(pw->pw_uid == geteuid()); + assert(strlen(pw->pw_name) > 0); + assert(pw->pw_dir != NULL); + printf("%s\n", pw->pw_name); +} + +static void test_getpwuid_missing(void) { + errno = 0; + struct passwd *pw = getpwuid(0x7ffffffe); + assert(pw == NULL); + assert(errno == 0); +} + +static void test_getpwuid_r(void) { + struct passwd pw; + char buf[4096]; + struct passwd *result = NULL; + assert(getpwuid_r(geteuid(), &pw, buf, sizeof(buf), &result) == 0); + assert(result == &pw); + assert(pw.pw_uid == geteuid()); + assert(strlen(pw.pw_name) > 0); + struct passwd *pw2 = getpwuid(geteuid()); + assert(pw2 != NULL); + assert(strcmp(pw.pw_name, pw2->pw_name) == 0); + printf("%s\n", pw.pw_name); +} + +static void test_getpwuid_r_erange(void) { + struct passwd pw; + char tiny[1]; + struct passwd *result = NULL; + assert(getpwuid_r(geteuid(), &pw, tiny, sizeof(tiny), &result) == ERANGE); + assert(result == NULL); +} + +int main(void) { + test_getpwuid(); + test_getpwuid_missing(); + test_getpwuid_r(); + test_getpwuid_r_erange(); + return 0; +}