oss-sec mailing list archives
Re: libcap-2.69 addresses 2 CVEs
From: Solar Designer <solar () openwall com>
Date: Tue, 16 May 2023 11:39:16 +0200
On Mon, May 15, 2023 at 08:45:33AM -0700, Andrew G. Morgan wrote:
The release of libcap-2.69, announced here: https://sites.google.com/site/fullycapable/release-notes-for-libcap#h.iuvg7sbjg8pe addresses the following: - LCAP-CR-23-01 (SEVERITY) LOW (CVE-2023-2602) - found by David Gstir - LCAP-CR-23-02 (SEVERITY) MEDIUM (CVE-2023-2603) - found by Richard Weinberger The full details of both issues are provided in this audit report: https://www.x41-dsec.de/static/reports/X41-libcap-Code-Review-2023-OSTIF-Final-Report.pdf
Here's plain text export of the relevant part from the PDF file above: --- 4.1.1 LCAP-CR-23-01: Memory Leak on pthread_create() Error Severity: LOW CWE: 401 - Improper Release of Memory Before Removing Last Reference ('Memory Leak') Affected Component: libcap/psx/psx.c:__wrap_pthread_create() 4.1.1.1 Description X41 found that the error handling in __wrap_pthread_create() function is wrong and will leak mem- ory in case of an error. Function libpsx hooks the pthread_create() function and replaces it with __wrap_pthread_create(). This wrapping function will then register the required signal handler and call the actual pthread_create() (__real_pthread_create()). Here, the error handling for __real_pthread_create() is faulty as it checks for a negative return value which cannot happen. Instead, pthread_create() will return a value > 0 in case of an error1 . Thus, for every error in __real_pthread_create() where the tread routine (_psx_start_fn) is not called, the buffer starter will not be freed and thus this memory will be leaked once __wrap_pthread_create() returns. A malicious actor who is in the position to cause __real_pthread_create() to return an error, can potentially abuse this to exhaust the process memory. As libpsx hooks all pthread_create() calls of a process, this affects every thread. 1 * 2 * __wrap_pthread_create is the wrapped destination of all regular 3 * pthread_create calls. 4 */ 5 int __wrap_pthread_create(pthread_t *thread, const pthread_attr_t *attr, 6 void *(*start_routine) (void *), void *arg) { 7 psx_starter_t *starter = calloc(1, sizeof(psx_starter_t)); 8 9 // [...] 1 https://man7.org/linux/man-pages/man3/pthread_create.3.html X41 D-Sec GmbH PUBLIC Page 14 of 28 Source Code Audit on libcap for Open Source Technology Improvement Fund (OSTIF) 10 11 int ret = __real_pthread_create(thread, attr, _psx_start_fn, starter); 12 if (ret == -1) { 13 psx_new_state(_PSX_CREATE, _PSX_IDLE); 14 memset(starter, 0, sizeof(*starter)); 15 free(starter); 16 } /* else unlock happens in _psx_start_fn */ 17 18 /* the parent can once again receive psx interrupt signals */ 19 pthread_sigmask(SIG_SETMASK, &orig_sigbits, NULL); 20 21 return ret; 22 } Listing 4.1: Code Snippet Showing the Affected Part of __wrap_pthread_create() 4.1.1.2 Solution Advice While not critical, X41 advises fixing the error handling code to prevent any abuse from being possible. X41 D-Sec GmbH PUBLIC Page 15 of 28 Source Code Audit on libcap for Open Source Technology Improvement Fund (OSTIF) 4.1.2 LCAP-CR-23-02: Integer Overflow in _libcap_strdup() Severity: MEDIUM CWE: 190 - Integer Overflow or Wraparound Affected Component: libcap/cap_alloc.c:_libcap_strdup() 4.1.2.1 Description X41 found that in 32 bits execution mode, where sizeof(size_t) equals 4, the _libcap_strdup() func- tion can suffer from an integer overflow of the input string is close to a length of 4GiB. In this case len = strlen(old) + 1 + 2*sizeof(__u32); will overflow and results into a value much smaller than 4GiB. As consequence the overflow check len & 0xffffffff) != len will have no effect and the strcpy() func- tion at the end of the function will overwrite the heap. 1 __attribute__((visibility ("hidden"))) char *_libcap_strdup(const char *old) 2 { 3 struct _cap_alloc_s *header; 4 char *raw_data; 5 size_t len; 6 7 [...] 8 9 len = strlen(old) + 1 + 2*sizeof(__u32); 10 if (len < sizeof(struct _cap_alloc_s)) { 11 len = sizeof(struct _cap_alloc_s); 12 } 13 if ((len & 0xffffffff) != len) { 14 _cap_debug("len is too long for libcap to manage"); 15 errno = EINVAL; 16 return NULL; 17 } 18 19 raw_data = calloc(1, len); 20 21 [...] 22 23 strcpy(raw_data, old); 24 return raw_data; 25 } Listing 4.2: Code Snippet Showing the Affected Part of _libcap_strdup() X41 D-Sec GmbH PUBLIC Page 16 of 28 Source Code Audit on libcap for Open Source Technology Improvement Fund (OSTIF) 4.1.2.2 Solution Advice While the overflow is impossible to exploit on a pure 32 bits system because no user space ap- plication can use the whole 32 bits address space it might be possible on a 64 bits kernel in 32 bits compat mode. In this mode user space is allowed to use the full 32 bits address space. X41 advises checking whether strlen() returns a sufficient large number to overflow the addition. --- Alexander
Current thread:
- libcap-2.69 addresses 2 CVEs Andrew G. Morgan (May 15)
- Re: libcap-2.69 addresses 2 CVEs Solar Designer (May 16)