Bug 207549

Summary: when kernel is ahead of libcap we can get a segfault
Product: Tools Reporter: Andrew G. Morgan (morgan)
Component: libcapAssignee: Andrew G. Morgan (morgan)
Status: RESOLVED CODE_FIX    
Severity: blocking    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: linux-next Subsystem:
Regression: No Bisected commit-id:

Description Andrew G. Morgan 2020-05-02 23:15:06 UTC
This report and proposed patch is from Heiner Kallweit.

When testing a linux-next kernel on my system I got the following:
ntpd[]: segfault at [xx] ip [xx] sp [xx] error 4 in libcap.so.2.33[xx]
It turned out that a new capability (CAP_PERFMON) causes the issue.
_cap_max_bits is 39 now, whilst __CAP_BITS is 38. This results in
reading beyond the end of _cap_names[] .

Proposed patch:

---
 libcap/cap_alloc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/libcap/cap_alloc.c b/libcap/cap_alloc.c
index 6dab4e6..358d848 100644
--- a/libcap/cap_alloc.c
+++ b/libcap/cap_alloc.c
@@ -18,6 +18,13 @@ __attribute__((constructor (300))) static void _initialize_libcap(void) {
     }
     cap_set_syscall(NULL, NULL);
     _binary_search(_cap_max_bits, cap_get_bound, 0, __CAP_MAXBITS, __CAP_BITS);
+
+    /* kernel seems to report capabilities that libcap doesn't know yet */
+    if (_cap_max_bits > __CAP_BITS) {
+        _cap_debug("reducing _cap_max_bits from %d to %d\n",
+                   _cap_max_bits, __CAP_BITS);
+        _cap_max_bits = __CAP_BITS;
+    }
 }

 cap_value_t cap_max_bits(void) {
--
2.26.2
Comment 1 Andrew G. Morgan 2020-05-03 00:19:03 UTC
Fix:

https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=d10409db4cda0ab56d500de5658b9c6851301c2a

Will attempt to confirm with Heiner before closing.
Comment 2 Andrew G. Morgan 2020-05-03 15:48:27 UTC
Heiner confirmed that this fixes the issue he'd found.