*outlen = sizeof(ULong);
}
-static Bool sysctl_kern_proc_pathname(HChar *out, SizeT *len)
+static Int sysctl_kern_proc_pathname(HChar *out, SizeT *len)
{
const HChar *exe_name = VG_(resolved_exename);
+ // assert that exe_name is an absolute path
+ vg_assert(exe_name && exe_name[0] == '/');
if (!len) {
- return False;
+ return VKI_ENOMEM;
}
+ if (!ML_(safe_to_deref)(len, sizeof(len))) {
+ // ???? check
+ return VKI_ENOMEM;
+ }
+
+ SizeT exe_name_length = VG_(strlen)(exe_name)+1;
if (!out) {
- HChar tmp[VKI_PATH_MAX];
- if (!VG_(realpath)(exe_name, tmp)) {
- return False;
- }
- *len = VG_(strlen)(tmp)+1;
- return True;
+ *len = exe_name_length;
+ return 0;
}
- if (!VG_(realpath)(exe_name, out)) {
- return False;
+ if (*len < exe_name_length) {
+ return VKI_ENOMEM;
}
- *len = VG_(strlen)(out)+1;
- return True;
+ if (ML_(safe_to_deref)(out, exe_name_length)) {
+ VG_(strncpy)(out, exe_name, exe_name_length);
+ } else {
+ // ???? check
+ return VKI_EFAULT;
+ }
+
+ *len = exe_name_length;
+ return 0;
}
// SYS___sysctl 202
if (SARG2 == 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) {
if (name[0] == 1 && name[1] == 32) {
if (sysctl_kern_ps_strings((SizeT*)ARG3, (SizeT*)ARG4)) {
- SET_STATUS_Success(0);
+ SET_STATUS_Success(0);
}
}
}
if (name[0] == 1 && name[1] == 14 && name[2] == 12) {
vki_pid_t pid = (vki_pid_t)name[3];
if (pid == -1 || pid == VG_(getpid)()) {
- sysctl_kern_proc_pathname((HChar *)ARG3, (SizeT *)ARG4);
- SET_STATUS_Success(0);
+ int res = sysctl_kern_proc_pathname((HChar *)ARG3, (SizeT *)ARG4);
+ if (res == 0) {
+ SET_STATUS_Success(0);
+ } else {
+ SET_STATUS_Failure(res);
+ }
}
}
}
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
size_t len;
- if (sysctl(mib, 4, NULL, &len, NULL, 0) != 0) {
- cout << "sysctl failed to get path length: " << std::strerror(errno) << '\n';
+ if (argc < 2)
+ {
+ std::cout << "ERROR: missing argument, expected \"" << argv[0] << " {absolute path of " << argv[0] << "}\"\n";
return -1;
}
+ if (sysctl(mib, 4, nullptr, &len, nullptr, 0) != 0) {
+ cout << "ERROR: sysctl failed to get path length: " << std::strerror(errno) << '\n';
+ return -1;
+ }
+
+ // not for regtest, path length may vary
+ // std::cout << "read length " << len << '\n';
+
std::unique_ptr<char[]> aResult(new char[len]);
- if (sysctl(mib, 4, aResult.get(), &len, NULL, 0) != 0) {
- cout << "sysctl failed to get path: " << strerror(errno) << '\n';
+ if (sysctl(mib, 4, aResult.get(), &len, nullptr, 0) != 0) {
+ cout << "ERROR: sysctl failed to get path: " << strerror(errno) << '\n';
return -1;
}
if (string(aResult.get()) == argv[1]) {
- cout << "OK\n";
+ cout << "OK: got expected pathname\n";
+ } else {
+ cout << "ERROR: aResult " << aResult.get() << " argv[1] " << argv[1] << '\n';
+ }
+
+ if (sysctl(mib, 4, aResult.get(), nullptr, nullptr, 0) != 0) {
+ cout << "OK: sysctl failed with nullptr length: " << strerror(errno) << '\n';
+ } else {
+ cout << "ERROR: nullptr length sysctl succeeded when it should have failed\n";
+ }
+
+ size_t bad_len = len - 3U;
+ if (sysctl(mib, 4, aResult.get(), &bad_len, nullptr, 0) != 0) {
+ cout << "OK: sysctl failed to get path with bad_len: " << strerror(errno) << '\n';
} else {
- cout << "Not OK aResult " << aResult.get() << " argv[1] " << argv[1] << '\n';
+ cout << "ERROR: bad_len sysctl succeeded when it should have failed\n";
+ return -1;
}
- if (sysctl(mib, 4, NULL, NULL, NULL, 0) != -1) {
- cout << "OK syscall failed\n";
+ if (sysctl(mib, 4, nullptr, &len, nullptr, 0) != -1) {
+ cout << "OK: sysctl failed with nullptr name: " << strerror(errno) << '\n';
return -1;
} else {
- cout << "sysctl succeeded when it should have failed\n";
+ cout << "ERROR: nullptr name sysctl succeeded when it should have failed\n";
}
}
-