# GNU debugger checking for PaX and refusing to work with it

## miroR

The following is based on claims from people I trust.

(the axiom of not knowing that the Earth revolves around Sun but trusting that it does so because worthy people claim it to be the case, applies here for worthy

grsecurity/PaX developers' claim)

So, for the record. It's about this program:

```

*  sys-devel/gdb

      Latest version available: 7.8.2

      Latest version installed: 7.8.2

      Size of files: 17,265 KiB

      Homepage:      http://sourceware.org/gdb/

      Description:   GNU debugger

      License:       GPL-2 LGPL-2

```

And what that program does is, in PaX Team's own words:

 *PaX Team wrote:*   

> 
> 
> i checked the gdb sources now and it's intentional behaviour (check gdb/common/linux-ptrace.c:linux_ptrace_test_ret_to_nx). they're trying to detect the presence of PaX/MPROTECT, though in a broken way since the code execution attempt on a non-executable page would fail on any recent CPU/kernel too...
> 
> 

 

I looked up the source but don't understand so much. However, for the record, here is that file:

gdb/common/linux-ptrace.c:

```

/* Linux-specific ptrace manipulation routines.

   Copyright (C) 2012-2014 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify

   it under the terms of the GNU General Public License as published by

   the Free Software Foundation; either version 3 of the License, or

   (at your option) any later version.

   This program is distributed in the hope that it will be useful,

   but WITHOUT ANY WARRANTY; without even the implied warranty of

   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License

   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifdef GDBSERVER

#include "server.h"

#else

#include "defs.h"

#include <string.h>

#endif

#include "linux-ptrace.h"

#include "linux-procfs.h"

#include "nat/linux-waitpid.h"

#include "buffer.h"

#include "gdb_assert.h"

#include "gdb_wait.h"

#include <stdint.h>

/* Stores the currently supported ptrace options.  A value of

   -1 means we did not check for features yet.  A value of 0 means

   there are no supported features.  */

static int current_ptrace_options = -1;

/* Find all possible reasons we could fail to attach PID and append

   these as strings to the already initialized BUFFER.  '\0'

   termination of BUFFER must be done by the caller.  */

void

linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer)

{

  pid_t tracerpid;

  tracerpid = linux_proc_get_tracerpid (pid);

  if (tracerpid > 0)

    buffer_xml_printf (buffer, _("process %d is already traced "

             "by process %d"),

             (int) pid, (int) tracerpid);

  if (linux_proc_pid_is_zombie (pid))

    buffer_xml_printf (buffer, _("process %d is a zombie "

             "- the process has already terminated"),

             (int) pid);

}

#if defined __i386__ || defined __x86_64__

/* Address of the 'ret' instruction in asm code block below.  */

extern void (linux_ptrace_test_ret_to_nx_instr) (void);

#include <sys/reg.h>

#include <sys/mman.h>

#include <signal.h>

#endif /* defined __i386__ || defined __x86_64__ */

/* Test broken off-trunk Linux kernel patchset for NX support on i386.  It was

   removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd.

   Test also x86_64 arch for PaX support.  */

static void

linux_ptrace_test_ret_to_nx (void)

{

#if defined __i386__ || defined __x86_64__

  pid_t child, got_pid;

  gdb_byte *return_address, *pc;

  long l;

  int status, kill_status;

  return_address = mmap (NULL, 2, PROT_READ | PROT_WRITE,

          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

  if (return_address == MAP_FAILED)

    {

      warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),

          strerror (errno));

      return;

    }

  /* Put there 'int3'.  */

  *return_address = 0xcc;

  child = fork ();

  switch (child)

    {

    case -1:

      warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),

          strerror (errno));

      return;

    case 0:

      l = ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) NULL,

        (PTRACE_TYPE_ARG4) NULL);

      if (l != 0)

   warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),

       strerror (errno));

      else

   {

#if defined __i386__

     asm volatile ("pushl %0;"

         ".globl linux_ptrace_test_ret_to_nx_instr;"

         "linux_ptrace_test_ret_to_nx_instr:"

         "ret"

         : : "r" (return_address) : "%esp", "memory");

#elif defined __x86_64__

     asm volatile ("pushq %0;"

         ".globl linux_ptrace_test_ret_to_nx_instr;"

         "linux_ptrace_test_ret_to_nx_instr:"

         "ret"

         : : "r" ((uint64_t) (uintptr_t) return_address)

         : "%rsp", "memory");

#else

# error "!__i386__ && !__x86_64__"

#endif

     gdb_assert_not_reached ("asm block did not terminate");

   }

      _exit (1);

    }

  errno = 0;

  got_pid = waitpid (child, &status, 0);

  if (got_pid != child)

    {

      warning (_("linux_ptrace_test_ret_to_nx: waitpid returned %ld: %s"),

          (long) got_pid, strerror (errno));

      return;

    }

  if (WIFSIGNALED (status))

    {

      if (WTERMSIG (status) != SIGKILL)

   warning (_("linux_ptrace_test_ret_to_nx: WTERMSIG %d is not SIGKILL!"),

       (int) WTERMSIG (status));

      else

   warning (_("Cannot call inferior functions, Linux kernel PaX "

         "protection forbids return to non-executable pages!"));

      return;

    }

  if (!WIFSTOPPED (status))

    {

      warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),

          status);

      return;

    }

  /* We may get SIGSEGV due to missing PROT_EXEC of the return_address.  */

  if (WSTOPSIG (status) != SIGTRAP && WSTOPSIG (status) != SIGSEGV)

    {

      warning (_("linux_ptrace_test_ret_to_nx: "

       "WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),

          (int) WSTOPSIG (status));

      return;

    }

  errno = 0;

#if defined __i386__

  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (EIP * 4),

         (PTRACE_TYPE_ARG4) NULL);

#elif defined __x86_64__

  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (RIP * 8),

         (PTRACE_TYPE_ARG4) NULL);

#else

# error "!__i386__ && !__x86_64__"

#endif

  if (errno != 0)

    {

      warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER: %s"),

          strerror (errno));

      return;

    }

  pc = (void *) (uintptr_t) l;

  kill (child, SIGKILL);

  ptrace (PTRACE_KILL, child, (PTRACE_TYPE_ARG3) NULL,

     (PTRACE_TYPE_ARG4) NULL);

  errno = 0;

  got_pid = waitpid (child, &kill_status, 0);

  if (got_pid != child)

    {

      warning (_("linux_ptrace_test_ret_to_nx: "

       "PTRACE_KILL waitpid returned %ld: %s"),

          (long) got_pid, strerror (errno));

      return;

    }

  if (!WIFSIGNALED (kill_status))

    {

      warning (_("linux_ptrace_test_ret_to_nx: "

       "PTRACE_KILL status %d is not WIFSIGNALED!"),

          status);

      return;

    }

  /* + 1 is there as x86* stops after the 'int3' instruction.  */

  if (WSTOPSIG (status) == SIGTRAP && pc == return_address + 1)

    {

      /* PASS */

      return;

    }

  /* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page.  */

  if (WSTOPSIG (status) == SIGSEGV && pc == return_address)

    {

      /* PASS */

      return;

    }

  if ((void (*) (void)) pc != &linux_ptrace_test_ret_to_nx_instr)

    warning (_("linux_ptrace_test_ret_to_nx: PC %p is neither near return "

          "address %p nor is the return instruction %p!"),

        pc, return_address, &linux_ptrace_test_ret_to_nx_instr);

  else

    warning (_("Cannot call inferior functions on this system - "

          "Linux kernel with broken i386 NX (non-executable pages) "

          "support detected!"));

#endif /* defined __i386__ || defined __x86_64__ */

}

/* Helper function to fork a process and make the child process call

   the function FUNCTION, passing CHILD_STACK as parameter.

   For MMU-less targets, clone is used instead of fork, and

   CHILD_STACK is used as stack space for the cloned child.  If NULL,

   stack space is allocated via malloc (and subsequently passed to

   FUNCTION).  For MMU targets, CHILD_STACK is ignored.  */

static int

linux_fork_to_function (gdb_byte *child_stack, void (*function) (gdb_byte *))

{

  int child_pid;

  /* Sanity check the function pointer.  */

  gdb_assert (function != NULL);

#if defined(__UCLIBC__) && defined(HAS_NOMMU)

#define STACK_SIZE 4096

    if (child_stack == NULL)

      child_stack = xmalloc (STACK_SIZE * 4);

    /* Use CLONE_VM instead of fork, to support uClinux (no MMU).  */

#ifdef __ia64__

      child_pid = __clone2 (function, child_stack, STACK_SIZE,

             CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);

#else /* !__ia64__ */

      child_pid = clone (function, child_stack + STACK_SIZE,

          CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);

#endif /* !__ia64__ */

#else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */

  child_pid = fork ();

  if (child_pid == 0)

    function (NULL);

#endif /* defined(__UCLIBC) && defined(HAS_NOMMU) */

  if (child_pid == -1)

    perror_with_name (("fork"));

  return child_pid;

}

/* A helper function for linux_check_ptrace_features, called after

   the child forks a grandchild.  */

static void

linux_grandchild_function (gdb_byte *child_stack)

{

  /* Free any allocated stack.  */

  xfree (child_stack);

  /* This code is only reacheable by the grandchild (child's child)

     process.  */

  _exit (0);

}

/* A helper function for linux_check_ptrace_features, called after

   the parent process forks a child.  The child allows itself to

   be traced by its parent.  */

static void

linux_child_function (gdb_byte *child_stack)

{

  ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);

  kill (getpid (), SIGSTOP);

  /* Fork a grandchild.  */

  linux_fork_to_function (child_stack, linux_grandchild_function);

  /* This code is only reacheable by the child (grandchild's parent)

     process.  */

  _exit (0);

}

static void linux_test_for_tracesysgood (int child_pid);

static void linux_test_for_tracefork (int child_pid);

/* Determine ptrace features available on this target.  */

static void

linux_check_ptrace_features (void)

{

  int child_pid, ret, status;

  /* Initialize the options.  */

  current_ptrace_options = 0;

  /* Fork a child so we can do some testing.  The child will call

     linux_child_function and will get traced.  The child will

     eventually fork a grandchild so we can test fork event

     reporting.  */

  child_pid = linux_fork_to_function (NULL, linux_child_function);

  ret = my_waitpid (child_pid, &status, 0);

  if (ret == -1)

    perror_with_name (("waitpid"));

  else if (ret != child_pid)

    error (_("linux_check_ptrace_features: waitpid: unexpected result %d."),

      ret);

  if (! WIFSTOPPED (status))

    error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),

      status);

  linux_test_for_tracesysgood (child_pid);

  linux_test_for_tracefork (child_pid);

  /* Clean things up and kill any pending children.  */

  do

    {

      ret = ptrace (PTRACE_KILL, child_pid, (PTRACE_TYPE_ARG3) 0,

          (PTRACE_TYPE_ARG4) 0);

      if (ret != 0)

   warning (_("linux_check_ptrace_features: failed to kill child"));

      my_waitpid (child_pid, &status, 0);

    }

  while (WIFSTOPPED (status));

}

/* Determine if PTRACE_O_TRACESYSGOOD can be used to catch

   syscalls.  */

static void

linux_test_for_tracesysgood (int child_pid)

{

#ifdef GDBSERVER

  /* gdbserver does not support PTRACE_O_TRACESYSGOOD.  */

#else

  int ret;

  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) PTRACE_O_TRACESYSGOOD);

  if (ret == 0)

    current_ptrace_options |= PTRACE_O_TRACESYSGOOD;

#endif

}

/* Determine if PTRACE_O_TRACEFORK can be used to follow fork

   events.  */

static void

linux_test_for_tracefork (int child_pid)

{

  int ret, status;

  long second_pid;

  /* First, set the PTRACE_O_TRACEFORK option.  If this fails, we

     know for sure that it is not supported.  */

  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) PTRACE_O_TRACEFORK);

  if (ret != 0)

    return;

#ifdef GDBSERVER

  /* gdbserver does not support PTRACE_O_TRACEVFORKDONE yet.  */

#else

  /* Check if the target supports PTRACE_O_TRACEVFORKDONE.  */

  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) (PTRACE_O_TRACEFORK

                | PTRACE_O_TRACEVFORKDONE));

  if (ret == 0)

    current_ptrace_options |= PTRACE_O_TRACEVFORKDONE;

#endif

  /* Setting PTRACE_O_TRACEFORK did not cause an error, however we

     don't know for sure that the feature is available; old

     versions of PTRACE_SETOPTIONS ignored unknown options.

     Therefore, we attach to the child process, use PTRACE_SETOPTIONS

     to enable fork tracing, and let it fork.  If the process exits,

     we assume that we can't use PTRACE_O_TRACEFORK; if we get the

     fork notification, and we can extract the new child's PID, then

     we assume that we can.

     We do not explicitly check for vfork tracing here.  It is

     assumed that vfork tracing is available whenever fork tracing

     is available.  */

  ret = ptrace (PTRACE_CONT, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) 0);

  if (ret != 0)

    warning (_("linux_test_for_tracefork: failed to resume child"));

  ret = my_waitpid (child_pid, &status, 0);

  /* Check if we received a fork event notification.  */

  if (ret == child_pid && WIFSTOPPED (status)

      && status >> 16 == PTRACE_EVENT_FORK)

    {

      /* We did receive a fork event notification.  Make sure its PID

    is reported.  */

      second_pid = 0;

      ret = ptrace (PTRACE_GETEVENTMSG, child_pid, (PTRACE_TYPE_ARG3) 0,

          (PTRACE_TYPE_ARG4) &second_pid);

      if (ret == 0 && second_pid != 0)

   {

     int second_status;

     /* We got the PID from the grandchild, which means fork

        tracing is supported.  */

#ifdef GDBSERVER

     /* Do not enable all the options for now since gdbserver does not

        properly support them.  This restriction will be lifted when

        gdbserver is augmented to support them.  */

     current_ptrace_options |= PTRACE_O_TRACECLONE;

#else

     current_ptrace_options |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK

       | PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXEC;

     /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to

        support read-only process state.  */

#endif

     /* Do some cleanup and kill the grandchild.  */

     my_waitpid (second_pid, &second_status, 0);

     ret = ptrace (PTRACE_KILL, second_pid, (PTRACE_TYPE_ARG3) 0,

         (PTRACE_TYPE_ARG4) 0);

     if (ret != 0)

       warning (_("linux_test_for_tracefork: "

             "failed to kill second child"));

     my_waitpid (second_pid, &status, 0);

   }

    }

  else

    warning (_("linux_test_for_tracefork: unexpected result from waitpid "

        "(%d, status 0x%x)"), ret, status);

}

/* Enable reporting of all currently supported ptrace events.  */

void

linux_enable_event_reporting (pid_t pid)

{

  /* Check if we have initialized the ptrace features for this

     target.  If not, do it now.  */

  if (current_ptrace_options == -1)

    linux_check_ptrace_features ();

  /* Set the options.  */

  ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0,

     (PTRACE_TYPE_ARG4) (uintptr_t) current_ptrace_options);

}

/* Disable reporting of all currently supported ptrace events.  */

void

linux_disable_event_reporting (pid_t pid)

{

  /* Set the options.  */

  ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, 0);

}

/* Returns non-zero if PTRACE_OPTIONS is contained within

   CURRENT_PTRACE_OPTIONS, therefore supported.  Returns 0

   otherwise.  */

static int

ptrace_supports_feature (int ptrace_options)

{

  gdb_assert (current_ptrace_options >= 0);

  return ((current_ptrace_options & ptrace_options) == ptrace_options);

}

/* Returns non-zero if PTRACE_EVENT_FORK is supported by ptrace,

   0 otherwise.  Note that if PTRACE_EVENT_FORK is supported so is

   PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,

   since they were all added to the kernel at the same time.  */

int

linux_supports_tracefork (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACEFORK);

}

/* Returns non-zero if PTRACE_EVENT_CLONE is supported by ptrace,

   0 otherwise.  Note that if PTRACE_EVENT_CLONE is supported so is

   PTRACE_EVENT_FORK, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,

   since they were all added to the kernel at the same time.  */

int

linux_supports_traceclone (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACECLONE);

}

/* Returns non-zero if PTRACE_O_TRACEVFORKDONE is supported by

   ptrace, 0 otherwise.  */

int

linux_supports_tracevforkdone (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACEVFORKDONE);

}

/* Returns non-zero if PTRACE_O_TRACESYSGOOD is supported by ptrace,

   0 otherwise.  */

int

linux_supports_tracesysgood (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACESYSGOOD);

}

/* Display possible problems on this system.  Display them only once per GDB

   execution.  */

void

linux_ptrace_init_warnings (void)

{

  static int warned = 0;

  if (warned)

    return;

  warned = 1;

  linux_ptrace_test_ret_to_nx ();

}

```

And you can surely read a little more of my trouble because of this work agains grsecurity/PaX in another post of mine (didn't post this there, because there are too many subtopics there already):

Postfix smtp/TLS, Bkp/Cloning Mthd, Censorship/Intrusion

https://forums.gentoo.org/viewtopic-t-999436.html#7694556

No further comments at this time.

----------

## Hu

Do you have a question?  From your post, I cannot see anything you want readers to answer.  If you are trying to make an announcement, please be clearer.  It looks to me like gdb checks for PaX because the gdb developers believe that a PaX kernel imposes restrictions that break gdb's ability to call functions in the inferior.  I disagree with the quoted assessment from PaX Team.  As I read the code, gdb specifically checks for both PaX-style and mainline-style NX enforcement.

----------

## miroR

 *Hu wrote:*   

> ...From your post, I cannot see anything you want readers to answer... 

 

I posted the answer some grsecurity hardened Gentoo users can certainly find, now, in a fraction of time that it took me, from thos post of mine that readers are hopefully reading (unless... something comes in the way).

 *Quote:*   

> If you are trying to make an announcement, please be clearer.  It looks to me like gdb checks for PaX because the gdb developers believe that a PaX kernel imposes restrictions that break gdb's ability to call functions in the inferior.

 

If you are as far in the know as PaX Team is, whom I cited, and whose judgement I, and a host of users, trust, then you're posing this argument, if to me, to the wrong person. I'm not that advanced as I openly and clearly stated.

 *Quote:*   

> I disagree with the quoted assessment from PaX Team.  As I read the code, gdb specifically checks for both PaX-style and mainline-style NX enforcement.

 

In case no one replies to you here in that regard, you would be better off to put that to those who have been, as it appears to me, struck in their work, namely the grsecurity/PaX developers, not me. as I said. (But the grsecurity hardening team in Gentoo I don't think they can enjoy this new change, and I'm a little sad that nobody from among the advanced users and true contributors has replied anything yet... And it would be great to know if devs are in the know about this. This, to me, looks like a recent withdrawal of support for PaX... To me, OK?)

I had been having trouble for maybe ten (10) days, as I believed that a subterfuge like this, which this looks to me to be, subterfuge against such fine work as grsecurity/PaX and RBAC hardening of my poor user's kernel...

It was 10 days of really hard pondering over what was causing the troubles described in the link repeatedly, for your request, given below... Poring over this issue, in near complete unclarity about what it was...

I had been having trouble for maybe ten (10) days, maybe even more, and was getting nowhere because I couldn't solve what was it which breaking my system...

And lo and behold, it was that GNU debugger that caused the breakage, because it withdrew support from the kind of hardeneing that PaX does, that is, surely, my understanding of it, and it is documented in the link under the name PaX Team on top of the short quote, which, for purposes of clarity, which you ask of me, I'll now post again in clearer view:

PAX terminating task on /usr/bin/gdb 

http://forums.grsecurity.net/viewtopic.php?f=3&t=4137&#p14962

And also, to post the purpose more clearly for my post, as you suggest to me to do, I state again, users of grsecurity, study this case, and see if things have improved in the future, or if gnu debugger refuses to work with PaX and causes crashes, breakages and malfunction.

This clarity surely applies for people hardening their kernels with grsecurity, and we certainly are numerous, I believe.

Thank you!

----------

## Hu

Now that grsecurity is back online, I can see the full thread, including all your log messages.  I see that PaX team's post is not taken out of context, but their statement is perhaps a bit misleading.  The test that gdb runs necessarily causes the child process to crash.  The way in which it crashes tells gdb which of several execution prevention measures are active.  I see nothing in the source that records the result for long term use, so I do not see the point of this other than to print a message that the user may not notice or understand.  The only reason you see this implementation detail is that the grsecurity kernels are very aggressive about logging programs which die in suspicious ways and the test is a suspicious death.  The reason this becomes a real problem for you is that grsecurity then goes over the top and starts disrupting gdb's attempts to fork other children because one of its children died a suspicious death.  The death was deliberate, but PaX cannot recognize that.  Based on this, I would characterize the problem report as below:

 *Quote:*   

> GDB attempt to detect PaX mprotect generates spurious kernel warnings about process crashes and provokes kernel to delay forks by GDB.
> 
> Workaround: disable brute force prevention, or patch gdb not to run this check.

 

Aside from the scary messages in the logs, does this affect you in some way?

----------

## miroR

 *Hu wrote:*   

> Now that grsecurity is back online, I can see the full thread, including all your log messages.  I see that PaX team's post is not taken out of context, but their statement is perhaps a bit misleading.  The test that gdb runs necessarily causes the child process to crash.  The way in which it crashes tells gdb which of several execution prevention measures are active.  I see nothing in the source that records the result for long term use, so I do not see the point of this other than to print a message that the user may not notice or understand.  The only reason you see this implementation detail is that the grsecurity kernels are very aggressive about logging programs which die in suspicious ways and the test is a suspicious death.  The reason this becomes a real problem for you is that grsecurity then goes over the top and starts disrupting gdb's attempts to fork other children because one of its children died a suspicious death.  The death was deliberate, but PaX cannot recognize that.  Based on this, I would characterize the problem report as below:
> 
>  *Quote:*   GDB attempt to detect PaX mprotect generates spurious kernel warnings about process crashes and provokes kernel to delay forks by GDB.
> 
> Workaround: disable brute force prevention, or patch gdb not to run this check. 
> ...

 

Thanks, Hu, for the explanation. In effect, I am aware of the option to

disable brute force prevention (but how could I have known they were spurious

level only?), and also, it was only scary messages really: you can see in the

Grsecurity Forums topic that I linked that the messages were sent just the

same.

I cannot however check on this now without subtracting from my other efforts

(I work so slowly, and get lost if the burden is too much on me; a late time

in life adopter, near 60)...

The most important thing, and I believe my heroes in the FOSS *nix, spender

and PaX Team, will take the spurious scare into account in the future releases

of their program, so the other poor users will not be scared like I was...

The most important thing is that, as I hope you correctly state (but

don't know, not untill I find time and learn C; not soon, if ever), [that] my

dearest project in FOSS, the grsecurity/PaX, is not in jeopardy as the scares

led me to believe...

If you think it's really important, I can think about trying and finding time

to recreate the conditions as previously, to see more about this issue, but

I'm not so sure it would be easy... Can't really promise...

----------

## steveL

I'd report a bug, since that test is always going to fail on hardened, for certain, and elsewhere depending on the CPU/NX; and its only purpose is for startup warnings.

If it's hardened, better just warn unconditionally, and not trigger the protection (and the logging) which means gdb won't work.

----------

## miroR

 *steveL wrote:*   

> I'd report a bug, since that test is always going to fail on hardened, for certain, and elsewhere depending on the CPU/NX; and its only purpose is for startup warnings.
> 
> If it's hardened, better just warn unconditionally, and not trigger the protection (and the logging) which means gdb won't work.

 

Aaah, I thought I'd be able to go past this scot free...

But when you advise, I feel obliged to you, Elder[*] Gentoo user, whom I learned a few things from..

.

The kernel is new, with yesterday's blueness pathes, as the system is updated early in the day (early yesterday, and the patches are from day before, Saturday, as another Monday has just started in Central Europe...

I'll try. I still can't promise, but I'll try hard to post the bug.

[*] technically elder than me, just as, say, spender, not much more than a kid, maximum late 20s now, is Metusaleh for me... a Patriarch in my eyes..

----------

## PaX Team

 *Hu wrote:*   

> I see that PaX team's post is not taken out of context, but their statement is perhaps a bit misleading.  The test that gdb runs necessarily causes the child process to crash.  The way in which it crashes tells gdb which of several execution prevention measures are active.

 

actually it doesn't tell that  :Wink: . PaX features (MPROTECT in this case) are set on a per-executable (and therefore per-process) basis. gdb tests itself, not the target, whereas the actual gdb features that require runtime codegen would act on the target, if i'm not mistaken. also learning what PaX features are active on a target doesn't require triggering them, a simple look at /proc/pid/status:PaX tells the whole story. so i stand by my claim, what this test does is simply wrong (and i note that we were never consulted on this by anyone on the gdb side).

----------

## steveL

Good to have definitive info. File it with Gentoo anyhow, miro, as it works better like that. Upstreams tend to take it more seriously if it comes from a distro, and on the other side, Gentoo wrangler and hardened bods can make a more focussed report.

Zorry is cool, as is blueness, so shouldn't be any issue.

Give us the bug URL when you've filed it, please, so PaX can keep an eye (and provide correct info, if someone messes up along the chain.)

PaX: any chance we can see example output from /proc/self/status:PaX in shell? (Not running hardened here.)

----------

## miroR

I'll be filing the bug next.

It took me a while because I have the updated system (that is actually better for filing the bug).

It took me a while to figure things, also because the file has now changed. And changed even the location in the source...

I understood that could have been the case after preparing to post the bug.

I do not need to recreate the conditions from three weeks ago, as I thought I needed for a whilt.

No need! The same bug is still there in gdb-7.9!

And these conditions still do apply for other users, the same, whether they update or not (for a while I thought not, but that was due to my RBAC that was enabled; to get the bug as before, I disabled the RBAC), and I'm sure devs and advanced readers with knowledge of C will find so by reading the new file.

Here's where it is now:

```

mybox ~ # ls -l `find ./gdb-7*/ -name 'linux-ptrace.c'`

-rw-rw-rw- 1 ukra 200 16153 2015-01-15 11:58 ./gdb-7.8.2/gdb/common/linux-ptrace.c

-rw-rw-rw- 1 ukra 200 17904 2015-02-20 18:11 ./gdb-7.9/gdb/nat/linux-ptrace.c

mybox ~ # diff  `find ./gdb-7*/ -name 'linux-ptrace.c'` > linux-ptrace.c.diff

mybox ~ # ls -l linux-ptrace.c.diff

-rw-r--r-- 1 root root 5254 2015-02-23 07:21 linux-ptrace.c.diff

mybox ~ # 

```

Heavily rewritten.

So the file in question is now in different place and changed. Here it is:

```

/* Linux-specific ptrace manipulation routines.

   Copyright (C) 2012-2015 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify

   it under the terms of the GNU General Public License as published by

   the Free Software Foundation; either version 3 of the License, or

   (at your option) any later version.

   This program is distributed in the hope that it will be useful,

   but WITHOUT ANY WARRANTY; without even the implied warranty of

   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License

   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "common-defs.h"

#include "linux-ptrace.h"

#include "linux-procfs.h"

#include "linux-waitpid.h"

#include "buffer.h"

#include "gdb_wait.h"

#include <stdint.h>

/* Stores the currently supported ptrace options.  A value of

   -1 means we did not check for features yet.  A value of 0 means

   there are no supported features.  */

static int current_ptrace_options = -1;

/* Additional flags to test.  */

static int additional_flags;

/* Find all possible reasons we could fail to attach PID and append

   these as strings to the already initialized BUFFER.  '\0'

   termination of BUFFER must be done by the caller.  */

void

linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer)

{

  pid_t tracerpid;

  tracerpid = linux_proc_get_tracerpid_nowarn (pid);

  if (tracerpid > 0)

    buffer_xml_printf (buffer, _("process %d is already traced "

             "by process %d"),

             (int) pid, (int) tracerpid);

  if (linux_proc_pid_is_zombie_nowarn (pid))

    buffer_xml_printf (buffer, _("process %d is a zombie "

             "- the process has already terminated"),

             (int) pid);

}

/* See linux-ptrace.h.  */

char *

linux_ptrace_attach_fail_reason_string (ptid_t ptid, int err)

{

  static char *reason_string;

  struct buffer buffer;

  char *warnings;

  long lwpid = ptid_get_lwp (ptid);

  xfree (reason_string);

  buffer_init (&buffer);

  linux_ptrace_attach_fail_reason (lwpid, &buffer);

  buffer_grow_str0 (&buffer, "");

  warnings = buffer_finish (&buffer);

  if (warnings[0] != '\0')

    reason_string = xstrprintf ("%s (%d), %s",

            strerror (err), err, warnings);

  else

    reason_string = xstrprintf ("%s (%d)",

            strerror (err), err);

  xfree (warnings);

  return reason_string;

}

#if defined __i386__ || defined __x86_64__

/* Address of the 'ret' instruction in asm code block below.  */

extern void (linux_ptrace_test_ret_to_nx_instr) (void);

#include <sys/reg.h>

#include <sys/mman.h>

#include <signal.h>

#endif /* defined __i386__ || defined __x86_64__ */

/* Test broken off-trunk Linux kernel patchset for NX support on i386.  It was

   removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd.

   Test also x86_64 arch for PaX support.  */

static void

linux_ptrace_test_ret_to_nx (void)

{

#if defined __i386__ || defined __x86_64__

  pid_t child, got_pid;

  gdb_byte *return_address, *pc;

  long l;

  int status, kill_status;

  return_address = mmap (NULL, 2, PROT_READ | PROT_WRITE,

          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

  if (return_address == MAP_FAILED)

    {

      warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),

          strerror (errno));

      return;

    }

  /* Put there 'int3'.  */

  *return_address = 0xcc;

  child = fork ();

  switch (child)

    {

    case -1:

      warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),

          strerror (errno));

      return;

    case 0:

      l = ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) NULL,

        (PTRACE_TYPE_ARG4) NULL);

      if (l != 0)

   warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),

       strerror (errno));

      else

   {

#if defined __i386__

     asm volatile ("pushl %0;"

         ".globl linux_ptrace_test_ret_to_nx_instr;"

         "linux_ptrace_test_ret_to_nx_instr:"

         "ret"

         : : "r" (return_address) : "%esp", "memory");

#elif defined __x86_64__

     asm volatile ("pushq %0;"

         ".globl linux_ptrace_test_ret_to_nx_instr;"

         "linux_ptrace_test_ret_to_nx_instr:"

         "ret"

         : : "r" ((uint64_t) (uintptr_t) return_address)

         : "%rsp", "memory");

#else

# error "!__i386__ && !__x86_64__"

#endif

     gdb_assert_not_reached ("asm block did not terminate");

   }

      _exit (1);

    }

  errno = 0;

  got_pid = waitpid (child, &status, 0);

  if (got_pid != child)

    {

      warning (_("linux_ptrace_test_ret_to_nx: waitpid returned %ld: %s"),

          (long) got_pid, strerror (errno));

      return;

    }

  if (WIFSIGNALED (status))

    {

      if (WTERMSIG (status) != SIGKILL)

   warning (_("linux_ptrace_test_ret_to_nx: WTERMSIG %d is not SIGKILL!"),

       (int) WTERMSIG (status));

      else

   warning (_("Cannot call inferior functions, Linux kernel PaX "

         "protection forbids return to non-executable pages!"));

      return;

    }

  if (!WIFSTOPPED (status))

    {

      warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),

          status);

      return;

    }

  /* We may get SIGSEGV due to missing PROT_EXEC of the return_address.  */

  if (WSTOPSIG (status) != SIGTRAP && WSTOPSIG (status) != SIGSEGV)

    {

      warning (_("linux_ptrace_test_ret_to_nx: "

       "WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),

          (int) WSTOPSIG (status));

      return;

    }

  errno = 0;

#if defined __i386__

  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (EIP * 4),

         (PTRACE_TYPE_ARG4) NULL);

#elif defined __x86_64__

  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (RIP * 8),

         (PTRACE_TYPE_ARG4) NULL);

#else

# error "!__i386__ && !__x86_64__"

#endif

  if (errno != 0)

    {

      warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER: %s"),

          strerror (errno));

      return;

    }

  pc = (void *) (uintptr_t) l;

  kill (child, SIGKILL);

  ptrace (PTRACE_KILL, child, (PTRACE_TYPE_ARG3) NULL,

     (PTRACE_TYPE_ARG4) NULL);

  errno = 0;

  got_pid = waitpid (child, &kill_status, 0);

  if (got_pid != child)

    {

      warning (_("linux_ptrace_test_ret_to_nx: "

       "PTRACE_KILL waitpid returned %ld: %s"),

          (long) got_pid, strerror (errno));

      return;

    }

  if (!WIFSIGNALED (kill_status))

    {

      warning (_("linux_ptrace_test_ret_to_nx: "

       "PTRACE_KILL status %d is not WIFSIGNALED!"),

          status);

      return;

    }

  /* + 1 is there as x86* stops after the 'int3' instruction.  */

  if (WSTOPSIG (status) == SIGTRAP && pc == return_address + 1)

    {

      /* PASS */

      return;

    }

  /* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page.  */

  if (WSTOPSIG (status) == SIGSEGV && pc == return_address)

    {

      /* PASS */

      return;

    }

  if ((void (*) (void)) pc != &linux_ptrace_test_ret_to_nx_instr)

    warning (_("linux_ptrace_test_ret_to_nx: PC %p is neither near return "

          "address %p nor is the return instruction %p!"),

        pc, return_address, &linux_ptrace_test_ret_to_nx_instr);

  else

    warning (_("Cannot call inferior functions on this system - "

          "Linux kernel with broken i386 NX (non-executable pages) "

          "support detected!"));

#endif /* defined __i386__ || defined __x86_64__ */

}

/* Helper function to fork a process and make the child process call

   the function FUNCTION, passing CHILD_STACK as parameter.

   For MMU-less targets, clone is used instead of fork, and

   CHILD_STACK is used as stack space for the cloned child.  If NULL,

   stack space is allocated via malloc (and subsequently passed to

   FUNCTION).  For MMU targets, CHILD_STACK is ignored.  */

static int

linux_fork_to_function (gdb_byte *child_stack, void (*function) (gdb_byte *))

{

  int child_pid;

  /* Sanity check the function pointer.  */

  gdb_assert (function != NULL);

#if defined(__UCLIBC__) && defined(HAS_NOMMU)

#define STACK_SIZE 4096

    if (child_stack == NULL)

      child_stack = xmalloc (STACK_SIZE * 4);

    /* Use CLONE_VM instead of fork, to support uClinux (no MMU).  */

#ifdef __ia64__

      child_pid = __clone2 (function, child_stack, STACK_SIZE,

             CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);

#else /* !__ia64__ */

      child_pid = clone (function, child_stack + STACK_SIZE,

          CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);

#endif /* !__ia64__ */

#else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */

  child_pid = fork ();

  if (child_pid == 0)

    function (NULL);

#endif /* defined(__UCLIBC) && defined(HAS_NOMMU) */

  if (child_pid == -1)

    perror_with_name (("fork"));

  return child_pid;

}

/* A helper function for linux_check_ptrace_features, called after

   the child forks a grandchild.  */

static void

linux_grandchild_function (gdb_byte *child_stack)

{

  /* Free any allocated stack.  */

  xfree (child_stack);

  /* This code is only reacheable by the grandchild (child's child)

     process.  */

  _exit (0);

}

/* A helper function for linux_check_ptrace_features, called after

   the parent process forks a child.  The child allows itself to

   be traced by its parent.  */

static void

linux_child_function (gdb_byte *child_stack)

{

  ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);

  kill (getpid (), SIGSTOP);

  /* Fork a grandchild.  */

  linux_fork_to_function (child_stack, linux_grandchild_function);

  /* This code is only reacheable by the child (grandchild's parent)

     process.  */

  _exit (0);

}

static void linux_test_for_tracesysgood (int child_pid);

static void linux_test_for_tracefork (int child_pid);

static void linux_test_for_exitkill (int child_pid);

/* Determine ptrace features available on this target.  */

static void

linux_check_ptrace_features (void)

{

  int child_pid, ret, status;

  /* Initialize the options.  */

  current_ptrace_options = 0;

  /* Fork a child so we can do some testing.  The child will call

     linux_child_function and will get traced.  The child will

     eventually fork a grandchild so we can test fork event

     reporting.  */

  child_pid = linux_fork_to_function (NULL, linux_child_function);

  ret = my_waitpid (child_pid, &status, 0);

  if (ret == -1)

    perror_with_name (("waitpid"));

  else if (ret != child_pid)

    error (_("linux_check_ptrace_features: waitpid: unexpected result %d."),

      ret);

  if (! WIFSTOPPED (status))

    error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),

      status);

  linux_test_for_tracesysgood (child_pid);

  linux_test_for_tracefork (child_pid);

  linux_test_for_exitkill (child_pid);

  /* Clean things up and kill any pending children.  */

  do

    {

      ret = ptrace (PTRACE_KILL, child_pid, (PTRACE_TYPE_ARG3) 0,

          (PTRACE_TYPE_ARG4) 0);

      if (ret != 0)

   warning (_("linux_check_ptrace_features: failed to kill child"));

      my_waitpid (child_pid, &status, 0);

    }

  while (WIFSTOPPED (status));

}

/* Determine if PTRACE_O_TRACESYSGOOD can be used to catch

   syscalls.  */

static void

linux_test_for_tracesysgood (int child_pid)

{

  int ret;

  if ((additional_flags & PTRACE_O_TRACESYSGOOD) == 0)

    return;

  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) PTRACE_O_TRACESYSGOOD);

  if (ret == 0)

    current_ptrace_options |= PTRACE_O_TRACESYSGOOD;

}

/* Determine if PTRACE_O_TRACEFORK can be used to follow fork

   events.  */

static void

linux_test_for_tracefork (int child_pid)

{

  int ret, status;

  long second_pid;

  /* First, set the PTRACE_O_TRACEFORK option.  If this fails, we

     know for sure that it is not supported.  */

  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) PTRACE_O_TRACEFORK);

  if (ret != 0)

    return;

  if ((additional_flags & PTRACE_O_TRACEVFORKDONE) != 0)

    {

      /* Check if the target supports PTRACE_O_TRACEVFORKDONE.  */

      ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,

          (PTRACE_TYPE_ARG4) (PTRACE_O_TRACEFORK

               | PTRACE_O_TRACEVFORKDONE));

      if (ret == 0)

   current_ptrace_options |= PTRACE_O_TRACEVFORKDONE;

    }

  /* Setting PTRACE_O_TRACEFORK did not cause an error, however we

     don't know for sure that the feature is available; old

     versions of PTRACE_SETOPTIONS ignored unknown options.

     Therefore, we attach to the child process, use PTRACE_SETOPTIONS

     to enable fork tracing, and let it fork.  If the process exits,

     we assume that we can't use PTRACE_O_TRACEFORK; if we get the

     fork notification, and we can extract the new child's PID, then

     we assume that we can.

     We do not explicitly check for vfork tracing here.  It is

     assumed that vfork tracing is available whenever fork tracing

     is available.  */

  ret = ptrace (PTRACE_CONT, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) 0);

  if (ret != 0)

    warning (_("linux_test_for_tracefork: failed to resume child"));

  ret = my_waitpid (child_pid, &status, 0);

  /* Check if we received a fork event notification.  */

  if (ret == child_pid && WIFSTOPPED (status)

      && linux_ptrace_get_extended_event (status) == PTRACE_EVENT_FORK)

    {

      /* We did receive a fork event notification.  Make sure its PID

    is reported.  */

      second_pid = 0;

      ret = ptrace (PTRACE_GETEVENTMSG, child_pid, (PTRACE_TYPE_ARG3) 0,

          (PTRACE_TYPE_ARG4) &second_pid);

      if (ret == 0 && second_pid != 0)

   {

     int second_status;

     /* We got the PID from the grandchild, which means fork

        tracing is supported.  */

     current_ptrace_options |= PTRACE_O_TRACECLONE;

     current_ptrace_options |= (additional_flags & (PTRACE_O_TRACEFORK

                                                         | PTRACE_O_TRACEVFORK

                                                         | PTRACE_O_TRACEEXEC));

     /* Do some cleanup and kill the grandchild.  */

     my_waitpid (second_pid, &second_status, 0);

     ret = ptrace (PTRACE_KILL, second_pid, (PTRACE_TYPE_ARG3) 0,

         (PTRACE_TYPE_ARG4) 0);

     if (ret != 0)

       warning (_("linux_test_for_tracefork: "

             "failed to kill second child"));

     my_waitpid (second_pid, &status, 0);

   }

    }

  else

    warning (_("linux_test_for_tracefork: unexpected result from waitpid "

        "(%d, status 0x%x)"), ret, status);

}

/* Determine if PTRACE_O_EXITKILL can be used.  */

static void

linux_test_for_exitkill (int child_pid)

{

  int ret;

  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,

      (PTRACE_TYPE_ARG4) PTRACE_O_EXITKILL);

  if (ret == 0)

    current_ptrace_options |= PTRACE_O_EXITKILL;

}

/* Enable reporting of all currently supported ptrace events.

   ATTACHED should be nonzero if we have attached to the inferior.  */

void

linux_enable_event_reporting (pid_t pid, int attached)

{

  int ptrace_options;

  /* Check if we have initialized the ptrace features for this

     target.  If not, do it now.  */

  if (current_ptrace_options == -1)

    linux_check_ptrace_features ();

  ptrace_options = current_ptrace_options;

  if (attached)

    {

      /* When attached to our inferior, we do not want the inferior

    to die with us if we terminate unexpectedly.  */

      ptrace_options &= ~PTRACE_O_EXITKILL;

    }

  /* Set the options.  */

  ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0,

     (PTRACE_TYPE_ARG4) (uintptr_t) ptrace_options);

}

/* Disable reporting of all currently supported ptrace events.  */

void

linux_disable_event_reporting (pid_t pid)

{

  /* Set the options.  */

  ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, 0);

}

/* Returns non-zero if PTRACE_OPTIONS is contained within

   CURRENT_PTRACE_OPTIONS, therefore supported.  Returns 0

   otherwise.  */

static int

ptrace_supports_feature (int ptrace_options)

{

  if (current_ptrace_options == -1)

    linux_check_ptrace_features ();

  return ((current_ptrace_options & ptrace_options) == ptrace_options);

}

/* Returns non-zero if PTRACE_EVENT_FORK is supported by ptrace,

   0 otherwise.  Note that if PTRACE_EVENT_FORK is supported so is

   PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,

   since they were all added to the kernel at the same time.  */

int

linux_supports_tracefork (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACEFORK);

}

/* Returns non-zero if PTRACE_EVENT_CLONE is supported by ptrace,

   0 otherwise.  Note that if PTRACE_EVENT_CLONE is supported so is

   PTRACE_EVENT_FORK, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,

   since they were all added to the kernel at the same time.  */

int

linux_supports_traceclone (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACECLONE);

}

/* Returns non-zero if PTRACE_O_TRACEVFORKDONE is supported by

   ptrace, 0 otherwise.  */

int

linux_supports_tracevforkdone (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACEVFORKDONE);

}

/* Returns non-zero if PTRACE_O_TRACESYSGOOD is supported by ptrace,

   0 otherwise.  */

int

linux_supports_tracesysgood (void)

{

  return ptrace_supports_feature (PTRACE_O_TRACESYSGOOD);

}

/* Display possible problems on this system.  Display them only once per GDB

   execution.  */

void

linux_ptrace_init_warnings (void)

{

  static int warned = 0;

  if (warned)

    return;

  warned = 1;

  linux_ptrace_test_ret_to_nx ();

}

/* Set additional ptrace flags to use.  Some such flags may be checked

   by the implementation above.  This function must be called before

   any other function in this file; otherwise the flags may not take

   effect appropriately.  */

void

linux_ptrace_set_additional_flags (int flags)

{

  additional_flags = flags;

}

/* Extract extended ptrace event from wait status.  */

int

linux_ptrace_get_extended_event (int wstat)

{

  return (wstat >> 16);

}

/* Determine whether wait status denotes an extended event.  */

int

linux_is_extended_waitstatus (int wstat)

{

  return (linux_ptrace_get_extended_event (wstat) != 0);

}

```

Working on the bug report.

And here is for the impatient, how it goes now, from my /var/log/messages:

This is one single consecutive, complete, exceprt from my /var/log/messages, but I split it in three as there are three stages:

1st stage) with not properly configured RBAC policy for postfix in my /etc/grsec/policy (which issue which doesn't belong in this topic):

```

Feb 23 08:36:15 mybox kernel: [30033.404012] grsec: (root:U:/usr/libexec/postfix/qmgr) exec of /usr/libexec/postfix/qmgr (qmgr -l -t unix -u ) by /usr/libexec/postfix/qmgr[master:14362] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/master[master:3561] uid/euid:0/0 gid/egid:0/0

Feb 23 08:36:15 mybox kernel: [30033.404109] grsec: (root:U:/usr/libexec/postfix/qmgr) denied access to hidden file /lib64/ld-2.20.so by /usr/libexec/postfix/qmgr[master:14362] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/master[master:3561] uid/euid:0/0 gid/egid:0/0

Feb 23 08:36:15 mybox master[14362]: fatal: master_spawn: exec /usr/libexec/postfix/qmgr: No such file or directory

Feb 23 08:36:16 mybox postfix/master[3561]: warning: process /usr/libexec/postfix/qmgr pid 14362 exit status 1

Feb 23 08:36:16 mybox postfix/master[3561]: warning: /usr/libexec/postfix/qmgr: bad command startup -- throttling

Feb 23 08:37:10 mybox kernel: [30088.237962] grsec: (root:U:/bin/ls) exec of /bin/ls (ls --color=auto -ltrh ) by /bin/ls[bash:14366] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2871] uid/euid:0/0 gid/egid:0/0

Feb 23 08:37:16 mybox master[14373]: fatal: master_spawn: exec /usr/libexec/postfix/qmgr: No such file or directory

Feb 23 08:37:16 mybox kernel: [30094.502032] grsec: (root:U:/usr/libexec/postfix/qmgr) denied access to hidden file /lib64/ld-2.20.so by /usr/libexec/postfix/qmgr[master:14373] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/master[master:3561] uid/euid:0/0 gid/egid:0/0

Feb 23 08:37:17 mybox postfix/master[3561]: warning: process /usr/libexec/postfix/qmgr pid 14373 exit status 1

Feb 23 08:37:17 mybox postfix/master[3561]: warning: /usr/libexec/postfix/qmgr: bad command startup -- throttling

```

2nd stage) with grsec RBAC ACLs disabled, as you can see, locally postfix does the work fine:

```

Feb 23 08:37:35 mybox kernel: [30113.317303] grsec: shutdown auth success for /sbin/gradm[gradm:14376] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 08:37:44 mybox postfix/postfix-script[14386]: refreshing the Postfix mail system

Feb 23 08:37:44 mybox postfix/master[3561]: reload -- version 3.0.0, configuration /etc/postfix

Feb 23 08:38:17 mybox postfix/qmgr[14395]: 1B824380D48: from=<root@localdomain>, size=672, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: 366B338195D: from=<root@localdomain>, size=828, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: A28A63836D1: from=<root@localdomain>, size=383, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: 8BBBE38313B: from=<root@localdomain>, size=203664, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: C18CC3836D9: from=<root@localdomain>, size=1260797, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: DFB9A3815CE: from=<root@localdomain>, size=203664, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: 910C3380D3E: from=<root@localdomain>, size=665, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: 9ABE9380D20: from=<root@localdomain>, size=188702, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: C38B838453D: from=<root@localdomain>, size=828, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: 1BD94380DE3: from=<root@localdomain>, size=383, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: CD602383163: from=<root@localdomain>, size=828, nrcpt=1 (queue active)

Feb 23 08:38:17 mybox postfix/qmgr[14395]: B0C643830CD: from=<root@localdomain>, size=383, nrcpt=1 (queue active)

Feb 23 08:38:18 mybox postfix/local[14399]: 1B824380D48: to=<root@localdomain>, relay=local, delay=10968, delays=10968/0.08/0/0.11, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: 1B824380D48: removed

Feb 23 08:38:18 mybox postfix/local[14401]: 366B338195D: to=<root@localdomain>, orig_to=<root>, relay=local, delay=9249, delays=9249/0.06/0/0.18, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: 366B338195D: removed

Feb 23 08:38:18 mybox postfix/local[14399]: A28A63836D1: to=<root@localdomain.localdomain>, relay=local, delay=2065, delays=2064/0.16/0/0.14, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: A28A63836D1: removed

Feb 23 08:38:18 mybox postfix/local[14401]: 8BBBE38313B: to=<root@localdomain>, orig_to=<root>, relay=local, delay=5487, delays=5486/0.24/0/0.18, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: 8BBBE38313B: removed

Feb 23 08:38:18 mybox postfix/local[14399]: C18CC3836D9: to=<root@localdomain>, orig_to=<root>, relay=local, delay=1899, delays=1898/0.3/0/0.17, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: C18CC3836D9: removed

Feb 23 08:38:18 mybox postfix/local[14401]: DFB9A3815CE: to=<root@localdomain>, orig_to=<root>, relay=local, delay=9086, delays=9085/0.42/0/0.16, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: DFB9A3815CE: removed

Feb 23 08:38:18 mybox postfix/local[14399]: 910C3380D3E: to=<root@localdomain>, relay=local, delay=12180, delays=12179/0.47/0/0.16, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: 910C3380D3E: removed

Feb 23 08:38:18 mybox postfix/local[14401]: C38B838453D: to=<root@localdomain>, orig_to=<root>, relay=local, delay=2065, delays=2064/0.63/0/0.11, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/local[14402]: 9ABE9380D20: to=<root@localdomain>, orig_to=<root>, relay=local, delay=19204, delays=19203/0.58/0/0.16, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: C38B838453D: removed

Feb 23 08:38:18 mybox postfix/qmgr[14395]: 9ABE9380D20: removed

Feb 23 08:38:18 mybox postfix/local[14401]: CD602383163: to=<root@localdomain>, orig_to=<root>, relay=local, delay=5651, delays=5650/0.74/0/0.1, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/local[14399]: 1BD94380DE3: to=<root@localdomain.localdomain>, relay=local, delay=9250, delays=9249/0.74/0/0.1, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: CD602383163: removed

Feb 23 08:38:18 mybox postfix/qmgr[14395]: 1BD94380DE3: removed

Feb 23 08:38:18 mybox postfix/local[14402]: B0C643830CD: to=<root@localdomain.localdomain>, relay=local, delay=5651, delays=5650/0.84/0/0.07, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 08:38:18 mybox postfix/qmgr[14395]: B0C643830CD: removed

```

3rd stage) with debugging enabled with the ` -D' suffixes added to different lines in postfix's master.cf and the GNU debugger line added to postfix's main.cf

```

Feb 23 08:43:51 mybox postfix/postfix-script[14493]: refreshing the Postfix mail system

Feb 23 08:43:51 mybox postfix/master[3561]: reload -- version 3.0.0, configuration /etc/postfix

Feb 23 08:43:51 mybox postfix/pickup[14499]: running: PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont;?echo where) | gdb /usr/libexec/postfix/pickup 14499 2>&1?>/etc/postfix/pickup.14499.log & sleep 5

