From a4d4e7365ba195670eba1db13b759561f9b0ea78 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Gattupalli Date: Thu, 2 Sep 2021 09:08:21 +0530 Subject: ADSPRPC: Sanitize local fastrpc handle Observed use after free issue when passed handle that has been closed as part of a negative test. On function verify_local_handle() we receive local handle and try to dereference but local handle has already been freed. Solution is to check if handle is still open by traversing list of all handles that have been opened for all domains. CRs-Fixed: 2944637 Change-Id: I2a3afb655c08c4e4ece2f74659d5d94a0d29523d --- src/fastrpc_apps_user.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/fastrpc_apps_user.c b/src/fastrpc_apps_user.c index 7d159cf..1dbc58e 100644 --- a/src/fastrpc_apps_user.c +++ b/src/fastrpc_apps_user.c @@ -560,11 +560,31 @@ static int fdlist_fd_from_buf(void* buf, int bufLen, int* nova, void** base, int return 0; } +static inline int is_valid_local_handle(struct handle_info* hinfo) { + int domain = 0; + QNode* pn = NULL; + struct handle_info* hi = NULL; + + for (domain = 0; domain < NUM_DOMAINS_EXTEND; domain++) { + pthread_mutex_lock(&hlist[domain].mut); + QLIST_FOR_ALL(&hlist[domain].ql, pn) { + hi = STD_RECOVER_REC(struct handle_info, qn, pn); + if (hi == hinfo) { + pthread_mutex_unlock(&hlist[domain].mut); + return 1; + } + } + pthread_mutex_unlock(&hlist[domain].mut); + } + return 0; +} + static int verify_local_handle(remote_handle64 local) { struct handle_info* hinfo = (struct handle_info*)(uintptr_t)local; int nErr = AEE_SUCCESS; VERIFYC(hinfo, AEE_EMEMPTR); + VERIFYC(is_valid_local_handle(hinfo), AEE_EBADHANDLE); VERIFYC((hinfo->hlist >= &hlist[0]) && (hinfo->hlist < &hlist[NUM_DOMAINS_EXTEND]), AEE_EMEMPTR); VERIFYC(QNode_IsQueuedZ(&hinfo->qn), AEE_ENOSUCHHANDLE); bail: -- cgit v1.2.3 From 5441a5be1ae11a0a34a0f77f59e97e249b2b5872 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Gattupalli Date: Tue, 7 Sep 2021 18:01:24 +0530 Subject: ADSPRPC: Pass 64 bit va buffer to remote_mmap64 from remote_mmap API remote_mmap is a wrapper that calls remote_mmap64 with 32 bit VA buffer. API remote_mmap64 will write 64 bit to VA buffer, which will result in buffer overflow. Adding intermediate 64 bit buffer in between call to remote_mmap64 and then safely copying from 64 bit buffer to 32 bit buffer. CRs-Fixed: 2960630 Change-Id: I1a1671e0150bbd6305fea4d2805bc62807b89b3b --- src/fastrpc_apps_user.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fastrpc_apps_user.c b/src/fastrpc_apps_user.c index 7d159cf..b3f12d0 100644 --- a/src/fastrpc_apps_user.c +++ b/src/fastrpc_apps_user.c @@ -1230,7 +1230,12 @@ bail: } int remote_mmap(int fd, uint32_t flags, uint32_t vaddrin, int size, uint32_t* vaddrout) { - return remote_mmap64(fd, flags, (uintptr_t)vaddrin, (int64_t)size, (uint64_t*)vaddrout); + uint64_t vaddrout_64; + int nErr = 0; + + nErr = remote_mmap64(fd, flags, (uintptr_t)vaddrin, (int64_t)size, &vaddrout_64); + *vaddrout = (uint32_t)vaddrout_64; + return nErr; } int remote_munmap64(uint64_t vaddrout, int64_t size) { -- cgit v1.2.3