1*cc02d7e2SAndroid Build Coastguard Worker# gRPC Security Audit 2*cc02d7e2SAndroid Build Coastguard Worker 3*cc02d7e2SAndroid Build Coastguard WorkerA third-party security audit of gRPC C++ stack was performed by [Cure53](https://cure53.de) in October 2019. The full report can be found [here](https://github.com/grpc/grpc/tree/master/doc/grpc_security_audit.pdf). 4*cc02d7e2SAndroid Build Coastguard Worker 5*cc02d7e2SAndroid Build Coastguard Worker# Addressing grpc_security_audit 6*cc02d7e2SAndroid Build Coastguard Worker 7*cc02d7e2SAndroid Build Coastguard WorkerThe following describes how gRPC team has or will address each of the security issues pointed out in the report. 8*cc02d7e2SAndroid Build Coastguard Worker 9*cc02d7e2SAndroid Build Coastguard Worker## GRP-01-001 DoS through uninitialized pointer dereference 10*cc02d7e2SAndroid Build Coastguard Worker 11*cc02d7e2SAndroid Build Coastguard WorkerGRP-01-001 was fixed in version 1.24.0 and above with https://github.com/grpc/grpc/pull/20351. The fix was also patched in version 1.23.1. 12*cc02d7e2SAndroid Build Coastguard Worker 13*cc02d7e2SAndroid Build Coastguard Worker## GRP-01-002 Refs to freed memory not automatically nulled 14*cc02d7e2SAndroid Build Coastguard WorkerGRP-01-002 describes a programming pattern in gRPC Core where `gpr_free` is called and then the pointer is nulled afterwards. GRP-01-002 can be split into two concerns: 1) dangling pointer bugs and 2) the potential vulnerability of leveraging other bugs to access data through a freed pointer. 15*cc02d7e2SAndroid Build Coastguard Worker 16*cc02d7e2SAndroid Build Coastguard WorkerRegarding 1), gRPC uses a suite of sanitizer tests (asan, tsan, etc) to detect and fix any memory-related bugs. gRPC is also in the process of moving to c++ and the standard library, enabling the use of smart pointers in Core and thus making it harder to generate memory-related bugs. There are also plans to remove `gpr_free` in general. 17*cc02d7e2SAndroid Build Coastguard Worker 18*cc02d7e2SAndroid Build Coastguard WorkerRegarding 2), moving to smart pointers (in particular, unique_ptr) will help this issue as well. In addition, gRPC has continuous fuzzing tests to find and resolve security issues, and the pen test did not discover any concrete vulnerabilities in this area. 19*cc02d7e2SAndroid Build Coastguard Worker 20*cc02d7e2SAndroid Build Coastguard WorkerBelow is a list of alternatives that gRPC team considered. 21*cc02d7e2SAndroid Build Coastguard Worker 22*cc02d7e2SAndroid Build Coastguard Worker 23*cc02d7e2SAndroid Build Coastguard Worker### Alternative #1: Rewrite gpr_free to take void\*\* 24*cc02d7e2SAndroid Build Coastguard WorkerOne solution is to change the API of `gpr_free` so that it automatically nulls the given pointer after freeing it. 25*cc02d7e2SAndroid Build Coastguard Worker 26*cc02d7e2SAndroid Build Coastguard Worker``` 27*cc02d7e2SAndroid Build Coastguard Workergpr_free (void** ptr) { 28*cc02d7e2SAndroid Build Coastguard Worker ... 29*cc02d7e2SAndroid Build Coastguard Worker *ptr = nullptr; 30*cc02d7e2SAndroid Build Coastguard Worker} 31*cc02d7e2SAndroid Build Coastguard Worker``` 32*cc02d7e2SAndroid Build Coastguard Worker 33*cc02d7e2SAndroid Build Coastguard WorkerThis defensive programming pattern would help protect gRPC from the potential exploits and latent dangling pointer bugs mentioned in the security report. 34*cc02d7e2SAndroid Build Coastguard Worker 35*cc02d7e2SAndroid Build Coastguard WorkerHowever, performance would be a significant concern as we are now unconditionally adding a store to every gpr_free call, and there are potentially hundreds of these per RPC. At the RPC layer, this can add up to prohibitive costs. 36*cc02d7e2SAndroid Build Coastguard Worker 37*cc02d7e2SAndroid Build Coastguard WorkerMaintainability is also an issue since this approach impacts use of `*const`. Member pointers that are set in the initialization list of a constructor and not changed thereafter can be declared `*const`. This is a useful compile-time check if the member is taking ownership of something that was passed in by argument or allocated through a helper function called by the constructor initializer list. If this thing needs to be `gpr_free`'d using the proposed syntax, it can no longer be `*const` and we lose these checks (or we have to const_cast it which is also error-prone). 38*cc02d7e2SAndroid Build Coastguard Worker 39*cc02d7e2SAndroid Build Coastguard WorkerAnother concern is readability - this `gpr_free` interface is less intuitive than the current one. 40*cc02d7e2SAndroid Build Coastguard Worker 41*cc02d7e2SAndroid Build Coastguard WorkerYet another concern is that the use of non-smart pointers doesn’t imply ownership - it doesn’t protect against spare copies of the same pointers. 42*cc02d7e2SAndroid Build Coastguard Worker 43*cc02d7e2SAndroid Build Coastguard Worker### Alternative #2: Add another gpr_free to the Core API 44*cc02d7e2SAndroid Build Coastguard WorkerAdding an alternative `gpr_free` that nulls the given pointer is undesirable because we cannot enforce that we’re using this version of `gpr_free` everywhere we need to. It doesn’t solve the original problem because it doesn’t reduce the chance of programmer error. 45*cc02d7e2SAndroid Build Coastguard Worker 46*cc02d7e2SAndroid Build Coastguard WorkerLike alternative #1, this solution doesn’t protect against spare copies of the same pointers and is subject to the same maintainability concerns. 47*cc02d7e2SAndroid Build Coastguard Worker 48*cc02d7e2SAndroid Build Coastguard Worker### Alternative #3: Rewrite gpr_free to take void\*& 49*cc02d7e2SAndroid Build Coastguard Worker``` 50*cc02d7e2SAndroid Build Coastguard Workergpr_free (void*& ptr) { 51*cc02d7e2SAndroid Build Coastguard Worker ... 52*cc02d7e2SAndroid Build Coastguard Worker ptr = nullptr; 53*cc02d7e2SAndroid Build Coastguard Worker} 54*cc02d7e2SAndroid Build Coastguard Worker``` 55*cc02d7e2SAndroid Build Coastguard WorkerThis falls into the same pitfalls as solution #1 and furthermore is C89 non-compliant, which is a current requirement for `gpr_free`. Moreover, Google’s style guide discourages non-const reference parameters, so this is even less desirable than solution #1. 56*cc02d7e2SAndroid Build Coastguard Worker 57*cc02d7e2SAndroid Build Coastguard Worker 58*cc02d7e2SAndroid Build Coastguard Worker### Conclusion 59*cc02d7e2SAndroid Build Coastguard WorkerBecause of performance and maintainability concerns, GRP-01-002 will be addressed through the ongoing work to move gRPC Core to C++ and smart pointers and the future work of removing `gpr_free` in general. We will continue to leverage our sanitizer and fuzzing tests to help expose vulnerabilities. 60*cc02d7e2SAndroid Build Coastguard Worker 61*cc02d7e2SAndroid Build Coastguard Worker## GRP-01-003 Calls to malloc suffer from potential integer overflows 62*cc02d7e2SAndroid Build Coastguard WorkerThe vulnerability, as defined by the report, is that calls to `gpr_malloc` in the C-core codebase may suffer from potential integer overflow in cases where we multiply the array element size by the size of the array. The penetration testers did not identify a concrete place where this occurred, but rather emphasized that the coding pattern itself had potential to lead to vulnerabilities. The report’s suggested solution for GRP-01-003 was to create a `calloc(size_t nmemb, size_t size)` wrapper that contains integer overflow checks. 63*cc02d7e2SAndroid Build Coastguard Worker 64*cc02d7e2SAndroid Build Coastguard WorkerHowever, gRPC team firmly believes that gRPC Core should only use integer overflow checks in the places where they’re needed; for example, any place where remote input influences the input to `gpr_malloc` in an unverified way. This is because bounds-checking is very expensive at the RPC layer. 65*cc02d7e2SAndroid Build Coastguard Worker 66*cc02d7e2SAndroid Build Coastguard WorkerDetermining exactly where bounds-checking is needed requires an audit of tracing each `gpr_malloc` (or `gpr_realloc` or `gpr_zalloc`) call up the stack to determine if the sufficient bounds-checking was performed. This kind of audit, done manually, is fairly expensive engineer-wise. 67*cc02d7e2SAndroid Build Coastguard Worker 68*cc02d7e2SAndroid Build Coastguard Worker### Conclusion 69*cc02d7e2SAndroid Build Coastguard WorkerGRP-01-003 will be addressed through leveraging gRPC Core fuzzer tests to actively identify and resolve any integer overflow issues. If any issues are identified, we may create a `gpr_safe_malloc(size_t nmemb, size_t size)` wrapper to consolidate bounds-checking in one place. This function will *not* zero out memory because of performance concerns, and so will not be a calloc-style wrapper. 70*cc02d7e2SAndroid Build Coastguard Worker 71