Feb 23 08:43:51 mybox postfix/qmgr[14500]: running: PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont;?echo where) | gdb /usr/libexec/postfix/qmgr 14500 2>&1?>/etc/postfix/qmgr.14500.log & sleep 5

Feb 23 08:43:51 mybox kernel: [30489.757708] grsec: process /usr/libexec/postfix/pickup(pickup:14499) attached to via ptrace by /usr/bin/gdb[gdb:14507] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[sh:14501] uid/euid:0/0 gid/egid:0/0

Feb 23 08:43:51 mybox kernel: [30489.760510] grsec: process /usr/libexec/postfix/qmgr(qmgr:14500) attached to via ptrace by /usr/bin/gdb[gdb:14505] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[sh:14502] uid/euid:0/0 gid/egid:0/0

Feb 23 08:43:51 mybox kernel: [30489.762784] PAX: execution attempt in: <anonymous mapping>, 3a0d8adf000-3a0d8ae2000 3a0d8adf000

Feb 23 08:43:51 mybox kernel: [30489.762790] PAX: terminating task: /usr/bin/gdb(gdb):14515, uid/euid: 0/0, PC: 000003a0d8adf000, SP: 000003d728edf0c0

Feb 23 08:43:51 mybox kernel: [30489.762793] PAX: bytes at PC: cc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

