Re: ktrace/kdump give incorrect message on unlinkat() failure due to capabilities

From: Sergey Kandaurov <pluknet_at_freebsd.org>
Date: Wed, 25 Sep 2019 20:33:38 +0300
On Sat, Sep 21, 2019 at 08:43:58PM -0400, Ryan Stone wrote:
> I have written a short test program that runs unlinkat(2) in
> capability mode and fails due to not having the write capabilities:
> 
> https://people.freebsd.org/~rstone/src/unlink.c
> 
> If I run the binary under ktrace and look at the kdump output, it
> gives the following incorrect output:
> 
> 43775 unlink   CALL  unlinkat(0x3,0x7fffffffe995,0)
> 43775 unlink   NAMI  "from.QAUlAA0"
> 43775 unlink   CAP   operation requires CAP_LOOKUP, descriptor holds CAP_LOOKUP
> 43775 unlink   RET   unlinkat -1 errno 93 Capabilities insufficient
> 
> The message should instead say that the operation requires
> CAP_UNLINKAT.  Looking at sys/capsicum.h, I suspect that the problem
> is related to the strange definition of CAP_UNLINKAT:
> 
> #define CAP_UNLINKAT (CAP_LOOKUP | 0x0000000010000000ULL)

FYI, with this grep it was able to decode capabilities.

Index: lib/libsysdecode/mktables
===================================================================
--- lib/libsysdecode/mktables	(revision 352685)
+++ lib/libsysdecode/mktables	(working copy)
_at__at_ -157,7 +157,7 _at__at_
 gen_table "sigcode"         "SI_[A-Z]+[[:space:]]+0(x[0-9abcdef]+)?"       "sys/signal.h"
 gen_table "umtxcvwaitflags" "CVWAIT_[A-Z_]+[[:space:]]+0x[0-9]+"           "sys/umtx.h"
 gen_table "umtxrwlockflags" "URWLOCK_PREFER_READER[[:space:]]+0x[0-9]+"    "sys/umtx.h"
-gen_table "caprights"       "CAP_[A-Z_]+[[:space:]]+CAPRIGHT\([0-9],[[:space:]]+0x[0-9]{16}ULL\)"   "sys/capsicum.h"
+gen_table "caprights"       "CAP_[A-Z_]+[[:space:]]+(CAPRIGHT|[()A-Z_|[:space:]]+CAP_LOOKUP)"   "sys/capsicum.h"
 gen_table "sctpprpolicy"    "SCTP_PR_SCTP_[A-Z_]+[[:space:]]+0x[0-9]+"     "netinet/sctp_uio.h" "SCTP_PR_SCTP_ALL"
 gen_table "cmsgtypesocket"  "SCM_[A-Z_]+[[:space:]]+0x[0-9]+"              "sys/socket.h"
 if [ -e "${include_dir}/x86/sysarch.h" ]; then

On unlink.c, it gives:
 45494 unlink   CALL  cap_rights_limit(0x3,0x7fffffffead0)
 45494 unlink   STRU  cap_rights_t CAP_LOOKUP
 45494 unlink   RET   cap_rights_limit 0
 45494 unlink   CALL  openat(AT_FDCWD,0x200323,0<O_RDONLY>)
 45494 unlink   NAMI  "/tmp"
 45494 unlink   RET   openat 4
 45494 unlink   CALL  cap_rights_limit(0x4,0x7fffffffead0)
 45494 unlink   STRU  cap_rights_t CAP_LOOKUP,CAP_UNLINKAT
 45494 unlink   RET   cap_rights_limit 0
 45494 unlink   CALL  cap_enter
 45494 unlink   RET   cap_enter 0
 45494 unlink   CALL  unlinkat(0x3,0x7fffffffeaa5,0)
 45494 unlink   NAMI  "from.YG6jQx2"
 45494 unlink   CAP   operation requires CAP_LOOKUP,CAP_UNLINKAT, descriptor holds CAP_LOOKUP

> I have observed the same problem with renameat(2) and
> CAP_RENAMEAT_SOURCE and CAP_RENAMEAT_TARGET:
> 
> https://people.freebsd.org/~rstone/src/rename.c

 49410 rename   CAP   operation requires CAP_LOOKUP,CAP_RENAMEAT_SOURCE, descriptor holds CAP_LOOKUP
Received on Wed Sep 25 2019 - 15:33:43 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:22 UTC