-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Hi,
When using this library via xrootd-server on CentOS8 (version 0.5.1 from EPEL or OSG repos), I get the following crash when verifying a token:
#0 0x00007fb245d0d7ff in raise () from /lib64/libc.so.6
#1 0x00007fb245cf7c35 in abort () from /lib64/libc.so.6
#2 0x00007fb23fdc8b54 in std::__replacement_assert (__condition=0x7fb23fdcb130 "__builtin_expect(__n < this->size(), true)", __function=<synthetic pointer>, __line=932, __file=0x7fb23fdcb160 "/usr/include/c++/8/bits/stl_vector.h")
at /usr/include/c++/8/x86_64-redhat-linux/bits/c++config.h:2391
#3 std::vector<char, std::allocator<char> >::operator[] (__n=0, this=<synthetic pointer>) at /usr/include/c++/8/bits/stl_vector.h:932
#4 (anonymous namespace)::get_cache_file () at /usr/src/debug/scitokens-cpp-0.5.1-2.el8.x86_64/src/scitokens_cache.cpp:62
...
which refers to these lines of code:
scitokens-cpp/src/scitokens_cache.cpp
Lines 57 to 62 in 6870564
| std::vector<char> buf; | |
| buf.reserve(bufsize); | |
| std::string home_dir; | |
| struct passwd pwd, *result = NULL; | |
| getpwuid_r(geteuid(), &pwd, &buf[0], bufsize, &result); |
I think the problem is that accessing buf[0] is technically an out-of-bounds access because the vector is empty, but on glibc it does still return the start of the internal array so generally works (although this is undefined behaviour). When the code is put through the CentOS8 RPM build system, the build system adds a number of fortification options by default, which appears to include a bounds check on the [] operator, triggering the assert crash I'm seeing.
Would it be possible to fix this? I've included a patch below that I've been using as a workaround (although I haven't tested it very thoroughly).
Regards,
Simon
+++ b/src/scitokens_cache.cpp
@@ -1,7 +1,7 @@
#include <cstdint>
#include <string>
-#include <vector>
+#include <memory>
#include <pwd.h>
#include <stdlib.h>
@@ -54,12 +54,11 @@ get_cache_file() {
auto bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
bufsize = (bufsize == -1) ? 16384 : bufsize;
- std::vector<char> buf;
- buf.reserve(bufsize);
+ std::unique_ptr<char[]> buf(new char[bufsize]);
std::string home_dir;
struct passwd pwd, *result = NULL;
- getpwuid_r(geteuid(), &pwd, &buf[0], bufsize, &result);
+ getpwuid_r(geteuid(), &pwd, buf.get(), bufsize, &result);
if (result && result->pw_dir) {
home_dir = result->pw_dir;
home_dir += "/.cache";