Feb 23 08:43:51 mybox kernel: [30489.762808] PAX: bytes at SP-8: 000003a0d8adf000 0000000000000000 db2cd003f1af9d00 000003d728edf140 0000001965c07500 0000001965c07420 0000001968adb180 000000196559fb80 0000000000000000 000003d728edf190 0000001965549cc1 

Feb 23 08:43:51 mybox kernel: [30489.762828] grsec: bruteforce prevention initiated for the next 30 minutes or until service restarted, stalling each fork 30 seconds.  Please investigate the crash report for /usr/bin/gdb[gdb:14515] uid/euid:0/0 gid/egid:0/0, parent /usr/bin/gdb[gdb:14507] uid/euid:0/0 gid/egid:0/0

Feb 23 08:43:51 mybox kernel: [30489.762842] grsec: denied resource overstep by requesting 4096 for RLIMIT_CORE against limit 0 for /usr/bin/gdb[gdb:14515] uid/euid:0/0 gid/egid:0/0, parent /usr/bin/gdb[gdb:14507] uid/euid:0/0 gid/egid:0/0

Feb 23 08:43:51 mybox kernel: [30489.763999] PAX: execution attempt in: <anonymous mapping>, 2fb322e7000-2fb322ea000 2fb322e7000

Feb 23 08:43:51 mybox kernel: [30489.764005] PAX: terminating task: /usr/bin/gdb(gdb):14516, uid/euid: 0/0, PC: 000002fb322e7000, SP: 000003c0181a8e90

