#! /usr/bin/stap -g
// CVE-2018-14634
//
// Theory of operations: adjust the thread's # rlimit-in-effect around
// calls to the vulnerable get_arg_page() function so as to encompass
// the newly required _STK_LIM / 4 * 3 maximum.

// Complication: the rlimit is stored in a current-> structure that
// is shared across the threads of the process.  They may concurrently
// invoke this operation.

// First attempt ... don't overthink it, just permanently reduce the
// rlimit.


function clamp_stack_rlim_cur:long ()
%{
  struct rlimit *rlim = current->signal->rlim;
  unsigned long rlim_cur = READ_ONCE(rlim[RLIMIT_STACK].rlim_cur);

  unsigned long limit = _STK_LIM / 4 * 3;
  limit *= 4; // multiply it back up, to the scale used by rlim_cur

  if (rlim_cur > limit) {
    WRITE_ONCE(rlim[RLIMIT_STACK].rlim_cur, limit);
    STAP_RETURN(limit);
  } else
    STAP_RETURN(0);
%}

probe kernel.function("copy_strings").call
{
  l = clamp_stack_rlim_cur()
   if (l)
     printf("lowered process %s(%d) STACK rlim_cur to %p\n",
            execname(), pid(), l)
}


probe begin {
	printf("CVE-2018-14634 mitigation loaded\n")

}

probe end {
	printf("CVE-2018-14634 mitigation unloaded\n")
}

