Changeset 411 for trunk/src/sh_unix.c


Ignore:
Timestamp:
Aug 28, 2012, 9:00:20 PM (12 years ago)
Author:
katerina
Message:

More fixes for ticket #311 (thread safety of --enable-ptrace) and an option for setting the time difference.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_unix.c

    r410 r411  
    54575457 */
    54585458#if defined(SCREW_IT_UP)
    5459 struct screw_it_up {
    5460   int not_traced;
     5459
     5460#if defined(HAVE_PTHREAD)
     5461
     5462static pthread_key_t  gSigtrapVariables_key;
     5463static pthread_once_t gSigtrapVariables_key_once = PTHREAD_ONCE_INIT;
     5464
     5465static inline void make_gSigtrapVariables_key()
     5466{
     5467    (void) pthread_key_create(&gSigtrapVariables_key, free);
     5468}
     5469
     5470struct sh_sigtrap_variables * sh_sigtrap_variables_get()
     5471{
     5472  void * ptr;
     5473
     5474  (void) pthread_once(&gSigtrapVariables_key_once, make_gSigtrapVariables_key);
     5475 
     5476  ptr = pthread_getspecific(gSigtrapVariables_key);
     5477  if (ptr == NULL) {
     5478    ptr = malloc(sizeof(struct sh_sigtrap_variables));
     5479    if (ptr == NULL) {
     5480      return NULL;
     5481    }
     5482    (void) pthread_setspecific(gSigtrapVariables_key, ptr);
     5483  }
     5484
     5485  return (struct sh_sigtrap_variables *) ptr;
     5486}
     5487
     5488/* !defined(HAVE_PTHREAD) */
     5489#else
     5490
     5491static struct sh_sigtrap_variables global_sigtrap_variables;
     5492struct sh_sigtrap_variables * sh_sigtrap_variables_get()
     5493{
     5494  return &global_sigtrap_variables;
     5495}
     5496
     5497#endif
     5498
     5499int sh_sigtrap_max_duration_set (const char * str)
     5500{
     5501  /* For security (prevent reloading with larger value)
     5502   * this value can only be set once.
     5503   */
     5504  static int once = 0;
     5505  int i;
     5506
     5507  SL_ENTER(_("sh_sigtrap_max_duration_set"));
     5508
     5509  i = atoi (str);
     5510
     5511  if (i >= 0 && once == 0)
     5512    {
     5513      sh.sigtrap_max_duration = i;
     5514      once = 1;
     5515    }
     5516  else
     5517    {
     5518      SL_RETURN ((-1), _("sh_sigtrap_max_duration_set"));
     5519    }
     5520  SL_RETURN( (0), _("sh_sigtrap_max_duration_set"));
     5521}
     5522
     5523void sh_sigtrap_handler (int signum)
     5524{
     5525  struct sh_sigtrap_variables * sigtrap_variables;
     5526  sigtrap_variables = sh_sigtrap_variables_get();
     5527  if (sigtrap_variables == NULL) {
     5528    /* Perhaps, it's better to not die, and to continue using Samhain,
     5529       even if this part does not work. */
     5530    return;
     5531  }
     5532
    54615533#ifdef HAVE_GETTIMEOFDAY
    5462   struct timeval save_tv;
    5463 #endif
    5464 };
    5465 
    5466 #if defined(HAVE_PTHREAD)
    5467 
    5468 static pthread_key_t  gSaveTv_key;
    5469 static pthread_once_t gSaveTv_key_once = PTHREAD_ONCE_INIT;
    5470 
    5471 static inline void make_gSaveTv_key()
    5472 {
    5473     (void) pthread_key_create(&gSaveTv_key, free);
    5474 }
    5475 
    5476 static inline struct screw_it_up * sh_get_screw_it_up()
    5477 {
    5478   void * ptr;
    5479   struct screw_it_up * screw;
    5480 
    5481   (void) pthread_once(&gSaveTv_key_once, make_gSaveTv_key);
    5482  
    5483   if ((ptr = pthread_getspecific(gSaveTv_key)) == NULL)
    5484     {
    5485       ptr = malloc(sizeof(struct screw_it_up));
    5486       if (ptr)
    5487         {
    5488           screw = (struct screw_it_up *) ptr;
    5489           (void) pthread_setspecific(gSaveTv_key, ptr);
    5490         }
    5491       else
    5492         {
    5493           return NULL;
    5494         }
    5495     }
    5496   else
    5497     {
    5498       screw = (struct screw_it_up *) ptr;
    5499     }
    5500   return screw;
    5501 }
    5502 
    5503 #ifdef HAVE_GETTIMEOFDAY
    5504 void sh_set_save_tv()
    5505 {
    5506   struct screw_it_up * screw = sh_get_screw_it_up();
    5507   struct timeval * save_tv = &(screw->save_tv);
    5508   if (save_tv)
    5509     gettimeofday(save_tv, NULL);
     5534  {
     5535    struct timeval  tv;
     5536    long   difftv;
     5537   
     5538    gettimeofday(&tv, NULL);
     5539    difftv = (tv.tv_sec - sigtrap_variables->save_tv.tv_sec) * 1000000 +
     5540      (tv.tv_usec - sigtrap_variables->save_tv.tv_usec);
     5541    if (difftv > sh.sigtrap_max_duration)
     5542      raise(SIGKILL);
     5543  }
     5544#endif
     5545
     5546  sigtrap_variables->not_traced = signum;
    55105547  return;
    55115548}
    5512 struct timeval * sh_get_save_tv()
    5513 {
    5514   struct screw_it_up * screw = sh_get_screw_it_up();
    5515   struct timeval * save_tv = &(screw->save_tv);
    5516   return save_tv;
    5517 }
    5518 /* #ifdef HAVE_GETTIMEOFDAY */
    5519 #endif
    5520 
    5521 void sh_set_untraced(int val)
    5522 {
    5523   struct screw_it_up * screw = sh_get_screw_it_up();
    5524 
    5525   screw->not_traced = val;
    5526   return;
    5527 }
    5528 int sh_get_untraced()
    5529 {
    5530   struct screw_it_up * screw = sh_get_screw_it_up();
    5531 
    5532   return screw->not_traced;
    5533 }
    5534 
    5535 /* !defined(HAVE_PTHREAD) */
    5536 #else
    5537 
    5538 #ifdef HAVE_GETTIMEOFDAY
    5539 static struct timeval * sSaveTv = NULL;
    5540 static inline struct timeval * sh_get_save_tv()
    5541 {
    5542   return sSaveTv;
    5543 }
    5544 void sh_set_save_tv()
    5545 {
    5546   gettimeofday(sSaveTv, NULL);
    5547 }
    5548 /* #ifdef HAVE_GETTIMEOFDAY */
    5549 #endif
    5550 
    5551 volatile int sh_not_traced = 0;
    5552 void sh_set_untraced(int val)
    5553 {
    5554   sh_not_traced = val;
    5555   return;
    5556 }
    5557 int sh_get_untraced()
    5558 {
    5559   return sh_not_traced;
    5560 }
    5561 
    5562 #endif
    5563 
    5564 
    5565 void sh_sigtrap_handler (int signum)
    5566 {
    5567 #ifdef HAVE_GETTIMEOFDAY
    5568   struct timeval  tv;
    5569   long   difftv;
    5570   struct timeval * save_tv = sh_get_save_tv();
    5571 
    5572   gettimeofday(&tv, NULL);
    5573  
    5574   difftv = (tv.tv_sec - save_tv->tv_sec) * 1000000 +
    5575     (tv.tv_usec - save_tv->tv_usec);
    5576   if (difftv > 500000)
    5577     raise(SIGKILL);
    5578 #endif
    5579   sh_set_untraced(signum);
    5580   return;
    5581 }
    5582 #endif
     5549#endif
Note: See TracChangeset for help on using the changeset viewer.