Feb 23 08:43:51 mybox kernel: [30489.764009] PAX: bytes at PC: cc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

Feb 23 08:43:51 mybox kernel: [30489.764023] PAX: bytes at SP-8: 000002fb322e7000 0000000000000000 5ce42948a02eed00 000003c0181a8f10 0000001540666500 0000001540666420 000000154467b340 000000153fffeb80 0000000000000000 000003c0181a8f60 000000153ffa8cc1 

Feb 23 08:43:51 mybox kernel: [30489.764042] grsec: bruteforce prevention initiated for the next 30 minutes or until service restarted, stalling each fork 30 seconds.  Please investigate the crash report for /usr/bin/gdb[gdb:14516] uid/euid:0/0 gid/egid:0/0, parent /usr/bin/gdb[gdb:14505] uid/euid:0/0 gid/egid:0/0

Feb 23 08:43:51 mybox kernel: [30489.764056] grsec: denied resource overstep by requesting 4096 for RLIMIT_CORE against limit 0 for /usr/bin/gdb[gdb:14516] uid/euid:0/0 gid/egid:0/0, parent /usr/bin/gdb[gdb:14505] uid/euid:0/0 gid/egid:0/0

```

I'll be back to post the url of the bug report when done.

----------

## miroR

Sadly, my dillo can't even open bugs.gentoo.org.

And it was such a hard time filling the form with Lynx.

Which I did, but some links wouldn't anymore be opened neither by Lynx, and had to kill it.

Upun relogging into bugs.gentoo.org, I wasn't able to find the bug that I just filed.

Hoever, the CGI engine from ganet.gentoo.org reported that is sent quite a few mails with the bug that I just reported.

And, I wasn't able to attach my:

emerge --info

which I prepared beforehand...

So I don't know what to do. I hate Firefox because the Surveillance Engine is sitting in it, and I hate their freaking data harvesting.

I'll try again with Lynx, to post the emerge --info if I find my report there...

If not, I might first post the screencast showing to whom it was sent (but that takes longer). Anyway, the screencast and the accompanying dumpcap are:

94c26ae54aeffc6f8298ab438d570940dd86a3cd4e0b88a049894bb01962c8b6  dump_150223_0952_g0n.pcap

4cb72293941c2af7117d95fd8e1a8c648653fef3f9330217307a8f45cd506fcd  Screen_150223_0952_g0n.mkv

EDIT: I put that info taken by screencasting to good use this time. I was able to recover my submitted bug report id (541104) only from screencast, Lynx/other reasons did't allow it to be found in my searches.

Just in case I need to work on them if something nefarious happened again from somewhere to my connections.

Sorry for this digression.Last edited by miroR on Mon Feb 23, 2015 12:16 pm; edited 3 times in total

----------

## PaX Team

 *steveL wrote:*   

> PaX: any chance we can see example output from /proc/self/status:PaX in shell? (Not running hardened here.)

 

this is with softmode enabled (PaX features disabled at runtime for all processes), disabling PaX features only on the target app (grep in my example) would show the same:

```
grep PaX /proc/self/status

