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

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Mon, 7 Oct 2019 09:48:16 -0700
On 9/25/19 10:33 AM, Sergey Kandaurov wrote:
> 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

CAP_SEEK and CAP_MMAP_X might also be subject to this.  However, I'm not quite
understanding the regex, or at least why the modified portion of the regex isn't
something like this:

(CAPRIGHT\(|\(CAP_LOOKUP)

That is, you currently have [()A-Z_|[:space:]]+ for an expression that I think
will only ever match a single '(' character.

A more general form that might work for CAP_SEEK and CAP_MMAP_X might be
to match on 'CAP_<foo> | 0x<constant)', so something like:

(CAPRIGHT\(|\([^)]*CAP_[A-Z_]+ \| 0x[0-9]+)

-- 
John Baldwin
Received on Mon Oct 07 2019 - 14:48:21 UTC

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