Changeset 131 for trunk/src/sh_suidchk.c


Ignore:
Timestamp:
Oct 22, 2007, 11:19:15 PM (17 years ago)
Author:
rainer
Message:

Use thread-safe libc functions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_suidchk.c

    r119 r131  
    7171
    7272#include "samhain.h"
     73#include "sh_pthread.h"
    7374#include "sh_utils.h"
    7475#include "sh_error.h"
     
    842843  char            fileHash[2*(KEY_LEN + 1)];
    843844
     845  struct sh_dirent * dirlist = NULL;
     846  struct sh_dirent * dirlist_orig = NULL;
    844847
    845848  SL_ENTER(_("sh_suidchk_check_internal"));
     
    870873  /* Loop over directory entries
    871874   */
     875  SH_MUTEX_LOCK(readdir_lock);
     876
    872877  do {
    873878
     
    886891        continue;
    887892
    888       tmpcat = SH_ALLOC(PATH_MAX);
    889       (void) sl_strlcpy(tmpcat, iname, PATH_MAX);
    890 
    891       if ((sl_strlen(tmpcat) != sl_strlen(iname)) || (tmpcat[0] == '\0'))
    892         {
    893           sl_status = SL_ETRUNC;
    894         }
    895       else
    896         {
    897           if (tmpcat[1] != '\0')
    898             sl_status = sl_strlcat(tmpcat, "/",                 PATH_MAX);
    899         }
    900 
    901       if (! SL_ISERROR(sl_status))
    902         sl_status = sl_strlcat(tmpcat, thisEntry->d_name,   PATH_MAX);
    903 
    904       if (SL_ISERROR(sl_status))
    905         {
    906           tmp = sh_util_safe_name(tmpcat);
    907           sh_error_handle ((-1), FIL__, __LINE__, (int) sl_status,
    908                            MSG_E_SUBGPATH,
    909                            _("path too long"),
    910                            _("sh_suidchk_check_internal"), tmp );
    911           SH_FREE(tmp);
    912           continue;
    913         }
    914 
    915       ++FileLimNum;
    916       ++FileLimTotal;
    917 
    918       /* Rate limit (Fps == Files per second)
    919        */
    920       if ((ShSuidchkFps > 0 && FileLimNum > ShSuidchkFps && FileLimTotal > 0)&&
    921           (ShSuidchkYield == S_FALSE))
    922         {
    923           FileLimNum  = 0;
    924           FileLimNow  = time(NULL);
    925  
    926           if ( (FileLimNow  - FileLimStart) > 0 &&
    927                FileLimTotal/(FileLimNow  - FileLimStart) > ShSuidchkFps )
    928             (void) retry_msleep((int)((FileLimTotal/(FileLimNow-FileLimStart))/
    929                    ShSuidchkFps) , 0);
    930         }
     893      dirlist = addto_sh_dirlist (thisEntry, dirlist);
     894    }
     895
     896  } while (thisEntry != NULL);
     897
     898  SH_MUTEX_UNLOCK(readdir_lock);
     899
     900  closedir(thisDir);
     901
     902  dirlist_orig = dirlist;
     903
     904  do {
     905
     906    /* If the directory is empty, dirlist = NULL
     907     */
     908    if (!dirlist)
     909      break;
     910
     911    tmpcat = SH_ALLOC(PATH_MAX);
     912    (void) sl_strlcpy(tmpcat, iname, PATH_MAX);
     913   
     914    if ((sl_strlen(tmpcat) != sl_strlen(iname)) || (tmpcat[0] == '\0'))
     915      {
     916        sl_status = SL_ETRUNC;
     917      }
     918    else
     919      {
     920        if (tmpcat[1] != '\0')
     921          sl_status = sl_strlcat(tmpcat, "/",                 PATH_MAX);
     922      }
     923
     924    if (! SL_ISERROR(sl_status))
     925      sl_status = sl_strlcat(tmpcat, dirlist->sh_d_name,   PATH_MAX);
     926
     927    if (SL_ISERROR(sl_status))
     928      {
     929        tmp = sh_util_safe_name(tmpcat);
     930        sh_error_handle ((-1), FIL__, __LINE__, (int) sl_status,
     931                         MSG_E_SUBGPATH,
     932                         _("path too long"),
     933                         _("sh_suidchk_check_internal"), tmp );
     934        SH_FREE(tmp);
     935        dirlist = dirlist->next;
     936        continue;
     937      }
     938
     939    ++FileLimNum;
     940    ++FileLimTotal;
     941
     942    /* Rate limit (Fps == Files per second)
     943     */
     944    if ((ShSuidchkFps > 0 && FileLimNum > ShSuidchkFps && FileLimTotal > 0)&&
     945        (ShSuidchkYield == S_FALSE))
     946      {
     947        FileLimNum  = 0;
     948        FileLimNow  = time(NULL);
     949       
     950        if ( (FileLimNow  - FileLimStart) > 0 &&
     951             FileLimTotal/(FileLimNow  - FileLimStart) > ShSuidchkFps )
     952          (void) retry_msleep((int)((FileLimTotal/(FileLimNow-FileLimStart))/
     953                                    ShSuidchkFps) , 0);
     954      }
    931955             
    932       status = (int) retry_lstat(FIL__, __LINE__, tmpcat, &buf);
    933 
    934       if (status != 0)
    935         {
    936           status = errno;
    937           tmp = sh_util_safe_name(tmpcat);
    938           sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, status, MSG_ERR_LSTAT,
    939                            sh_error_message(status),
    940                            tmpcat );
    941           SH_FREE(tmp);
    942         }
    943       else
    944         {
    945           if (/*@-usedef@*/S_ISDIR(buf.st_mode)/*@+usedef@*/ &&
    946               (ShSuidchkExclude == NULL ||
    947                0 != strcmp(tmpcat, ShSuidchkExclude)))
    948             {
    949               /* fs is a STATIC string or NULL
    950                */
    951               fs = filesystem_type (tmpcat, tmpcat, &buf);
    952               if (fs != NULL
     956    status = (int) retry_lstat(FIL__, __LINE__, tmpcat, &buf);
     957
     958    if (status != 0)
     959      {
     960        status = errno;
     961        tmp = sh_util_safe_name(tmpcat);
     962        sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, status, MSG_ERR_LSTAT,
     963                         sh_error_message(status),
     964                         tmpcat );
     965        SH_FREE(tmp);
     966      }
     967    else
     968      {
     969        if (/*@-usedef@*/S_ISDIR(buf.st_mode)/*@+usedef@*/ &&
     970            (ShSuidchkExclude == NULL ||
     971             0 != strcmp(tmpcat, ShSuidchkExclude)))
     972          {
     973            /* fs is a STATIC string or NULL
     974             */
     975            fs = filesystem_type (tmpcat, tmpcat, &buf);
     976            if (fs != NULL
    953977#ifndef SH_SUIDTESTDIR
    954                   &&
    955                   0 != strncmp (_("afs"),     fs, 3) &&
    956                   0 != strncmp (_("devfs"),   fs, 5) &&
    957                   0 != strncmp (_("iso9660"), fs, 7) &&
    958                   0 != strncmp (_("lustre"),  fs, 6) &&
    959                   0 != strncmp (_("mmfs"),    fs, 4) &&
    960                   0 != strncmp (_("msdos"),   fs, 5) &&
    961                   0 != strncmp (_("nfs"),     fs, 3) &&
    962                   0 != strncmp (_("proc"),    fs, 4) &&
    963                   0 != strncmp (_("vfat"),    fs, 4)
     978                &&
     979                0 != strncmp (_("afs"),     fs, 3) &&
     980                0 != strncmp (_("devfs"),   fs, 5) &&
     981                0 != strncmp (_("iso9660"), fs, 7) &&
     982                0 != strncmp (_("lustre"),  fs, 6) &&
     983                0 != strncmp (_("mmfs"),    fs, 4) &&
     984                0 != strncmp (_("msdos"),   fs, 5) &&
     985                0 != strncmp (_("nfs"),     fs, 3) &&
     986                0 != strncmp (_("proc"),    fs, 4) &&
     987                0 != strncmp (_("vfat"),    fs, 4)
    964988#endif
     989                )
     990              {
     991                if ((ShSuidchkNosuid == S_TRUE) ||
     992                    (0 != strncmp (_("nosuid"),  fs, 6)))
     993                  /* fprintf(stderr, "%s: %s\n", fs, tmpcat); */
     994                  (void) sh_suidchk_check_internal(tmpcat);
     995              }
     996          }
     997        else if (S_ISREG(buf.st_mode) &&
     998                 (0 !=(S_ISUID & buf.st_mode) ||
     999#if defined(HOST_IS_LINUX)
     1000                  (0 !=(S_ISGID & buf.st_mode) &&
     1001                   0 !=(S_IXGRP & buf.st_mode))
     1002#else 
     1003                  0 !=(S_ISGID & buf.st_mode)
     1004#endif
    9651005                  )
    966                 {
    967                   if ((ShSuidchkNosuid == S_TRUE) ||
    968                       (0 != strncmp (_("nosuid"),  fs, 6)))
    969                     /* fprintf(stderr, "%s: %s\n", fs, tmpcat); */
    970                     (void) sh_suidchk_check_internal(tmpcat);
    971                 }
    972             }
    973           else if (S_ISREG(buf.st_mode) &&
    974                    (0 !=(S_ISUID & buf.st_mode) ||
    975 #if defined(HOST_IS_LINUX)
    976                     (0 !=(S_ISGID & buf.st_mode) &&
    977                      0 !=(S_IXGRP & buf.st_mode))
    978 #else 
    979                     0 !=(S_ISGID & buf.st_mode)
    980 #endif
    981                     )
    982                    )
    983             {
    984              
    985               (void) sl_strlcpy (theFile.fullpath, tmpcat, PATH_MAX);
    986               theFile.check_mask  = sh_files_maskof(SH_LEVEL_READONLY);
    987               CLEAR_SH_FFLAG_REPORTED(theFile.file_reported);
    988               theFile.attr_string = NULL;
    989 
    990               status = sh_unix_getinfo (ShDFLevel[SH_ERR_T_RO],
    991                                         thisEntry->d_name,
    992                                         &theFile, fileHash, 0);
    993 
    994               tmp = sh_util_safe_name(tmpcat);
    995 
    996               if (status != 0)
    997                 {
    998                   sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__,
    999                                    0, MSG_E_SUBGPATH,
    1000                                    _("Could not check suid/sgid file"),
    1001                                    _("sh_suidchk_check_internal"),
    1002                                    tmp);
    1003                 }
    1004               else
    1005                 {
    1006 
    1007                   if ( sh.flag.update   == S_TRUE &&
    1008                       (sh.flag.checkSum == SH_CHECK_INIT  ||
    1009                        sh.flag.checkSum == SH_CHECK_CHECK))
    1010                     {
    1011                       /* Updating database. Report new files that
    1012                        * are not in database already. Then compare
    1013                        * to database and report changes.
    1014                        */
    1015                       if (-1 == sh_hash_have_it (tmpcat))
    1016                         {
    1017                           sh_error_handle ((-1), FIL__, __LINE__,
    1018                                            0, MSG_SUID_FOUND, tmp );
    1019                         }
    1020                       else
    1021                         {
    1022                           sh_error_handle (SH_ERR_ALL, FIL__, __LINE__,
    1023                                            0, MSG_SUID_FOUND, tmp );
    1024                         }
    1025 
    1026                       if (0 == sh_hash_compdata (SH_LEVEL_READONLY,
     1006                 )
     1007          {
     1008           
     1009            (void) sl_strlcpy (theFile.fullpath, tmpcat, PATH_MAX);
     1010            theFile.check_mask  = sh_files_maskof(SH_LEVEL_READONLY);
     1011            CLEAR_SH_FFLAG_REPORTED(theFile.file_reported);
     1012            theFile.attr_string = NULL;
     1013           
     1014            status = sh_unix_getinfo (ShDFLevel[SH_ERR_T_RO],
     1015                                      thisEntry->d_name,
     1016                                      &theFile, fileHash, 0);
     1017           
     1018            tmp = sh_util_safe_name(tmpcat);
     1019           
     1020            if (status != 0)
     1021              {
     1022                sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__,
     1023                                 0, MSG_E_SUBGPATH,
     1024                                 _("Could not check suid/sgid file"),
     1025                                 _("sh_suidchk_check_internal"),
     1026                                 tmp);
     1027              }
     1028            else
     1029              {
     1030               
     1031                if ( sh.flag.update   == S_TRUE &&
     1032                     (sh.flag.checkSum == SH_CHECK_INIT  ||
     1033                      sh.flag.checkSum == SH_CHECK_CHECK))
     1034                  {
     1035                    /* Updating database. Report new files that
     1036                     * are not in database already. Then compare
     1037                     * to database and report changes.
     1038                     */
     1039                    if (-1 == sh_hash_have_it (tmpcat))
     1040                      {
     1041                        sh_error_handle ((-1), FIL__, __LINE__,
     1042                                         0, MSG_SUID_FOUND, tmp );
     1043                      }
     1044                    else
     1045                      {
     1046                        sh_error_handle (SH_ERR_ALL, FIL__, __LINE__,
     1047                                         0, MSG_SUID_FOUND, tmp );
     1048                      }
     1049                   
     1050                    if (0 == sh_hash_compdata (SH_LEVEL_READONLY,
     1051                                               &theFile, fileHash,
     1052                                               _("[SuidCheck]"),
     1053                                               ShSuidchkSeverity))
     1054                      {
     1055                        sh_hash_pushdata_memory (&theFile, fileHash);
     1056                      }
     1057                   
     1058                    sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
     1059                   
     1060                  }
     1061               
     1062                else if (sh.flag.checkSum == SH_CHECK_INIT  &&
     1063                         sh.flag.update == S_FALSE )
     1064                  {
     1065                    /* Running init. Report on files detected.
     1066                     */
     1067                    sh_hash_pushdata (&theFile, fileHash);
     1068                    sh_error_handle ((-1), FIL__, __LINE__,
     1069                                     0, MSG_SUID_FOUND, tmp );
     1070                  }
     1071               
     1072                else if (sh.flag.checkSum == SH_CHECK_CHECK )
     1073                  {
     1074                    /* Running file check. Report on new files
     1075                     * detected, and quarantine them.
     1076                     */
     1077                    sh_error_handle (SH_ERR_ALL, FIL__, __LINE__,
     1078                                     0, MSG_SUID_FOUND, tmp );
     1079                   
     1080                    fflags = sh_hash_getflags(tmpcat);
     1081                   
     1082                    if ( (-1 == fflags) || (!SH_FFLAG_SUIDCHK_SET(fflags)))
     1083                      {
     1084                        if (-1 == fflags)
     1085                          report_file(tmpcat, &theFile, timestrc, timestra, timestrm);
     1086                       
     1087                        /* Quarantine file according to configured method
     1088                         */
     1089                        if (ShSuidchkQEnable == S_TRUE)
     1090                          {
     1091                            switch (ShSuidchkQMethod)
     1092                              {
     1093                              case SH_Q_DELETE:
     1094                                sh_q_delete(theFile.fullpath);
     1095                                break;
     1096                              case SH_Q_CHANGEPERM:
     1097                                sh_q_changeperm(theFile.fullpath);
     1098                                break;
     1099                              case SH_Q_MOVE:
     1100                                sh_q_move(theFile.fullpath, &theFile, timestrc, timestra, timestrm);
     1101                                break;
     1102                              default:
     1103                                sh_error_handle (ShSuidchkSeverity, FIL__,
     1104                                                 __LINE__, 0, MSG_SUID_QREPORT,
     1105                                                 _("Bad quarantine method"), tmp);
     1106                                break;
     1107                              }
     1108                          }
     1109                        else
     1110                          {
     1111                            /* 1.8.1 push file to in-memory database
     1112                             */
     1113                            (void) sh_hash_compdata (SH_LEVEL_READONLY,
     1114                                                     &theFile, fileHash,
     1115                                                     _("[SuidCheck]"),
     1116                                                     ShSuidchkSeverity);
     1117                           
     1118                            sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
     1119                           
     1120                          }
     1121                      }
     1122                    else
     1123                      {
     1124                        /* File exists. Check for modifications.
     1125                         */
     1126                        (void) sh_hash_compdata (SH_LEVEL_READONLY,
    10271127                                                 &theFile, fileHash,
    1028                                                  _("[SuidCheck]"),
    1029                                                  ShSuidchkSeverity))
    1030                         {
    1031                           sh_hash_pushdata_memory (&theFile, fileHash);
    1032                         }
    1033                      
    1034                       sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
    1035                      
    1036                     }
    1037 
    1038                   else if (sh.flag.checkSum == SH_CHECK_INIT  &&
    1039                            sh.flag.update == S_FALSE )
    1040                     {
    1041                       /* Running init. Report on files detected.
    1042                        */
    1043                       sh_hash_pushdata (&theFile, fileHash);
    1044                       sh_error_handle ((-1), FIL__, __LINE__,
    1045                                        0, MSG_SUID_FOUND, tmp );
    1046                     }
    1047 
    1048                   else if (sh.flag.checkSum == SH_CHECK_CHECK )
    1049                     {
    1050                       /* Running file check. Report on new files
    1051                        * detected, and quarantine them.
    1052                        */
    1053                       sh_error_handle (SH_ERR_ALL, FIL__, __LINE__,
    1054                                        0, MSG_SUID_FOUND, tmp );
    1055 
    1056                       fflags = sh_hash_getflags(tmpcat);
    1057 
    1058                       if ( (-1 == fflags) || (!SH_FFLAG_SUIDCHK_SET(fflags)))
    1059                         {
    1060                           if (-1 == fflags)
    1061                             report_file(tmpcat, &theFile, timestrc, timestra, timestrm);
    1062 
    1063                           /* Quarantine file according to configured method
    1064                           */
    1065                           if (ShSuidchkQEnable == S_TRUE)
    1066                             {
    1067                               switch (ShSuidchkQMethod)
    1068                                 {
    1069                                   case SH_Q_DELETE:
    1070                                     sh_q_delete(theFile.fullpath);
    1071                                     break;
    1072                                   case SH_Q_CHANGEPERM:
    1073                                     sh_q_changeperm(theFile.fullpath);
    1074                                     break;
    1075                                   case SH_Q_MOVE:
    1076                                     sh_q_move(theFile.fullpath, &theFile, timestrc, timestra, timestrm);
    1077                                     break;
    1078                                   default:
    1079                                     sh_error_handle (ShSuidchkSeverity, FIL__,
    1080                                                      __LINE__, 0, MSG_SUID_QREPORT,
    1081                                                      _("Bad quarantine method"), tmp);
    1082                                     break;
    1083                                 }
    1084                             }
    1085                           else
    1086                             {
    1087                               /* 1.8.1 push file to in-memory database
    1088                                */
    1089                               (void) sh_hash_compdata (SH_LEVEL_READONLY,
    1090                                                        &theFile, fileHash,
    1091                                                        _("[SuidCheck]"),
    1092                                                        ShSuidchkSeverity);
    1093 
    1094                               sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
    1095 
    1096                             }
    1097                         }
    1098                       else
    1099                         {
    1100                           /* File exists. Check for modifications.
    1101                            */
    1102                           (void) sh_hash_compdata (SH_LEVEL_READONLY,
    1103                                                    &theFile, fileHash,
    1104                                                    _("[SuidCheck]"),
    1105                                                    ShSuidchkSeverity);
    1106                          
    1107                           sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
    1108 
    1109                         }
    1110                     }
    1111                 }
    1112               SH_FREE(tmp);
    1113               if (theFile.attr_string)
    1114                 SH_FREE(theFile.attr_string);
    1115             }
    1116         }
    1117       SH_FREE(tmpcat);
    1118     }
    1119 
     1128                                                 _("[SuidCheck]"),
     1129                                                 ShSuidchkSeverity);
     1130                       
     1131                        sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
     1132                       
     1133                      }
     1134                  }
     1135              }
     1136            SH_FREE(tmp);
     1137            if (theFile.attr_string)
     1138              SH_FREE(theFile.attr_string);
     1139          }
     1140      }
     1141    SH_FREE(tmpcat);
     1142
     1143 
    11201144#ifdef HAVE_SCHED_YIELD
    11211145    if (ShSuidchkYield == S_TRUE)
     
    11251149            status = errno;
    11261150            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
    1127                              _("Failed to release time slice"),
     1151                             _("Failed to release time slice"),
    11281152                             _("sh_suidchk_check_internal") );
    11291153          }
    11301154      }
    11311155#endif
    1132 
    1133   }  while (thisEntry != NULL);
    1134 
    1135   (void) closedir (thisDir);
     1156 
     1157    dirlist = dirlist->next;
     1158
     1159  }  while (dirlist != NULL);
     1160
     1161
     1162  kill_sh_dirlist (dirlist_orig);
     1163
    11361164  SL_RETURN( (0), _("sh_suidchk_check_internal"));
    11371165}
Note: See TracChangeset for help on using the changeset viewer.