PaX:    pemrs
```

in normal mode:

```
grep PaX /proc/self/status

PaX:    PeMRs

```

the important bit is the 'm' vs. 'M' change, that tells whether MPROTECT was off or on, respectively. so gdb could just check this flag on the target process and disable(and warn perhaps) or enable the features that require runtime codegen in the target. this would be certainly better than spamming system logs and triggering reaction mechanisms.

note that in general i don't think gdb should do anything at all, it's up to distros or direct PaX users to know what they're doing and disable MPROTECT when they need to debug something. this is really not different from making exceptions for java, browsers (javascript JIT engines), apps using mesa, etc.

----------

## miroR

Is is here:

GNU debugger employed via Postfix crashed PaX hardened kernel

https://bugs.gentoo.org/show_bug.cgi?id=541104

However, looking it up in Lynx (and let me repeat that dillo can't open bugs.gentoo.org --I wish I could post a bug on that... don't know)...

However, looking it up in Lynx is very miserable. I did post all the necessary info, but can't really check with Lynx, errors, freezes and inconsistency...

Not going for the Googlofox, regardless of how hard this is.

Pls., somebody tell me if the paste that I posted above is NOT visible there (only 2nd and 3rd stages). (Important only to let me know if it is NOT available there, it's the last of the attachments/pastes that I posted there)

Thank you

----------

## miroR

Nope, the:

The log with the crashes

https://541104.bugs.gentoo.org/attachment.cgi?id=397334

is only now there (and my dillo now works).

 *PaX Team wrote:*   

>  *steveL wrote:*   PaX: any chance we can see example output from /proc/self/status:PaX in shell? (Not running hardened here.) 
> 
> this is with softmode enabled (PaX features disabled at runtime for all processes), disabling PaX features only on the target app (grep in my example) would show the same:
> 
> ```
> ...

 

