Пример #1
0
// Run the command specified by the argv array and kill it after timeout
// seconds.
static void SpawnCommand(char *const *argv, double timeout_secs) {
  CHECK_CALL(global_child_pid = fork());
  if (global_child_pid == 0) {
    // In child.
    CHECK_CALL(setsid());
    ClearSignalMask();

    // Force umask to include read and execute for everyone, to make
    // output permissions predictable.
    umask(022);

    // Does not return unless something went wrong.
    execvp(argv[0], argv);
    err(EXIT_FAILURE, "execvp(\"%s\", ...)", argv[0]);
  } else {
    // In parent.

    // Set up a signal handler which kills all subprocesses when the given
    // signal is triggered.
    HandleSignal(SIGALRM, OnSignal);
    HandleSignal(SIGTERM, OnSignal);
    HandleSignal(SIGINT, OnSignal);
    SetTimeout(timeout_secs);

    int status = WaitChild(global_child_pid, argv[0]);

    // The child is done for, but may have grandchildren that we still have to
    // kill.
    kill(-global_child_pid, SIGKILL);

    if (global_signal > 0) {
      // Don't trust the exit code if we got a timeout or signal.
      UnHandle(global_signal);
      raise(global_signal);
    } else if (WIFEXITED(status)) {
      exit(WEXITSTATUS(status));
    } else {
      int sig = WTERMSIG(status);
      UnHandle(sig);
      raise(sig);
    }
  }
}
Пример #2
0
void UnHandle(int sig) {
  switch (sig) {
    case SIGSTOP:
    case SIGKILL:
      // These signals can't be handled, so they'll always have a valid default
      // handler. In fact, even trying to install SIG_DFL again will result in
      // EINVAL, so we'll just not do anything for these.
      return;
    default:
      HandleSignal(sig, SIG_DFL);
  }
}
Пример #3
0
void DirPop(int goback,char * name,struct stat *sb)      /* Exit dir and check for race exploits */

{
if (goback && TRAVLINKS)
   {
   if (chdir(name) == -1)
      {
      snprintf(OUTPUT,CF_BUFSIZE,"Error in backing out of recursive descent securely to %s",name);
      CfLog(cferror,OUTPUT,"chdir");
      HandleSignal(SIGTERM);
      }
   
   CheckLinkSecurity(sb,name); 
   }
else if (goback)
   {
   if (chdir("..") == -1)
      {
      snprintf(OUTPUT,CF_BUFSIZE,"Error in backing out of recursive descent securely to %s",name);
      CfLog(cferror,OUTPUT,"chdir");
      HandleSignal(SIGTERM);
      }
   }
}
Пример #4
0
void CheckLinkSecurity(struct stat *sb,char *name)

{ struct stat security;

Debug("Checking the inode and device to make sure we are where we think we are...\n"); 

if (stat(".",&security) == -1)
   {
   snprintf(OUTPUT,CF_BUFSIZE,"Could not stat directory %s after entering!",name);
   CfLog(cferror,OUTPUT,"stat");
   return;
   }

if ((sb->st_dev != security.st_dev) || (sb->st_ino != security.st_ino))
   {
   snprintf(OUTPUT,CF_BUFSIZE,"SERIOUS SECURITY ALERT: path race exploited in recursion to/from %s. Not safe for agent to continue - aborting",name);
   CfLog(cferror,OUTPUT,"");
   HandleSignal(SIGTERM);
   /* Exits */
   }
}
Пример #5
0
// Set up various signal handlers.
static void SetupSignals(void) {
  HandleSignal(SIGSEGV, RecoverFromError);
  HandleSignal(SIGBUS, RecoverFromError);
  HandleSignal(SIGFPE, RecoverFromError);
  HandleSignal(SIGTRAP, ConsumeTrap);
  HandleSignal(SIGILL, HandleUnsupportedInstruction);
#ifdef SIGSTKFLT
  HandleSignal(SIGSTKFLT, RecoverFromError);
#endif  // SIGSTKFLT
  sigset_t set;
  sigemptyset(&set);
  sigprocmask(SIG_SETMASK, &set, nullptr);

  stack_t sig_stack;
  sig_stack.ss_sp = &gSigStack;
  sig_stack.ss_size = SIGSTKSZ;
  sig_stack.ss_flags = 0;
  sigaltstack(&sig_stack, nullptr);
}
Пример #6
0
/**
 * @function GUI_DrawObjects
 * @brief handle all object (user event, refresh)
 * @param none
 * @return none
 */
void GUI_DrawObjects(void) {

  g_obj_st *ptr = NULL;
  coord_t newX, newY;

  /*reset signal & read touch screen; only once for all object*/
  signal = 0;
  TouchScreenRead(&newX, &newY);

  /*small hysteresis to compensate touchscreen noise*/
  #define TOUCH_THRES_HYS 2
  if(newX < 0 || newY < 0) {
    x = y = -1;
  }
  else {

    if(x < 0 || y < 0) {
      x = newX;
      y = newY;
    }
    else if(P2D_Abs(newX - x) > TOUCH_THRES_HYS || P2D_Abs(newY - y) > TOUCH_THRES_HYS) {
      x = newX;
      y = newY;
    }
  }


  /*get the object list, according to the active layer*/
  ptr = GetObjectList();

  /*process notification blink*/
  if(IsTimerElapsed(tmrBlink)) {
    bBlink = !bBlink;
    tmrBlink = GetPeriodicTimeout(500);
    while(ptr != NULL) {
      GUI_ObjSetBlink(ptr, bBlink);
      ptr = ptr->next;
    }
  }

  /*process each generic object of the current layer*/
  while(ptr != NULL) {

    /*handle user interaction*/
    HandleTouchEvent(x, y, ptr);

    /*handle object signals*/
    HandleSignal(ptr);

    if(ptr->obj != NULL) {

      /*launch the object task, if any*/
      if(ptr->task != NULL) ptr->task(ptr, ptr->obj);

      /*redraw the object, only if needed*/
      if(GUI_ObjIsNeedRefresh(ptr) && ptr->draw != NULL) {
        P2D_SetClip(&(ptr->rec));
        ptr->draw(ptr, ptr->obj);
        GUI_ObjSetNeedRefresh(ptr, false);
      }
    }

    /*next object*/
    ptr = ptr->next;
  }

  /**
   * execute, if any, the top layer task
   * pInternalTask may close the top layer and return a signal;
   * when closing the top layer, pInternalTask becomes NULL
   * this signal will be given to the user at end of GUI_DrawObjects()
   */
  if(pInternalTask != NULL) signal = pInternalTask(signal);
  
  /**
   * Save the last non null signal (for slave remote)
   */
  if(signal != 0 && pInternalTask == NULL) {
    lastSignal = signal;
  }
  
  /**
   * execute the user task, if no internal task is running
   * DO NOT concate this condition with the previous one in a if/else statement !
   */
  if(pInternalTask == NULL) {
    if(pUserTask != NULL) pUserTask(signal);
  }
}