The sad thing is that too few of you, Gentoo Forum members, care. You really think the NSA's SELinux will protect your privacy, if you lose grsecurity, as these dirty moves by these sabotage-workers obviously aim to do?

If not something even worse is at play from some of you, here, than just lack of care.

Because we have here a blatant, completely warrantless and utterly damaging for the Free Open Source Software, subterfuge, by some of the GNU people envolved with the GNU debugger.

The debugger shouldn't do anything about PaX whatsoever, as PaX Team stated and I quoted again above.

----------

## miroR

I thought I'd post this, as this demonstrates how (I'll recheck it, but) my system, if not distracted by the work of those (not all the teams at the GNU and associates) GNU people of the FOSS sabotage in question in this topic made available for the harm to FOSS in their new versions of the program GNU debugger...

I thought I'd post this, as this demonstrates how my system works fine also with RBAC enabled, as far as all, or at least most (yet to check, esp. after cloning this master Gentoo system of mine onto my online Gentoo box) of the functions of the Postfix programs work just fine.

```

Feb 23 18:53:09 gbn kernel: [67068.263329] grsec: (admin:S:/) exec of /sbin/gradm (gradm -D ) by /sbin/gradm[bash:26411] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:13 gbn kernel: [67072.241926] grsec: shutdown auth success for /sbin/gradm[gradm:26411] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:13 gbn kernel: [67072.242343] grsec: exec of /sbin/grlearn (/sbin/grlearn -stop ) by /sbin/grlearn[gradm:26412] uid/euid:0/0 gid/egid:0/0, parent /sbin/init[init:1] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:19 gbn kernel: [67078.203494] grsec: exec of /sbin/gradm (gradm -C ) by /sbin/gradm[bash:26413] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:19 gbn kernel: [67078.205182] grsec: chdir to /etc/grsec by /sbin/gradm[gradm:26413] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:20 gbn kernel: [67079.773427] grsec: exec of /sbin/gradm (gradm -E ) by /sbin/gradm[bash:26414] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:20 gbn kernel: [67079.775552] grsec: chdir to /etc/grsec by /sbin/gradm[gradm:26414] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:21 gbn kernel: [67079.818137] grsec: (root:U:/sbin/gradm) grsecurity 3.0 RBAC system loaded by /sbin/gradm[gradm:26414] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:25 gbn kernel: [67084.494723] grsec: (root:U:/sbin/gradm) exec of /sbin/gradm (gradm -a admin ) by /sbin/gradm[bash:26415] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:53:30 gbn kernel: [67089.182680] grsec: (root:U:/sbin/gradm) successful change to special role admin (id 8) by /sbin/gradm[gradm:26415] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.738826] grsec: (admin:S:/) exec of /usr/sbin/postfix (postfix reload ) by /usr/sbin/postfix[bash:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.748614] grsec: (admin:S:/) chdir to /usr/sbin by /usr/sbin/postfix[postfix:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.748625] grsec: (admin:S:/) chdir to /usr/libexec/postfix by /usr/sbin/postfix[postfix:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.748633] grsec: (admin:S:/) chdir to /var/spool/postfix by /usr/sbin/postfix[postfix:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.748833] grsec: (admin:S:/) exec of /usr/libexec/postfix/postfix-script (/usr/libexec/postfix/postfix-script reload ) by /usr/libexec/postfix/postfix-script[postfix:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.755921] grsec: (admin:S:/) chdir to /usr/sbin by /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.755959] grsec: (admin:S:/) chdir to /usr/libexec/postfix by /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.756016] grsec: (admin:S:/) chdir to /etc/postfix by /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.756066] grsec: (admin:S:/) chdir to /usr/lib64/postfix/3.0.0 by /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.756097] grsec: (admin:S:/) chdir to /etc/postfix by /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.756131] grsec: (admin:S:/) chdir to /var/spool/postfix by /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2886] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.756996] grsec: (admin:S:/) exec of /usr/sbin/postconf (/usr/sbin/postconf -dh config_directory ) by /usr/sbin/postconf[postfix-script:26419] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.778999] grsec: (admin:S:/) exec of /usr/sbin/postconf (/usr/sbin/postconf -c /etc/postfix -h multi_instance_directories ) by /usr/sbin/postconf[postfix-script:26421] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26420] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.779521] grsec: (admin:S:/) exec of /bin/sed (sed s/,/ / ) by /bin/sed[postfix-script:26422] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26420] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.790448] grsec: (admin:S:/) exec of /usr/libexec/postfix/master (/usr/libexec/postfix/master -t ) by /usr/libexec/postfix/master[postfix-script:26423] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.796273] grsec: (admin:S:/) chdir to /var/spool/postfix by /usr/libexec/postfix/master[master:26423] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.797425] grsec: (admin:S:/) exec of /usr/sbin/postlog (/usr/sbin/postlog -t postfix/postfix-script -p info refreshing the Postfix mail system ) by /usr/sbin/postlog[postfix-script:26424] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn postfix/postfix-script[26424]: refreshing the Postfix mail system

Feb 23 18:55:06 gbn kernel: [67185.803507] grsec: (admin:S:/) exec of /usr/sbin/postsuper (/usr/sbin/postsuper active ) by /usr/sbin/postsuper[postfix-script:26425] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.807668] grsec: (admin:S:/) chdir to /var/spool/postfix by /usr/sbin/postsuper[postsuper:26425] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.809415] grsec: (admin:S:/) exec of /bin/sed (sed 1q pid/master.pid ) by /bin/sed[postfix-script:26426] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn postfix/master[3561]: reload -- version 3.0.0, configuration /etc/postfix

Feb 23 18:55:06 gbn kernel: [67185.812928] grsec: (admin:S:/) exec of /usr/sbin/postsuper (/usr/sbin/postsuper ) by /usr/sbin/postsuper[postfix-script:26427] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/postfix-script[postfix-script:26416] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.817950] grsec: (admin:S:/) chdir to /var/spool/postfix by /usr/sbin/postsuper[postsuper:26427] uid/euid:0/0 gid/egid:0/0, parent /sbin/init[init:1] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.818301] grsec: (root:U:/usr/libexec/postfix/pickup) exec of /usr/libexec/postfix/pickup (pickup -l -t unix -u ) by /usr/libexec/postfix/pickup[master:26428] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/master[master:3561] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.819635] grsec: (root:U:/usr/libexec/postfix/qmgr) exec of /usr/libexec/postfix/qmgr (qmgr -l -t unix -u ) by /usr/libexec/postfix/qmgr[master:26429] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/master[master:3561] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.822726] grsec: (root:U:/usr/libexec/postfix/pickup) chdir to /var/spool/postfix by /usr/libexec/postfix/pickup[pickup:26428] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/master[master:3561] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:06 gbn kernel: [67185.825309] grsec: (root:U:/usr/libexec/postfix/qmgr) chdir to /var/spool/postfix by /usr/libexec/postfix/qmgr[qmgr:26429] uid/euid:0/0 gid/egid:0/0, parent /usr/libexec/postfix/master[master:3561] uid/euid:0/0 gid/egid:0/0

Feb 23 18:55:11 gbn kernel: [67190.141925] grsec: (root:U:/bin/ls) exec of /bin/ls (ls --color=auto -ltrh ) by /bin/ls[bash:26430] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2871] uid/euid:0/0 gid/egid:0/0

Feb 23 18:58:22 gbn kernel: [67381.954862] grsec: (root:U:/usr/bin/eject) denied access to hidden file /boot by /usr/bin/eject[eject:26611] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2838] uid/euid:0/0 gid/egid:0/0

Feb 23 18:58:23 gbn kernel: [67381.960517] grsec: (root:U:/usr/bin/eject) use of CAP_SYS_ADMIN denied for /usr/bin/eject[eject:26611] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2838] uid/euid:0/0 gid/egid:0/0

Feb 23 18:58:23 gbn kernel: [67381.960569] grsec: (root:U:/usr/bin/eject) use of CAP_SYS_RAWIO denied for /usr/bin/eject[eject:26611] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2838] uid/euid:0/0 gid/egid:0/0

Feb 23 18:58:23 gbn kernel: [67381.961406] grsec: (root:U:/usr/bin/eject) use of CAP_SYS_RAWIO denied for /usr/bin/eject[eject:26611] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2838] uid/euid:0/0 gid/egid:0/0

Feb 23 18:58:23 gbn kernel: [67381.962427] grsec: more alerts, logging disabled for 10 seconds

Feb 23 18:58:30 gbn kernel: [67389.749802] VFS: busy inodes on changed media or resized disk sr0

Feb 23 19:00:01 gbn run-crons[26624]: (root) CMD (/etc/cron.hourly/logrotate)

Feb 23 19:00:01 gbn run-crons[26630]: (root) CMD (/etc/cron.hourly/man-db)

Feb 23 19:00:01 gbn run-crons[26633]: (root) CMD (/etc/cron.hourly/mlocate)

Feb 23 19:00:02 gbn run-crons[26645]: (root) CMD (/etc/cron.hourly/rkhunter)

Feb 23 19:04:12 gbn postfix/pickup[26428]: 7B001386521: uid=0 from=<root>

Feb 23 19:04:12 gbn postfix/cleanup[17952]: 7B001386521: message-id=<20150223180412.7B001386521@gbn.localdomain>

Feb 23 19:04:12 gbn postfix/qmgr[26429]: 7B001386521: from=<root@localdomain>, size=383, nrcpt=1 (queue active)

Feb 23 19:04:12 gbn postfix/local[17978]: 7B001386521: to=<root@localdomain.localdomain>, relay=local, delay=0.1, delays=0.07/0.01/0/0.03, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 19:04:12 gbn postfix/qmgr[26429]: 7B001386521: removed

Feb 23 19:04:12 gbn postfix/pickup[26428]: 942F238652D: uid=0 from=<root>

Feb 23 19:04:12 gbn postfix/cleanup[17952]: 942F238652D: message-id=<20150223180412.942F238652D@gbn.localdomain>

Feb 23 19:04:12 gbn run-crons[17999]: (root) CMD (/etc/cron.hourly/tripwire)

Feb 23 19:04:12 gbn postfix/qmgr[26429]: 942F238652D: from=<root@localdomain>, size=827, nrcpt=1 (queue active)

Feb 23 19:04:12 gbn postfix/local[17978]: 942F238652D: to=<root@localdomain>, orig_to=<root>, relay=local, delay=0.11, delays=0.06/0/0/0.05, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 19:04:12 gbn postfix/qmgr[26429]: 942F238652D: removed

Feb 23 19:05:14 gbn kernel: [67793.219711] grsec: (root:U:/etc/cron.hourly) denied open of /usr/sbin/sendmail for reading by /usr/sbin/tripwire[tripwire:18002] uid/euid:0/0 gid/egid:0/0, parent /etc/cron.hourly/tripwire[tripwire:18000] uid/euid:0/0 gid/egid:0/0

Feb 23 19:07:00 gbn tripwire[18002]: Integrity Check Complete: /var/lib/tripwire/gbn.twd TWReport gbn 20150223190412 V:24112 S:100 A:23511 R:219 C:382

Feb 23 19:07:01 gbn run-crons[18008]: (root) CMD (/etc/cron.hourly/yclamscan)

Feb 23 19:07:01 gbn postfix/pickup[26428]: 3FAE9386521: uid=0 from=<root>

Feb 23 19:07:01 gbn postfix/cleanup[18018]: 3FAE9386521: message-id=<20150223180701.3FAE9386521@gbn.localdomain>

Feb 23 19:07:01 gbn postfix/qmgr[26429]: 3FAE9386521: from=<root@localdomain>, size=1264493, nrcpt=1 (queue active)

Feb 23 19:07:01 gbn postfix/local[18020]: 3FAE9386521: to=<root@localdomain>, orig_to=<root>, relay=local, delay=0.19, delays=0.13/0.01/0/0.05, dsn=2.0.0, status=sent (delivered to maildir)

Feb 23 19:07:01 gbn postfix/qmgr[26429]: 3FAE9386521: removed

```

If you look at the llnes containing "hidden" and "denied".

Why would the eject program (the ejecting of BluRays that I communicate btwn my online and air-gapped systems) need to access /boot for the shine of the Look at you of the Intellect of the Worlds:

```

Feb 23 18:58:22 gbn kernel: [67381.954862] grsec: (root:U:/usr/bin/eject) denied access to hidden file /boot by /usr/bin/eject[eject:26611] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[bash:2838] uid/euid:0/0 gid/egid:0/0

```

and why would it need CAP_SYS_ADMIN? It opened and closed the tray as I asked for, so it did its work, but threw a few senseless errors on stdout.

Also, it appears to me, surely someone correct me if I'm wrong, that:

```

Feb 23 19:05:14 gbn kernel: [67793.219711] grsec: (root:U:/etc/cron.hourly) denied open of /usr/sbin/sendmail for reading by /usr/sbin/tripwire[tripwire:18002] uid/euid:0/0 gid/egid:0/0, parent /etc/cron.hourly/tripwire[tripwire:18000] uid/euid:0/0 gid/egid:0/0

```

crond (that is crond the binary IIUC, or dcron the program, in my system) only need to execute sendmail, not read it, does it?

This post is pending confirmation by more checking of my logs in the next hours. If I don't add to this, consider it confirmed.

----------

## miroR

And as far as the RBAC policy in question goes, you can read it in its entirety, here:

A no-poetteringware desktop RBAC policy

http://forums.grsecurity.net/viewtopic.php?f=5&p=15004

Cheers!

----------

