Changeset 93 for trunk


Ignore:
Timestamp:
Feb 26, 2007, 10:48:51 PM (18 years ago)
Author:
rainer
Message:

Add check for PCI ROMs; fix ticket #51 (symlinks in root directory reported with leading double slash).

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/docs/Changelog

    r92 r93  
     12.3.3:
     2        * fix bug with leading slashes in liked path of symlinks within
     3          the root directory
     4        * sh_kern.c: check PCI ROM (Linux), refactor code
     5        * move file descriptor closing more towards program startup
     6        * kernel check: support OpenBSD 4.0 (wishlist)
     7        * fix samhain_hide module (in-)compatibility with recent kernels
     8          (reported by Jonny Halfmoon)
     9
    1102.3.2:
    2         * move file descriptor closing more towards program startup
    3         * fix samhain_hide module (in-)compatibility with recent kernels
    411        * fix regression in full stealth mode (incorrect comparison of
    512          bytes read vs. maximum capacity), reported by B. Fleming
  • trunk/docs/README.UPGRADE

    r73 r93  
    11
    2 from lower to 2.3.x: database scheme has changed slightly
     2to 2.3.3 and higher: a bug has been fixed that resulted in an additional
     3  slash at the beginning of the linked path of symlinks in the root
     4  directory (symlinks in other directories were not affected)
     5
     6  -- this may cause spurious warnings about modified links, if you check
     7     against a database created with an earlier version of samhain
     8
     9
     10
     11from lower to 2.3.x: the database scheme has changed slightly.
     12  To upgrade, use the following SQL commands in the command-line
     13  client of your database:
    314
    415  -- MySQL:
  • trunk/include/samhain.h

    r76 r93  
    124124  SH_CHECK_CHECK   = 2
    125125};
     126
     127#define SH_KEY_NULL _("000000000000000000000000000000000000000000000000")
    126128
    127129/**************************************************
  • trunk/include/sh_utils.h

    r76 r93  
    102102int sh_util_obscure_ok (const char * str);
    103103
    104 /* read a hexchar
     104/* output a hexchar[2]
     105 */
     106char * sh_util_charhex( unsigned char c );
     107
     108/* read a hexchar, return int value (0-15)
    105109 */
    106110int sh_util_hexchar( char c );
  • trunk/src/cutest_sh_utils.c

    r76 r93  
    143143  char res3[] = "/";
    144144
     145  char input4[] = "///foo//bar";
     146  char res4[] = "///foo";
     147
     148  char input5[] = "//foo///bar///";
     149  char res5[] = "//foo";
     150
     151  char input6[] = "///";
     152  char res6[] = "///";
     153
     154  char input7[] = "//f///b///";
     155  char res7[] = "//f";
     156
     157  char input8[] = "/f/b/";
     158  char res8[] = "/f";
     159
     160  char input9[] = "/f/b";
     161  char res9[] = "/f";
     162
    145163  ret = sh_util_dirname(input0);
    146164  CuAssertPtrNotNull(tc, ret);
     
    158176  CuAssertPtrNotNull(tc, ret);
    159177  CuAssertStrEquals(tc, res3, ret);
     178
     179  ret = sh_util_dirname(input4);
     180  CuAssertPtrNotNull(tc, ret);
     181  CuAssertStrEquals(tc, res4, ret);
     182
     183  ret = sh_util_dirname(input5);
     184  CuAssertPtrNotNull(tc, ret);
     185  CuAssertStrEquals(tc, res5, ret);
     186
     187  ret = sh_util_dirname(input6);
     188  CuAssertPtrNotNull(tc, ret);
     189  CuAssertStrEquals(tc, res6, ret);
     190
     191  ret = sh_util_dirname(input7);
     192  CuAssertPtrNotNull(tc, ret);
     193  CuAssertStrEquals(tc, res7, ret);
     194
     195  ret = sh_util_dirname(input8);
     196  CuAssertPtrNotNull(tc, ret);
     197  CuAssertStrEquals(tc, res8, ret);
     198
     199  ret = sh_util_dirname(input9);
     200  CuAssertPtrNotNull(tc, ret);
     201  CuAssertStrEquals(tc, res9, ret);
    160202  return;
    161203}
     
    179221  char res4[] = "bar";
    180222
     223  char input5[] = "/foo///bar///";
     224  char res5[] = "bar";
     225
     226  char input6[] = "//foo";
     227  char res6[] = "foo";
     228
    181229  ret = sh_util_basename(input0);
    182230  CuAssertPtrNotNull(tc, ret);
     
    198246  CuAssertPtrNotNull(tc, ret);
    199247  CuAssertStrEquals(tc, res4, ret);
     248
     249  ret = sh_util_basename(input5);
     250  CuAssertPtrNotNull(tc, ret);
     251  CuAssertStrEquals(tc, res5, ret);
     252
     253  ret = sh_util_basename(input6);
     254  CuAssertPtrNotNull(tc, ret);
     255  CuAssertStrEquals(tc, res6, ret);
    200256
    201257  return;
  • trunk/src/sh_hash.c

    r77 r93  
    19261926 ******************************************************************/
    19271927
    1928 static char * sh_hash_charhex( unsigned char i )
    1929 {
    1930   static char i2h[2];
    1931   int j, k;
    1932 
    1933   j = i / 16;
    1934   k = i - (j*16);
    1935 
    1936   if (j < 10) i2h[0] = '0'+j;
    1937   else        i2h[0] = 'A'+(j-10);
    1938  
    1939   if (k < 10) i2h[1] = '0'+k;
    1940   else        i2h[1] = 'A'+(k-10);
    1941 
    1942   return i2h;
    1943 }
    1944 
    19451928void sh_hash_push2db (char * key, unsigned long val1,
    19461929                      unsigned long val2, unsigned long val3,
     
    19751958      for (i = 0; i < size; ++i)
    19761959        {
    1977           p = sh_hash_charhex (str[i]);
     1960          p = sh_util_charhex (str[i]);
    19781961          tmpFile.linkpath[2*i]   = p[0];
    19791962          tmpFile.linkpath[2*i+1] = p[1];
     
    19831966  else
    19841967    {
    1985       tmpFile.c_mode[0] = '-'; 
    1986       tmpFile.c_mode[1] = '-'; tmpFile.c_mode[2]  = '-';
    1987       tmpFile.c_mode[3] = '-'; tmpFile.c_mode[4]  = '-';
    1988       tmpFile.c_mode[5] = '-'; tmpFile.c_mode[6]  = '-';
    1989       tmpFile.c_mode[7] = '-'; tmpFile.c_mode[8]  = '-';
    1990       tmpFile.c_mode[9] = '-'; tmpFile.c_mode[10] = '\0';
    1991       tmpFile.linkpath[0] = '-'; tmpFile.linkpath[1] = '\0';
     1968      for (i = 0; i < 10; ++i)
     1969        tmpFile.c_mode[i] = '-';
     1970      tmpFile.c_mode[10] = '\0';
     1971      tmpFile.linkpath[0] = '-';
     1972      tmpFile.linkpath[1] = '\0';
    19921973    }
    19931974
    19941975  if (sh.flag.checkSum == SH_CHECK_CHECK &&
    19951976      sh.flag.update == S_TRUE)
    1996     sh_hash_pushdata_memory (&tmpFile,
    1997                              _("000000000000000000000000000000000000000000000000"));
    1998   else
    1999     sh_hash_pushdata (&tmpFile,
    2000                       _("000000000000000000000000000000000000000000000000"));
     1977    sh_hash_pushdata_memory (&tmpFile, SH_KEY_NULL);
     1978  else
     1979    sh_hash_pushdata (&tmpFile, SH_KEY_NULL);
    20011980
    20021981  return;
     
    20181997  if (0 == sh_hash_get_it (key, &tmpFile))
    20191998    {
    2020       *val1  = tmpFile.size;
     1999      *val1 = tmpFile.size;
    20212000      *val2 = tmpFile.mtime;
    20222001      *val3 = tmpFile.ctime;
     
    27012680          maxcomp = KEY_LEN;
    27022681        }
    2703 
    2704     if ( sl_strncmp (linkHash, p->linkpath, maxcomp) != 0 &&
    2705          (theFile->check_mask & MODI_LNK) != 0)
    2706       {
    2707         modi_mask |= MODI_LNK;
    2708         change_code[1] = 'L';
    2709         TPT ((0, FIL__, __LINE__, _("mod=<link>")));
    2710       }
     2682     
     2683
     2684      if ( sl_strncmp (linkHash, p->linkpath, maxcomp) != 0 &&
     2685           (theFile->check_mask & MODI_LNK) != 0)
     2686        {
     2687          modi_mask |= MODI_LNK;
     2688          change_code[1] = 'L';
     2689          TPT ((0, FIL__, __LINE__, _("mod=<link>")));
     2690        }
    27112691    }
    27122692
  • trunk/src/sh_kern.c

    r83 r93  
    2323#define SH_SYSCALL_CODE
    2424
    25 #ifdef HOST_IS_I86LINUX
    26 #define SH_IDT_TABLE
    27 #define SH_PROC_CHECK
    28 #endif
    2925
    3026#include <stdio.h>
     
    156152#endif
    157153
     154/* This is the module 'reconfigure' function, which is a no-op.
     155 */
    158156int sh_kern_null()
    159157{
     
    161159}
    162160
    163 #ifdef SH_IDT_TABLE
     161#define SH_KERN_DBPUSH 0
     162#define SH_KERN_DBPOP  1
     163
     164char * sh_kern_db_syscall (int num, char * prefix,
     165                   void * in_name, unsigned long * addr,
     166                           unsigned int * code1, unsigned int * code2,
     167                           int * size, int direction)
     168{
     169  char            path[128];
     170  char          * p = NULL;
     171  unsigned long   x1 = 0, x2 = 0;
     172  unsigned char * name = (unsigned char *) in_name;
     173
     174  sl_snprintf(path, 128, "K_%s_%04d", prefix, num);
     175
     176  if (direction == SH_KERN_DBPUSH)
     177    {
     178      x1 = *code1;
     179      x2 = *code2;
     180
     181      sh_hash_push2db (path, *addr, x1, x2,
     182                       name, (name == NULL) ? 0 : (*size));
     183    }
     184  else
     185    {
     186      p = sh_hash_db2pop (path, addr,  &x1, &x2, size);
     187      *code1 = (unsigned int) x1;
     188      *code2 = (unsigned int) x2;
     189    }
     190  return p;
     191}
     192
     193static char * sh_kern_pathmsg (char * msg, size_t msg_len,
     194                               int num, char * prefix,
     195                               unsigned char * old, size_t old_len,
     196                               unsigned char * new, size_t new_len)
     197{
     198  size_t k;
     199  char   tmp[128];
     200  char  *p;
     201  char  *linkpath_old;
     202  char  *linkpath_new;
     203
     204#ifdef SH_USE_XML
     205  sl_snprintf(tmp, sizeof(tmp), _("path=\"K_%s_%04d\" "),
     206              prefix, num);
     207#else
     208  sl_snprintf(tmp, sizeof(tmp), _("path=<K_%s_%04d> "),
     209              prefix, num);
     210#endif
     211  sl_strlcpy(msg, tmp, msg_len);
     212
     213  if (SL_TRUE == sl_ok_muls(old_len, 2) &&
     214      SL_TRUE == sl_ok_adds(old_len * 2, 1))
     215    linkpath_old = SH_ALLOC(old_len * 2 + 1);
     216  else
     217    return msg;
     218
     219  if (SL_TRUE == sl_ok_muls(new_len, 2) &&
     220      SL_TRUE == sl_ok_adds(new_len * 2, 1))
     221    linkpath_new = SH_ALLOC(new_len * 2 + 1);
     222  else
     223    return msg;
     224
     225  for (k = 0; k < old_len; ++k)
     226    {
     227      p = sh_util_charhex (old[k]);
     228      linkpath_old[2*k]   = p[0];
     229      linkpath_old[2*k+1] = p[1];
     230      linkpath_old[2*k+2] = '\0';
     231    }
     232
     233  for (k = 0; k < new_len; ++k)
     234    {
     235      p = sh_util_charhex (new[k]);
     236      linkpath_new[2*k]   = p[0];
     237      linkpath_new[2*k+1] = p[1];
     238      linkpath_new[2*k+2] = '\0';
     239   
     240}
     241#ifdef SH_USE_XML
     242  sl_strlcat(msg, _("link_old=\""),    msg_len);
     243  sl_strlcat(msg, linkpath_old,        msg_len);
     244  sl_strlcat(msg, _("\" link_new=\""), msg_len);
     245  sl_strlcat(msg, linkpath_new,        msg_len);
     246  sl_strlcat(msg, _("\""),             msg_len);
     247#else
     248  sl_strlcat(msg, _("link_old=<"),     msg_len);
     249  sl_strlcat(msg, linkpath_old,        msg_len);
     250  sl_strlcat(msg, _(">, link_new=<"),  msg_len);
     251  sl_strlcat(msg, linkpath_new,        msg_len);
     252  sl_strlcat(msg, _(">"),              msg_len);
     253#endif
     254
     255  SH_FREE(linkpath_old);
     256  SH_FREE(linkpath_new);
     257
     258  return msg;
     259}
     260 
     261#ifdef HOST_IS_LINUX
     262
     263/*
     264 * Interrupt Descriptor Table
     265 */
    164266
    165267#include <asm/segment.h>
    166268
    167269#define SH_MAXIDT   256
    168 unsigned char sh_idt_table[SH_MAXIDT * 8];
    169 char * sh_strseg(unsigned short segment)
     270
     271static unsigned char sh_idt_table[SH_MAXIDT * 8];
     272
     273static char * sh_strseg(unsigned short segment)
    170274{
    171275  switch (segment) {
     
    182286  }
    183287}
    184 /* ifdef SH_IDT_TABLE */
    185 #endif
    186 
    187 static char * sh_kern_charhex( unsigned char i )
    188 {
    189   static char i2h[2];
    190   int j, k;
    191 
    192   j = i / 16;
    193   k = i - (j*16);
    194 
    195   if (j < 10) i2h[0] = '0'+j;
    196   else        i2h[0] = 'A'+(j-10);
    197  
    198   if (k < 10) i2h[1] = '0'+k;
    199   else        i2h[1] = 'A'+(k-10);
    200 
    201   return i2h;
    202 }
    203 
    204 static void sh_kern_push2db (char * name, unsigned long addr,
    205                              unsigned long code1, unsigned long code2,
    206                              unsigned char * code, int size)
    207 {
    208   file_type   tmpFile;
    209   int         i = 0;
    210   char      * p;
    211 
    212   tmpFile.attr_string = NULL;
    213 
    214   sl_strlcpy(tmpFile.fullpath, name, PATH_MAX);
    215   tmpFile.size  = addr;
    216   tmpFile.mtime = code1;
    217   tmpFile.ctime = code2;
    218 
    219   tmpFile.atime = 0;
    220   tmpFile.mode  = 0;
    221   tmpFile.owner = 0;
    222   tmpFile.group = 0;
    223   sl_strlcpy(tmpFile.c_owner, _("root"), 5);
    224   sl_strlcpy(tmpFile.c_group, _("root"), 5);
    225 
    226   if ((code != NULL) && (size < (PATH_MAX/2)-1))
    227     {
    228       tmpFile.c_mode[0] = 'l'; 
    229       tmpFile.c_mode[1] = 'r'; tmpFile.c_mode[2]  = 'w';
    230       tmpFile.c_mode[3] = 'x'; tmpFile.c_mode[4]  = 'r';
    231       tmpFile.c_mode[5] = 'w'; tmpFile.c_mode[6]  = 'x';
    232       tmpFile.c_mode[7] = 'r'; tmpFile.c_mode[8]  = 'w';
    233       tmpFile.c_mode[9] = 'x'; tmpFile.c_mode[10] = '\0';
    234       for (i = 0; i < size; ++i)
    235         {
    236           p = sh_kern_charhex (code[i]);
    237           tmpFile.linkpath[2*i]   = p[0];
    238           tmpFile.linkpath[2*i+1] = p[1];
    239           tmpFile.linkpath[2*i+2] = '\0';
    240         }
    241     }
    242   else
    243     {
    244       tmpFile.c_mode[0] = '-'; 
    245       tmpFile.c_mode[1] = '-'; tmpFile.c_mode[2]  = '-';
    246       tmpFile.c_mode[3] = '-'; tmpFile.c_mode[4]  = '-';
    247       tmpFile.c_mode[5] = '-'; tmpFile.c_mode[6]  = '-';
    248       tmpFile.c_mode[7] = '-'; tmpFile.c_mode[8]  = '-';
    249       tmpFile.c_mode[9] = '-'; tmpFile.c_mode[10] = '\0';
    250       tmpFile.linkpath[0] = '-'; tmpFile.linkpath[1] = '\0';
    251     }
    252 
    253   if (sh.flag.checkSum == SH_CHECK_CHECK && sh.flag.update == S_TRUE)
    254     sh_hash_pushdata_memory (&tmpFile,
    255                              _("000000000000000000000000000000000000000000000000"));
    256   else
    257     sh_hash_pushdata (&tmpFile,
    258                       _("000000000000000000000000000000000000000000000000"));
    259   return;
    260 }
    261 
    262 extern int sh_util_hextobinary (char * binary, const char * hex, int bytes);
    263 
    264 static char * sh_kern_db2pop (char * name, unsigned long * addr,
    265                               unsigned long * code1, unsigned long * code2,
    266                               int * size)
    267 {
    268   file_type   tmpFile;
    269   char      * p;
    270   int         i;
    271 
    272   if (0 == sh_hash_get_it (name, &tmpFile))
    273     {
    274       *addr  = tmpFile.size;
    275       *code1 = tmpFile.mtime;
    276       *code2 = tmpFile.ctime;
    277 
    278       if (tmpFile.linkpath[0] != '-')
    279         {
    280           p = SH_ALLOC(PATH_MAX);
    281           i = sh_util_hextobinary (p, tmpFile.linkpath,
    282                                    strlen(tmpFile.linkpath));
    283           if (i == 0)
    284             {
    285               *size = (strlen(tmpFile.linkpath)/2);
    286               p[*size] = '\0';
    287               return p;
    288             }
    289           else
    290             {
    291               SH_FREE(p);
    292               *size = 0;
    293               return NULL;
    294             }
    295         }
    296       else
    297         {
    298           *size = 0;
    299           return NULL;
    300         }
    301     }
    302   else
    303     {
    304       *size = 0;
    305       *addr = 0;
    306       return NULL;
    307     }
    308 }
    309 
    310 char * sh_kern_db_syscall (int num, char * prefix,
    311                            void * in_name, unsigned long * addr,
    312                            unsigned int * code1, unsigned int * code2,
    313                            int * size, int direction)
    314 {
    315   char            path[128];
    316   char          * p = NULL;
    317   unsigned long   x1 = 0, x2 = 0;
    318   unsigned char * name = (unsigned char *) in_name;
    319 
    320   sl_snprintf(path, 128, "K_%s_%04d", prefix, num);
    321 
    322   if (direction == 0)
    323     {
    324       x1 = *code1;
    325       x2 = *code2;
    326 
    327       sh_kern_push2db (path, *addr, x1, x2,
    328                        name, (name == NULL) ? 0 : (*size));
    329     }
    330   else
    331     {
    332       p = sh_kern_db2pop (path, addr,  &x1, &x2, size);
    333       *code1 = (unsigned int) x1;
    334       *code2 = (unsigned int) x2;
    335     }
    336   return p;
    337 }
    338  
    339 #ifdef HOST_IS_LINUX
    340 
    341 int sh_kern_data_init ()
     288
     289
     290static int sh_kern_data_init ()
    342291{
    343292  unsigned long store0 = 0;
     
    346295  char        * databuf;
    347296
    348 #ifdef SH_SYSCALL_CODE
    349297  /* system_call code
    350298   */
    351299  databuf = sh_kern_db_syscall (0, _("system_call"),
    352300                                NULL, &store0, &store1, &store2,
    353                                 &datasize, 1);
     301                                &datasize, SH_KERN_DBPOP);
    354302  if (datasize == sizeof(system_call_code))
    355303    {
     
    364312      return -1;
    365313    }
    366 #endif
    367314
    368315  /* syscall address and code
     
    372319      databuf = sh_kern_db_syscall (i, _("syscall"),
    373320                                    NULL, &store0, &store1, &store2,
    374                                     &datasize, 1);
     321                                    &datasize, SH_KERN_DBPOP);
    375322      sh_syscalls[i].addr = store0;
    376323      if (store0 == 0) {
     
    380327        return -1;
    381328      }
    382 #ifdef SH_SYSCALL_CODE
     329
    383330      sh_syscalls[i].code[0] = (unsigned int) store1;
    384331      sh_syscalls[i].code[1] = (unsigned int) store2;
     
    387334                        _("syscall code not found in database"),
    388335                        _("sh_kern_data_init"));
    389         /* fprintf(stderr, "Syscall #%d\n", i); */
    390         /* return -1; */
    391336      }
    392 #endif
     337
    393338      if (databuf != NULL) {
    394339        SH_FREE(databuf);
     
    397342    }
    398343
    399 #ifdef SH_IDT_TABLE
    400344  if (ShKernIDT == S_TRUE)
    401345    {
     
    405349                                        NULL,
    406350                                        &store0, &store1, &store2,
    407                                         &datasize, 1);
     351                                        &datasize, SH_KERN_DBPOP);
    408352          if (datasize == 8) {
    409353            memcpy(&idt_table[j*8], databuf, 8);
     
    417361        }
    418362    }
    419 #endif
    420363
    421364  return 0;
    422365}
    423366
    424 #ifdef SH_PROC_CHECK
    425367
    426368/*
     
    495437  */         
    496438};
    497 #endif
     439
    498440
    499441static int sh_kern_kmem_read (int fd, unsigned long addr,
     
    540482}
    541483
    542 int sh_kern_check_internal ()
     484
     485static int check_init (int * init_retval)
    543486{
    544487  static int is_init = 0;
    545   int kd;
    546   int res;
    547   pid_t mpid;
    548   int mpipe[2];
    549   int i, j, status = 0;
    550   /* unsigned int kaddr; */
    551   unsigned long kmem_call_table[512];
    552 
    553 #ifdef SH_PROC_CHECK
    554   struct inode_operations proc_root_inode;
    555   struct proc_dir_entry proc_root_dir;
    556 #endif
    557 
    558 #ifdef SH_SYSCALL_CODE
    559   unsigned int kmem_code_table[512][2];
    560 #endif
    561 #ifdef SH_IDT_TABLE
     488
     489  SL_ENTER(_("check_init"));
     490
     491  if (is_init == 0)
     492    {
     493      if (sh.flag.checkSum != SH_CHECK_INIT && sh.flag.update != S_TRUE)
     494        {
     495          if (0 == sh_kern_data_init()) {
     496            is_init = 1;
     497          } else {
     498            sh_error_handle (ShKernSeverity, FIL__, __LINE__, 1,
     499                             MSG_E_SUBGEN,
     500                             _("could not initialize kernel check - switching off"),
     501                             _("check_init") );
     502            ShKernActive = S_FALSE;
     503            *init_retval = is_init;
     504            SL_RETURN( (-1), _("check_init"));
     505          }
     506        }
     507      else if ((sh.flag.checkSum == SH_CHECK_INIT ||
     508                sh.flag.checkSum == SH_CHECK_CHECK) &&
     509               (sh.flag.update == S_TRUE))
     510        {
     511          if (0 == sh_kern_data_init()) {
     512            is_init = 1;
     513          } else {
     514            sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, 0,
     515                             MSG_E_SUBGEN,
     516                             _("no or incomplete data in baseline database for kernel check"),
     517                             _("check_init") );
     518          }
     519        }
     520    }
     521  *init_retval = is_init;
     522  SL_RETURN( (0), _("check_init"));
     523}
     524
     525#define SH_KERN_SIZ 512
     526#define SH_KERN_SCC 256
     527
     528static void run_child(int kd, int mpipe[2])
     529{
     530  int j;
     531
     532  unsigned long kmem_call_table[SH_KERN_SIZ];
     533  unsigned int  kmem_code_table[SH_KERN_SIZ][2];
     534
    562535  unsigned char  buf[6];
    563536  unsigned short idt_size;
    564537  unsigned long  idt_addr;
    565   /* int            k, curr_keep = 0; */
     538
     539  unsigned char new_system_call_code[SH_KERN_SCC];
     540
     541  struct inode_operations proc_root_inode;
     542  struct proc_dir_entry   proc_root_dir;
     543
     544  int status = close(mpipe[0]);
     545
     546  setpgid(0, 0);
     547         
     548  /* Seek to the system call table (at kaddr) and read it into
     549   * the kmem_call_table array
     550   */
     551  if(status == 0)
     552    {
     553      retry_msleep (0, ShKernDelay); /* milliseconds */
     554     
     555      if (sh_kern_read_data (kd, kaddr,
     556                             (unsigned char *) &kmem_call_table,
     557                             sizeof(kmem_call_table)))
     558        {
     559          status = -2;
     560        }
     561    }
     562
     563  /*
     564   * Seek to the system call address (at sh_syscalls[j].addr) and
     565   * read first 8 bytes into the array kmem_code_table[j][] (2 * unsigned int)
     566   */
     567  if(status == 0)
     568    {
     569      memset(kmem_code_table, 0, sizeof(kmem_code_table));
     570      for (j = 0; j < SH_MAXCALLS; ++j)
     571        {
     572          if (sh_syscalls[j].addr == 0UL) {
     573            sh_syscalls[j].addr = kmem_call_table[j];
     574          }
     575
     576          if (sh_syscalls[j].name == NULL ||
     577              sh_syscalls[j].addr == 0UL)
     578            break;
     579
     580          if ((sh.flag.checkSum == SH_CHECK_INIT ||
     581               sh.flag.checkSum == SH_CHECK_CHECK) &&
     582              (sh.flag.update == S_TRUE))
     583            {
     584              sh_kern_read_data (kd, kmem_call_table[j],
     585                                 (unsigned char *) &(kmem_code_table[j][0]),
     586                                 2 * sizeof(unsigned int));
     587            }
     588          else
     589            {
     590              sh_kern_read_data (kd, sh_syscalls[j].addr,
     591                                 (unsigned char *) &(kmem_code_table[j][0]),
     592                                 2 * sizeof(unsigned int));
     593            }
     594        }
     595    }
     596
     597  if(status == 0)
     598    {
     599      /*
     600       * Get the address and size of Interrupt Descriptor Table,
     601       * and read the content into the global array sh_idt_table[]
     602       */
     603      __asm__ volatile ("sidt %0": "=m" (buf));
     604      idt_size = *((unsigned short *) &buf[0]);
     605      idt_addr = *((unsigned long *)  &buf[2]);
     606      idt_size = (idt_size + 1)/8;
     607     
     608      if (idt_size > SH_MAXIDT)
     609        idt_size = SH_MAXIDT;
     610     
     611      memset(sh_idt_table, '\0', SH_MAXIDT*8);
     612      sh_kern_read_data (kd, idt_addr,
     613                         (unsigned char *) sh_idt_table, idt_size*8);
     614    }
     615
     616  /*
     617   * Seek to the system_call address (at system_call_addr) and
     618   * read first 256 bytes into new_system_call_code[]
     619   *
     620   * system_call_addr is defined in the include file.
     621   */
     622  if(status == 0)
     623    {
     624      sh_kern_read_data (kd, system_call_addr,
     625                         (unsigned char *) new_system_call_code, SH_KERN_SCC);
     626    }
     627 
     628  /*
     629   * Seek to proc_root and read the structure.
     630   * Seek to proc_root_inode_operations and get the structure.
     631   */
     632  if(status == 0)
     633    {
     634      sh_kern_read_data (kd, proc_root,
     635                         (unsigned char *) &proc_root_dir,
     636                         sizeof(proc_root_dir));
     637      sh_kern_read_data (kd, proc_root_iops,
     638                         (unsigned char *) &proc_root_inode,
     639                         sizeof(proc_root_inode));
     640    }
     641 
     642  /*
     643   * Write out data to the pipe
     644   */
     645  if(status == 0)
     646    {
     647      status = write(mpipe[1], &kmem_call_table, sizeof(kmem_call_table));
     648
     649      if(status > 0)
     650        status = write(mpipe[1], &kmem_code_table, sizeof(kmem_code_table));
     651
     652      if(status > 0)
     653        status = write(mpipe[1], &sh_idt_table, sizeof(sh_idt_table));
     654
     655      if(status > 0)
     656        status = write(mpipe[1], new_system_call_code, SH_KERN_SCC);
     657
     658      if(status > 0)
     659        status = write(mpipe[1], &proc_root_dir, sizeof(proc_root_dir));
     660
     661      if(status > 0)
     662        status = write(mpipe[1], &proc_root_inode, sizeof(proc_root_inode));
     663    }
     664  _exit( (status >= 0) ? 0 : status);
     665}
     666
     667
     668struct sh_kernel_info {
     669  unsigned long kmem_call_table[SH_KERN_SIZ];
     670  unsigned int  kmem_code_table[SH_KERN_SIZ][2];
     671
     672  unsigned char new_system_call_code[SH_KERN_SCC];
     673
     674  struct inode_operations proc_root_inode;
     675  struct proc_dir_entry   proc_root_dir;
     676};
     677
     678static int read_from_child(pid_t mpid, int * mpipe,
     679                           struct sh_kernel_info * kinfo)
     680{
     681  int  res;
     682  int  status;
     683  long size;
     684
     685  /* Close reading side of pipe, and wait some milliseconds
     686   */
     687  close (mpipe[1]);
     688  retry_msleep (0, ShKernDelay); /* milliseconds */
     689
     690  size = SH_KERN_SIZ * sizeof(unsigned long);
     691
     692  if (size != read(mpipe[0], &(kinfo->kmem_call_table), size))
     693    status = -4;
     694  else
     695    status = 0;
     696
     697  if(status == 0)
     698    {
     699      size = sizeof(unsigned int) * 2 * SH_KERN_SIZ;
     700
     701      if (size != read(mpipe[0], &(kinfo->kmem_code_table), size))
     702        status = -5;
     703      else
     704        status = 0;
     705    }
     706
     707  if(status == 0)
     708    {
     709      memset(sh_idt_table, '\0', SH_MAXIDT*8);
     710      if (sizeof(sh_idt_table) !=
     711          read(mpipe[0], &sh_idt_table, sizeof(sh_idt_table)))
     712        status = -5;
     713      else
     714        status = 0;
     715    }
     716
     717  if(status == 0)
     718    {
     719      size = SH_KERN_SCC;
     720
     721      if (size != read(mpipe[0], &(kinfo->new_system_call_code), size))
     722        status = -6;
     723      else
     724        status = 0;
     725    }
     726 
     727  if(status == 0)
     728    {
     729      size = sizeof (struct proc_dir_entry);
     730
     731      if (size != read(mpipe[0], &(kinfo->proc_root_dir), size))
     732        status = -7;
     733      else
     734        status = 0;
     735    }
     736
     737  if(status == 0)
     738    {
     739      size = sizeof (struct inode_operations);
     740
     741      if (size != read(mpipe[0], &(kinfo->proc_root_inode), size))
     742        status = -8;
     743      else
     744        status = 0;
     745    }
     746
     747  if (status < 0)
     748    res = waitpid(mpid, NULL,    WNOHANG|WUNTRACED);
     749  else
     750    {
     751      res = waitpid(mpid, &status, WNOHANG|WUNTRACED);
     752      if (res == 0 && 0 != WIFEXITED(status))
     753        status = WEXITSTATUS(status);
     754    }
     755  close (mpipe[0]);
     756  if (res <= 0)
     757    {
     758      aud_kill(FIL__, __LINE__, mpid, 9);
     759      waitpid(mpid, NULL, 0);
     760    }
     761  return status;
     762}
     763
     764
     765static void check_idt_table(int is_init)
     766{
     767  int            i, j;
     768
    566769  unsigned short idt_offset_lo, idt_offset_hi, idt_selector;
    567770  unsigned char  idt_reserved, idt_flag;
     
    573776  unsigned long  sh_idt_iaddr;
    574777  char           idt_type, sh_idt_type;
    575 #endif
    576 
    577   unsigned char new_system_call_code[256];
    578 
    579 #ifdef SH_USE_LKM
    580   static int check_getdents      = 0;
    581   /* #ifdef __NR_getdents64 */
    582   static int check_getdents64    = 0;
    583   /* #endif */
    584   static int copy_if_next        = -1;
    585   static int copy_if_next_64     = -1;
    586 #endif
    587778
    588779  unsigned long store0;
    589780  unsigned int  store1, store2;
    590781  int           datasize;
    591   int           mod_syscall_addr = 0;
    592   int           mod_syscall_code = 0;
    593   UINT64        size_old  = 0, size_new = 0;
    594   UINT64        mtime_old = 0, mtime_new = 0;
    595   UINT64        ctime_old = 0, ctime_new = 0;
    596   char          tmp[128];
    597782  char          msg[2*SH_BUFSIZE];
    598   char timstr_o[32];
    599   char timstr_n[32];
    600   char * p;
    601   int    k;
    602   char * linkpath_old;
    603   char * linkpath_new;
    604 
    605   int           max_system_call = (SYS_CALL_LOC < 128) ? 128 : SYS_CALL_LOC;
    606 
    607   SL_ENTER(_("sh_kern_check_internal"));
    608 
    609  
    610   if (is_init == 0)
    611     {
    612       if (sh.flag.checkSum != SH_CHECK_INIT && sh.flag.update != S_TRUE)
    613         {
    614           if (0 == sh_kern_data_init()) {
    615             is_init = 1;
    616           } else {
    617             sh_error_handle (ShKernSeverity, FIL__, __LINE__, status,
    618                              MSG_E_SUBGEN,
    619                              _("could not initialize - switching off"),
    620                              _("kern_check_internal") );
    621             ShKernActive = S_FALSE;
    622             SL_RETURN( (-1), _("sh_kern_check_internal"));
    623           }
    624         }
    625       else if ((sh.flag.checkSum == SH_CHECK_INIT ||
    626                 sh.flag.checkSum == SH_CHECK_CHECK) &&
    627                (sh.flag.update == S_TRUE))
    628         {
    629           if (0 == sh_kern_data_init()) {
    630             is_init = 1;
    631           } else {
    632             sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, status,
    633                              MSG_E_SUBGEN,
    634                              _("no or incomplete data in baseline database"),
    635                              _("kern_check_internal") );
    636           }
    637         }
    638     }
    639 
    640   /*
    641    * kaddr is the address of the sys_call_table
    642    */
    643 
    644   if (kaddr == (unsigned int) -1)
    645     {
    646       sh_error_handle (ShKernSeverity, FIL__, __LINE__, status, MSG_E_SUBGEN,
    647                        _("no address for sys_call_table - switching off"),
    648                        _("kern_check_internal") );
    649       ShKernActive = S_FALSE;
    650       SL_RETURN( (-1), _("sh_kern_check_internal"));
    651     }
    652  
    653   kd = aud_open(FIL__, __LINE__, SL_YESPRIV, _("/dev/kmem"), O_RDONLY, 0);
    654  
    655   if (kd < 0)
    656     {
    657       status = errno;
    658       sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
    659                        _("error opening /dev/kmem"),
    660                        _("kern_check_internal") );
    661       SL_RETURN( (-1), _("sh_kern_check_internal"));
    662     }
    663 
    664   status = aud_pipe(FIL__, __LINE__, mpipe);
    665 
    666   if (status == 0)
    667     {
    668       mpid = aud_fork(FIL__, __LINE__);
    669 
    670       switch (mpid)
    671         {
    672         case -1:
    673           status = -1;
    674           break;
    675         case 0:                       /* child */
    676           status = close(mpipe[0]);
    677           setpgid(0, 0);
    678          
    679           /* Seek to the system call table (at kaddr) and read it into
    680            * the kmem_call_table array
    681            */
    682           if(status == 0)
    683             {
    684               retry_msleep (0, ShKernDelay); /* milliseconds */
    685              
    686               if (sh_kern_read_data (kd, kaddr,
    687                                      (unsigned char *) &kmem_call_table,
    688                                      sizeof(kmem_call_table)))
    689                 {
    690                   status = -2;
    691                 }
    692             }
    693 
    694 #ifdef SH_SYSCALL_CODE
    695           /*
    696            * Seek to the system call address (at sh_syscalls[j].addr) and
    697            * read first 8 bytes into kmem_code_table[j][] (2 * unsigned int)
    698            */
    699           if(status == 0)
    700             {
    701               memset(kmem_code_table, 0, sizeof(kmem_code_table));
    702               for (j = 0; j < SH_MAXCALLS; ++j)
    703                 {
    704 
    705                   if (sh_syscalls[j].addr == 0UL) {
    706                     sh_syscalls[j].addr = kmem_call_table[j];
    707                   }
    708 
    709                   if (sh_syscalls[j].name == NULL ||
    710                       sh_syscalls[j].addr == 0UL)
    711                     break;
    712 
    713                   if ((sh.flag.checkSum == SH_CHECK_INIT ||
    714                        sh.flag.checkSum == SH_CHECK_CHECK) &&
    715                       (sh.flag.update == S_TRUE))
    716                     {
    717                       sh_kern_read_data (kd, kmem_call_table[j],
    718                                          (unsigned char *) &(kmem_code_table[j][0]),
    719                                          2 * sizeof(unsigned int));
    720                     }
    721                   else
    722                     {
    723                       sh_kern_read_data (kd, sh_syscalls[j].addr,
    724                                          (unsigned char *) &(kmem_code_table[j][0]),
    725                                          2 * sizeof(unsigned int));
    726                     }
    727                 }
    728             }
    729 #endif
    730 
    731 #ifdef SH_IDT_TABLE
    732           if(status == 0)
    733             {
    734               /*
    735                * Get the address and size of Interrupt Descriptor Table,
    736                * and read the content into sh_idt_table[]
    737                */
    738               __asm__ volatile ("sidt %0": "=m" (buf));
    739               idt_size = *((unsigned short *) &buf[0]);
    740               idt_addr = *((unsigned long *)  &buf[2]);
    741               idt_size = (idt_size + 1)/8;
    742 
    743               if (idt_size > SH_MAXIDT)
    744                 idt_size = SH_MAXIDT;
    745 
    746               memset(sh_idt_table, '\0', SH_MAXIDT*8);
    747               sh_kern_read_data (kd, idt_addr,
    748                                  (unsigned char *) sh_idt_table, idt_size*8);
    749             }
    750 #endif
    751 
    752           /*
    753            * Seek to the system_call address (at system_call_addr) and
    754            * read first 256 bytes into new_system_call_code[]
    755            *
    756            * system_call_addr is defined in the include file.
    757            */
    758           if(status == 0)
    759             {
    760               sh_kern_read_data (kd, system_call_addr,
    761                                  (unsigned char *) new_system_call_code, 256);
    762             }
    763 
    764 
    765           /*
    766            * Seek to proc_root and read the structure.
    767            * Seek to proc_root_inode_operations and get the structure.
    768            */
    769 #ifdef SH_PROC_CHECK
    770           if(status == 0)
    771             {
    772               sh_kern_read_data (kd, proc_root,
    773                                  (unsigned char *) &proc_root_dir,
    774                                  sizeof(proc_root_dir));
    775               sh_kern_read_data (kd, proc_root_iops,
    776                                  (unsigned char *) &proc_root_inode,
    777                                  sizeof(proc_root_inode));
    778             }
    779 #endif
    780 
    781           if(status == 0)
    782             {
    783               status =
    784                 write(mpipe[1], &kmem_call_table, sizeof(kmem_call_table));
    785 #ifdef SH_SYSCALL_CODE
    786               if(status > 0)
    787                 {
    788                   status =
    789                     write(mpipe[1], &kmem_code_table, sizeof(kmem_code_table));
    790                 }
    791 #endif
    792 #ifdef SH_IDT_TABLE
    793               if(status > 0)
    794                 {
    795                   status =
    796                     write(mpipe[1], &sh_idt_table, sizeof(sh_idt_table));
    797                 }
    798 #endif
    799               if(status > 0)
    800                 {
    801                   status =
    802                     write(mpipe[1], new_system_call_code, 256);
    803                 }
    804 #ifdef SH_PROC_CHECK
    805               if(status > 0)
    806                 {
    807                   status =
    808                     write(mpipe[1], &proc_root_dir, sizeof(proc_root_dir));
    809                 }
    810               if(status > 0)
    811                 {
    812                   status =
    813                     write(mpipe[1], &proc_root_inode, sizeof(proc_root_inode));
    814                 }
    815 #endif
    816             }
    817           _exit( (status >= 0) ? 0 : status);
    818           break;
    819          
    820         default:
    821           close (mpipe[1]);
    822           close (kd);
    823           retry_msleep (0, ShKernDelay); /* milliseconds */
    824           if (sizeof(kmem_call_table) !=
    825               read(mpipe[0], &kmem_call_table, sizeof(kmem_call_table)))
    826             status = -4;
    827           else
    828             status = 0;
    829 
    830 #ifdef SH_SYSCALL_CODE
    831           if(status == 0)
    832             {
    833               if (sizeof(kmem_code_table) !=
    834                   read(mpipe[0], &kmem_code_table, sizeof(kmem_code_table)))
    835                 status = -5;
    836               else
    837                 status = 0;
    838             }
    839 #endif   
    840 
    841 #ifdef SH_IDT_TABLE
    842           if(status == 0)
    843             {
    844               memset(sh_idt_table, '\0', SH_MAXIDT*8);
    845               if (sizeof(sh_idt_table) !=
    846                   read(mpipe[0], &sh_idt_table, sizeof(sh_idt_table)))
    847                 status = -5;
    848               else
    849                 status = 0;
    850             }
    851 #endif   
    852 
    853           if(status == 0)
    854             {
    855               if (256 != read(mpipe[0], new_system_call_code, 256))
    856                 status = -6;
    857               else
    858                 status = 0;
    859             }
    860 
    861 #ifdef SH_PROC_CHECK
    862           if(status == 0)
    863             {
    864               if (sizeof(proc_root_dir) !=
    865                   read(mpipe[0], &proc_root_dir, sizeof(proc_root_dir)))
    866                 status = -7;
    867               else
    868                 status = 0;
    869             }
    870           if(status == 0)
    871             {
    872               if (sizeof(proc_root_inode) !=
    873                   read(mpipe[0], &proc_root_inode, sizeof(proc_root_inode)))
    874                 status = -8;
    875               else
    876                 status = 0;
    877             }
    878 #endif
    879 
    880           if (status < 0)
    881             res = waitpid(mpid, NULL,    WNOHANG|WUNTRACED);
    882           else
    883             {
    884               res = waitpid(mpid, &status, WNOHANG|WUNTRACED);
    885               if (res == 0 && 0 != WIFEXITED(status))
    886                 status = WEXITSTATUS(status);
    887             }
    888           close (mpipe[0]);
    889           if (res <= 0)
    890             {
    891               aud_kill(FIL__, __LINE__, mpid, 9);
    892               waitpid(mpid, NULL, 0);
    893             }
    894           break;
    895         }
    896     }
    897 
    898   if ( status < 0)
    899     {
    900       sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
    901                        _("error reading from /dev/kmem"),
    902                        _("kern_check_internal") );
    903       SL_RETURN( (-1), _("sh_kern_check_internal"));
    904     }
    905 
    906   /* Check the proc_root inode.
    907    *
    908    * This will detect adore-ng.
    909    */
    910   if ( (unsigned int) *proc_root_inode.lookup != proc_root_lookup)
    911     {
    912       sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_KERN_PROC,
    913                        _("proc_root_inode_operations.lookup != proc_root_lookup"));
    914     }
    915   else if (    (((unsigned int) * &proc_root_dir.proc_iops) != proc_root_iops)
    916             && (proc_root_dir.size != proc_root_iops)
    917             && (((unsigned int) * &proc_root_dir.proc_fops) != proc_root_iops)
    918             )
    919     {
    920       sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_KERN_PROC,
    921                        _("proc_root.proc_iops != proc_root_inode_operations"));
    922     }
    923 
    924   /* Check the system_call syscall gate.
    925    *
    926    * Stored(old) is system_call_code[]
    927    */
    928   if (sh.flag.checkSum == SH_CHECK_INIT || sh.flag.update == S_TRUE)
    929     {
    930       store0 = 0; store1 = 0; store2 = 0;
    931       datasize = sizeof(system_call_code);
    932       sh_kern_db_syscall (0, _("system_call"),
    933                           new_system_call_code, &store0, &store1, &store2,
    934                           &datasize, 0);
    935     }
    936 
    937   if ((sh.flag.checkSum != SH_CHECK_INIT) ||
    938       (sh.flag.update == S_TRUE && is_init == 1))
    939     {
    940       for (i = 0; i < (max_system_call + 4); ++i)
    941         {
    942           if (system_call_code[i] != new_system_call_code[i])
    943             {
    944 #ifdef SH_USE_XML
    945               sl_snprintf(tmp, 128, "path=\"K_%s_%04d\" ",
    946                           _("system_call"), 0);
    947 #else
    948               sl_snprintf(tmp, 128, "path=<K_%s_%04d>, ",
    949                           _("system_call"), 0);
    950 #endif
    951               sl_strlcpy(msg, tmp, SH_BUFSIZE);
    952 
    953               linkpath_old = SH_ALLOC(520);
    954               linkpath_new = SH_ALLOC(520);
    955               for (k = 0; k < 256; ++k)
    956                 {
    957                   p = sh_kern_charhex (system_call_code[k]);
    958                   linkpath_old[2*k]   = p[0];
    959                   linkpath_old[2*k+1] = p[1];
    960                   linkpath_old[2*k+2] = '\0';
    961                 }
    962               for (k = 0; k < 256; ++k)
    963                 {
    964                   p = sh_kern_charhex (new_system_call_code[k]);
    965                   linkpath_new[2*k]   = p[0];
    966                   linkpath_new[2*k+1] = p[1];
    967                   linkpath_new[2*k+2] = '\0';
    968                 }
    969 #ifdef SH_USE_XML
    970               sl_strlcat(msg, _("link_old=\""),    2*SH_BUFSIZE);
    971               sl_strlcat(msg, linkpath_old,        2*SH_BUFSIZE);
    972               sl_strlcat(msg, _("\" link_new=\""), 2*SH_BUFSIZE);
    973               sl_strlcat(msg, linkpath_new,        2*SH_BUFSIZE);
    974               sl_strlcat(msg, _("\""),             2*SH_BUFSIZE);
    975 #else
    976               sl_strlcat(msg, _("link_old=<"),     2*SH_BUFSIZE);
    977               sl_strlcat(msg, linkpath_old,        2*SH_BUFSIZE);
    978               sl_strlcat(msg, _(">, link_new=<"),   2*SH_BUFSIZE);
    979               sl_strlcat(msg, linkpath_new,        2*SH_BUFSIZE);
    980               sl_strlcat(msg, _(">"),              2*SH_BUFSIZE);
    981 #endif
    982 
    983               sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    984                                status, MSG_KERN_GATE,
    985                                new_system_call_code[i], 0,
    986                                system_call_code[i], 0,
    987                                0, _("system_call (interrupt handler)"),
    988                                msg);
    989              
    990               SH_FREE(linkpath_old);
    991               SH_FREE(linkpath_new);
    992 
    993               for (j = 0; j < (max_system_call + 4); ++j)
    994                 system_call_code[j] = new_system_call_code[j];
    995               break;
    996             }
    997         }
    998     }
    999  
    1000   /* Check the individual syscalls
    1001    *
    1002    * Stored(old) is sh_syscalls[] array.
    1003    */
    1004   if (sh.flag.checkSum == SH_CHECK_INIT || sh.flag.update == S_TRUE)
    1005     {
    1006       for (i = 0; i < SH_MAXCALLS; ++i)
    1007         {
    1008           store0 = kmem_call_table[i];
    1009 #ifdef SH_SYSCALL_CODE
    1010           store1 = kmem_code_table[i][0]; store2 = kmem_code_table[i][1];
    1011 #else
    1012           store1 = 0; store2 = 0;
    1013 #endif
    1014           sh_kern_db_syscall (i, _("syscall"),
    1015                               NULL, &store0, &store1, &store2,
    1016                               0, 0);
    1017         }
    1018     }
    1019 
    1020   if ((sh.flag.checkSum != SH_CHECK_INIT) ||
    1021       (sh.flag.update == S_TRUE && is_init == 1))
    1022     {
    1023       for (i = 0; i < SH_MAXCALLS; ++i)
    1024         {
    1025           if (sh_syscalls[i].name == NULL /* || sh_syscalls[i].addr == 0UL */)
    1026             break;
    1027 
    1028 #ifdef SH_USE_LKM
    1029           if (sh_syscalls[i].addr != kmem_call_table[i])
    1030             {
    1031               if (check_getdents == 0 &&
    1032                   0 == strcmp(_(sh_syscalls[i].name), _("sys_getdents")))
    1033                 {
    1034                   check_getdents = 1;
    1035                   sh_error_handle (SH_ERR_WARN, FIL__, __LINE__,
    1036                                    status, MSG_E_SUBGEN,
    1037                                    _("Modified kernel syscall (expected)."),
    1038                                    _(sh_syscalls[i].name) );
    1039                   copy_if_next = i;
    1040                   sh_syscalls[i].addr = kmem_call_table[i];
    1041                   continue;
    1042                 }
    1043               /* #ifdef __NR_getdents64 */
    1044               else if  (check_getdents64 == 0 &&
    1045                         0 == strcmp(_(sh_syscalls[i].name),
    1046                                     _("sys_getdents64")))
    1047                 {
    1048                   check_getdents64 = 1;
    1049                   sh_error_handle (SH_ERR_WARN, FIL__, __LINE__,
    1050                                    status, MSG_E_SUBGEN,
    1051                                    _("Modified kernel syscall (expected)."),
    1052                                    _(sh_syscalls[i].name) );
    1053                   copy_if_next_64 = i;
    1054                   sh_syscalls[i].addr = kmem_call_table[i];
    1055                   continue;
    1056                 }
    1057               /* #endif */
    1058               else
    1059                 {
    1060                   size_old = sh_syscalls[i].addr;
    1061                   size_new = kmem_call_table[i];
    1062                   mod_syscall_addr = 1;
    1063                   /*
    1064                   sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    1065                                    status, MSG_KERN_POLICY,
    1066                                    kmem_call_table[i],
    1067                                    sh_syscalls[i].addr,
    1068                                    i, _(sh_syscalls[i].name)
    1069                                    );
    1070                   */
    1071                 }
    1072               sh_syscalls[i].addr = kmem_call_table[i];
    1073             }
    1074 #else
    1075           if (sh_syscalls[i].addr != kmem_call_table[i])
    1076             {
    1077               size_old = sh_syscalls[i].addr;
    1078               size_new = kmem_call_table[i];
    1079               mod_syscall_addr = 1;
    1080               /*
    1081               sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    1082                                status, MSG_KERN_POLICY,
    1083                                kmem_call_table[i],
    1084                                sh_syscalls[i].addr,
    1085                                i, _(sh_syscalls[i].name)
    1086                                );
    1087               */
    1088               sh_syscalls[i].addr = kmem_call_table[i];
    1089             }
    1090 #endif
    1091 
    1092 
    1093           /* Check the code at syscall address
    1094            *
    1095            * Stored(old) is sh_syscalls[]
    1096            */
    1097 #ifdef SH_SYSCALL_CODE
    1098           if ( (mod_syscall_addr == 0) &&
    1099                ((sh_syscalls[i].code[0] != kmem_code_table[i][0]) ||
    1100                 (sh_syscalls[i].code[1] != kmem_code_table[i][1]))
    1101                )
    1102             {
    1103               mtime_old = sh_syscalls[i].code[0];
    1104               mtime_new = kmem_code_table[i][0];
    1105               ctime_old = sh_syscalls[i].code[1];
    1106               ctime_new = kmem_code_table[i][1];
    1107               mod_syscall_code = 1;
    1108 
    1109 #ifdef SH_USE_LKM
    1110               if (i == copy_if_next)
    1111                 {
    1112                   mod_syscall_code =  0;
    1113                   copy_if_next     = -1;
    1114                 }
    1115               if (i == copy_if_next_64)
    1116                 {
    1117                   mod_syscall_code =  0;
    1118                   copy_if_next_64  = -1;
    1119                 }
    1120 #endif
    1121 
    1122               /*
    1123               sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    1124                                status, MSG_KERN_POL_CO,
    1125                                kmem_code_table[i][0],  kmem_code_table[i][1],
    1126                                sh_syscalls[i].code[0], sh_syscalls[i].code[1],
    1127                                i, _(sh_syscalls[i].name)
    1128                                );
    1129               */
    1130               sh_syscalls[i].code[0] = kmem_code_table[i][0];
    1131               sh_syscalls[i].code[1] = kmem_code_table[i][1];
    1132             }
    1133 #endif
    1134           /*
    1135            * Build the error message, if something has been
    1136            * detected.
    1137            */
    1138           if ((mod_syscall_addr != 0) || (mod_syscall_code != 0))
    1139             {
    1140 #ifdef SH_USE_XML
    1141               sl_snprintf(tmp, 128, "path=\"K_%s_%04d\" ",
    1142                           _("syscall"), i);
    1143 #else
    1144               sl_snprintf(tmp, 128, "path=<K_%s_%04d>, ",
    1145                           _("syscall"), i);
    1146 #endif
    1147               sl_strlcpy(msg, tmp, SH_BUFSIZE);
    1148 
    1149               if (mod_syscall_addr != 0)
    1150                 {
    1151                   sl_snprintf(tmp, 128, sh_hash_size_format(),
    1152                               size_old, size_new);
    1153                   sl_strlcat(msg, tmp, SH_BUFSIZE);
    1154                 }
    1155               if (mod_syscall_code != 0)
    1156                 {
    1157                   sl_strlcpy (timstr_o, sh_unix_gmttime (ctime_old), 32);
    1158                   sl_strlcpy (timstr_n, sh_unix_gmttime (ctime_new), 32);
    1159 #ifdef SH_USE_XML
    1160                   sl_snprintf(tmp, 128,
    1161                               _("ctime_old=\"%s\" ctime_new=\"%s\" "),
    1162                               timstr_o, timstr_n);
    1163 #else
    1164                   sl_snprintf(tmp, 128,
    1165                               _("ctime_old=<%s>, ctime_new=<%s>, "),
    1166                               timstr_o, timstr_n);
    1167 #endif
    1168                   sl_strlcat(msg, tmp, SH_BUFSIZE);
    1169                   sl_strlcpy (timstr_o, sh_unix_gmttime (mtime_old), 32);
    1170                   sl_strlcpy (timstr_n, sh_unix_gmttime (mtime_new), 32);
    1171 #ifdef SH_USE_XML
    1172                   sl_snprintf(tmp, 128,
    1173                               _("mtime_old=\"%s\" mtime_new=\"%s\" "),
    1174                               timstr_o, timstr_n);
    1175 #else
    1176                   sl_snprintf(tmp, 128,
    1177                               _("mtime_old=<%s>, mtime_new=<%s> "),
    1178                               timstr_o, timstr_n);
    1179 #endif
    1180                   sl_strlcat(msg, tmp, SH_BUFSIZE);
    1181                 }
    1182               sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    1183                                status, MSG_KERN_SYSCALL,
    1184                                i, _(sh_syscalls[i].name), msg);
    1185               mod_syscall_addr = 0;
    1186               mod_syscall_code = 0;
    1187             }
    1188         }
    1189     }
    1190 
    1191 #ifdef SH_IDT_TABLE
     783
    1192784  if (ShKernIDT == S_TRUE)
    1193785    {
     
    1200792                                  &sh_idt_table[j*8],
    1201793                                  &store0, &store1, &store2,
    1202                                   &datasize, 0);
     794                                  &datasize, SH_KERN_DBPUSH);
    1203795            }
    1204796        }
     
    1275867                  else { sh_dpl = -1; sh_idt_type = 'U'; }
    1276868                 
    1277 #ifdef SH_USE_XML
    1278                   sl_snprintf(tmp, 128, "path=\"K_%s_%04d\" ",
    1279                               _("idt_table"), j);
    1280 #else
    1281                   sl_snprintf(tmp, 128, "path=<K_%s_%04d> ",
    1282                               _("idt_table"), j);
    1283 #endif
    1284                   sl_strlcpy(msg, tmp, SH_BUFSIZE);
    1285 
    1286                   linkpath_old = SH_ALLOC(32);
    1287                   linkpath_new = SH_ALLOC(32);
    1288                   for (k = 0; k < 8; ++k)
    1289                     {
    1290                       p = sh_kern_charhex (idt_table[i+k]);
    1291                       linkpath_old[2*k]   = p[0];
    1292                       linkpath_old[2*k+1] = p[1];
    1293                       linkpath_old[2*k+2] = '\0';
    1294                     }
    1295                   for (k = 0; k < 8; ++k)
    1296                     {
    1297                       p = sh_kern_charhex (sh_idt_table[i+k]);
    1298                       linkpath_new[2*k]   = p[0];
    1299                       linkpath_new[2*k+1] = p[1];
    1300                       linkpath_new[2*k+2] = '\0';
    1301                     }
    1302 #ifdef SH_USE_XML
    1303                   sl_snprintf(tmp, 128,
    1304                               _("link_old=\"%s\" link_new=\"%s\" "),
    1305                               linkpath_old, linkpath_new);
    1306 #else
    1307                   sl_snprintf(tmp, 128,
    1308                               _("link_old=<%s> link_new=<%s> "),
    1309                               linkpath_old, linkpath_new);
    1310 #endif
    1311                   sl_strlcat(msg, tmp, SH_BUFSIZE);
     869                  sh_kern_pathmsg (msg, SH_BUFSIZE,
     870                                   j, _("idt_table"),
     871                                   &idt_table[i], 8,
     872                                   &sh_idt_table[i], 8);
    1312873
    1313874                  sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    1314                                    status, MSG_KERN_IDT,
     875                                   0, MSG_KERN_IDT,
    1315876                                   j,
    1316877                                   sh_idt_iaddr, sh_strseg(sh_idt_selector),
     
    1319880                                   (int) dpl, idt_type, msg);
    1320881                 
    1321                   SH_FREE(linkpath_old);
    1322                   SH_FREE(linkpath_new);
    1323 
    1324882                  memcpy(&idt_table[i], &sh_idt_table[i], 8);
    1325883                }
     
    1327885        }
    1328886    }
    1329 #endif
     887}
     888
     889
     890#define SYS_BUS_PCI _("/sys/bus/pci/devices")
     891#include <dirent.h>
     892
     893static void check_rom (char * pcipath, char * name)
     894{
     895  file_type       theFile;
     896  char            fileHash[2*(KEY_LEN + 1)];
     897  int             status;
     898  char          * tmp;
     899  extern unsigned long sh_files_maskof (int class);
     900
     901  (void) sl_strlcpy (theFile.fullpath, pcipath, PATH_MAX);
     902  theFile.check_mask  = sh_files_maskof(SH_LEVEL_READONLY);
     903  theFile.reported    = S_FALSE;
     904  theFile.attr_string = NULL;
     905 
     906  status = sh_unix_getinfo (ShDFLevel[SH_ERR_T_RO],
     907                            name, &theFile, fileHash, 0);
     908
     909  if (status != 0)
     910    {
     911      tmp = sh_util_safe_name(pcipath);
     912      sh_error_handle (ShKernSeverity, FIL__, __LINE__,
     913                       0, MSG_E_SUBGPATH,
     914                       _("Could not check PCI ROM"),
     915                       _("check_rom"),
     916                       tmp);
     917      SH_FREE(tmp);
     918      return;
     919    }
     920
     921  if ( sh.flag.checkSum == SH_CHECK_INIT )
     922    {
     923      sh_hash_pushdata (&theFile, fileHash);
     924    }
     925  else if (sh.flag.checkSum == SH_CHECK_CHECK )
     926    {
     927      sh_hash_compdata (SH_LEVEL_READONLY, &theFile, fileHash, NULL, -1);
     928    }
     929
     930  return;
     931}
     932
     933static void check_pci_rom (char * pcipath, char * name)
     934{
     935  struct stat buf;
     936  int         fd;
     937
     938  if (0 == stat(pcipath, &buf))
     939    {
     940      /* Need to write "1" to the file to enable the ROM. Afterwards,
     941       * write "0" to disable it.
     942       */
     943      fd = open ( pcipath, O_RDWR );
     944      write( fd, "1", 1 );
     945      close ( fd );
     946
     947      check_rom(pcipath, name);
     948
     949      fd = open ( pcipath, O_RDWR );
     950      write( fd, "0", 1 );
     951      close ( fd );
     952    }
     953  return;
     954}
     955
     956static void check_pci()
     957{
     958  char pci_dir[256];
     959  char * pcipath;
     960  DIR * df;
     961  struct dirent * entry;
     962
     963  sl_strlcpy(pci_dir, SYS_BUS_PCI, sizeof(pci_dir));
     964
     965  df = opendir(pci_dir);
     966  if (df)
     967    {
     968      while (NULL != (entry = readdir(df)))
     969        {
     970          if (0 == strcmp(entry->d_name, ".") &&
     971              0 == strcmp(entry->d_name, ".."))
     972            continue;
     973
     974          pcipath = sh_util_strconcat(pci_dir, "/",
     975                                      entry->d_name, "/rom", NULL);
     976          check_pci_rom(pcipath, entry->d_name);
     977          SH_FREE(pcipath);
     978        }
     979      closedir(df);
     980    }
     981}
     982
     983/* -- Check the proc_root inode.
     984 *
     985 * This will detect adore-ng.
     986 */
     987static void check_proc_root (struct sh_kernel_info * kinfo)
     988{
     989  struct inode_operations proc_root_inode;
     990  struct proc_dir_entry   proc_root_dir;
     991
     992  memcpy (&proc_root_inode, &(kinfo->proc_root_inode), sizeof(struct inode_operations));
     993  memcpy (&proc_root_dir,   &(kinfo->proc_root_dir),   sizeof(struct proc_dir_entry));
     994
     995  if ( (unsigned int) *proc_root_inode.lookup != proc_root_lookup)
     996    {
     997      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_KERN_PROC,
     998                       _("proc_root_inode_operations.lookup != proc_root_lookup"));
     999    }
     1000  else if (    (((unsigned int) * &proc_root_dir.proc_iops) != proc_root_iops)
     1001            && (proc_root_dir.size != proc_root_iops)
     1002            && (((unsigned int) * &proc_root_dir.proc_fops) != proc_root_iops)
     1003            )
     1004    {
     1005      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_KERN_PROC,
     1006                       _("proc_root.proc_iops != proc_root_inode_operations"));
     1007    }
     1008  return;
     1009}
     1010
     1011/* -- Check the system_call syscall gate.
     1012 *
     1013 * Stored(old) is system_call_code[]
     1014 */
     1015static void check_syscall_gate(int is_init, struct sh_kernel_info * kinfo)
     1016{
     1017  int           i, j;
     1018  unsigned long store0;
     1019  unsigned int  store1, store2;
     1020  int           datasize;
     1021  int           max_system_call = (SYS_CALL_LOC < 128) ? 128 : SYS_CALL_LOC;
     1022  char          msg[2*SH_BUFSIZE];
     1023 
     1024  if (sh.flag.checkSum == SH_CHECK_INIT || sh.flag.update == S_TRUE)
     1025    {
     1026      store0 = 0; store1 = 0; store2 = 0;
     1027      datasize = SH_KERN_SCC;
     1028      sh_kern_db_syscall (0, _("system_call"),
     1029                          &(kinfo->new_system_call_code), &store0, &store1, &store2,
     1030                          &datasize, SH_KERN_DBPUSH);
     1031    }
     1032
     1033  if ((sh.flag.checkSum != SH_CHECK_INIT) ||
     1034      (sh.flag.update == S_TRUE && is_init == 1))
     1035    {
     1036      for (i = 0; i < (max_system_call + 4); ++i)
     1037        {
     1038          if (system_call_code[i] != kinfo->new_system_call_code[i])
     1039            {
     1040
     1041              sh_kern_pathmsg (msg, sizeof(msg),
     1042                               0, _("system_call"),
     1043                               system_call_code, SH_KERN_SCC,
     1044                               kinfo->new_system_call_code, SH_KERN_SCC);
     1045
     1046              sh_error_handle (ShKernSeverity, FIL__, __LINE__,
     1047                               0, MSG_KERN_GATE,
     1048                               kinfo->new_system_call_code[i], 0,
     1049                               system_call_code[i], 0,
     1050                               0, _("system_call (interrupt handler)"),
     1051                               msg);
     1052             
     1053              for (j = 0; j < (max_system_call + 4); ++j)
     1054                system_call_code[j] = kinfo->new_system_call_code[j];
     1055              break;
     1056            }
     1057        }
     1058    }
     1059  return;
     1060}
     1061
     1062static void check_system_calls (int is_init, struct sh_kernel_info * kinfo)
     1063{
     1064  int           i;
     1065
     1066#ifdef SH_USE_LKM
     1067  static int check_getdents      = 0;
     1068  /* #ifdef __NR_getdents64 */
     1069  static int check_getdents64    = 0;
     1070  /* #endif */
     1071  static int copy_if_next        = -1;
     1072  static int copy_if_next_64     = -1;
     1073#endif
     1074
     1075  unsigned long store0;
     1076  unsigned int  store1, store2;
     1077  int           mod_syscall_addr = 0;
     1078  int           mod_syscall_code = 0;
     1079  UINT64        size_old  = 0, size_new = 0;
     1080  UINT64        mtime_old = 0, mtime_new = 0;
     1081  UINT64        ctime_old = 0, ctime_new = 0;
     1082  char          tmp[128];
     1083  char          msg[2*SH_BUFSIZE];
     1084  char timstr_o[32];
     1085  char timstr_n[32];
     1086
     1087  if (sh.flag.checkSum == SH_CHECK_INIT || sh.flag.update == S_TRUE)
     1088    {
     1089      for (i = 0; i < SH_MAXCALLS; ++i)
     1090        {
     1091          store0 = kinfo->kmem_call_table[i];
     1092          store1 = kinfo->kmem_code_table[i][0]; store2 = kinfo->kmem_code_table[i][1];
     1093          sh_kern_db_syscall (i, _("syscall"),
     1094                              NULL, &store0, &store1, &store2,
     1095                              0, SH_KERN_DBPUSH);
     1096        }
     1097    }
     1098
     1099  if ((sh.flag.checkSum != SH_CHECK_INIT) ||
     1100      (sh.flag.update == S_TRUE && is_init == 1))
     1101    {
     1102      for (i = 0; i < SH_MAXCALLS; ++i)
     1103        {
     1104          if (sh_syscalls[i].name == NULL /* || sh_syscalls[i].addr == 0UL */)
     1105            break;
     1106
     1107#ifdef SH_USE_LKM
     1108          if (sh_syscalls[i].addr != kinfo->kmem_call_table[i])
     1109            {
     1110              if (check_getdents == 0 &&
     1111                  0 == strcmp(_(sh_syscalls[i].name), _("sys_getdents")))
     1112                {
     1113                  check_getdents = 1;
     1114                  sh_error_handle (SH_ERR_WARN, FIL__, __LINE__,
     1115                                   0, MSG_E_SUBGEN,
     1116                                   _("Modified kernel syscall (expected)."),
     1117                                   _(sh_syscalls[i].name) );
     1118                  copy_if_next = i;
     1119                  sh_syscalls[i].addr = kinfo->kmem_call_table[i];
     1120                  continue;
     1121                }
     1122              /* #ifdef __NR_getdents64 */
     1123              else if  (check_getdents64 == 0 &&
     1124                        0 == strcmp(_(sh_syscalls[i].name),
     1125                                    _("sys_getdents64")))
     1126                {
     1127                  check_getdents64 = 1;
     1128                  sh_error_handle (SH_ERR_WARN, FIL__, __LINE__,
     1129                                   0, MSG_E_SUBGEN,
     1130                                   _("Modified kernel syscall (expected)."),
     1131                                   _(sh_syscalls[i].name) );
     1132                  copy_if_next_64 = i;
     1133                  sh_syscalls[i].addr = kinfo->kmem_call_table[i];
     1134                  continue;
     1135                }
     1136              /* #endif */
     1137              else
     1138                {
     1139                  size_old = sh_syscalls[i].addr;
     1140                  size_new = kinfo->kmem_call_table[i];
     1141                  mod_syscall_addr = 1;
     1142                }
     1143              sh_syscalls[i].addr = kinfo->kmem_call_table[i];
     1144            }
     1145#else
     1146          if (sh_syscalls[i].addr != kinfo->kmem_call_table[i])
     1147            {
     1148              size_old = sh_syscalls[i].addr;
     1149              size_new = kinfo->kmem_call_table[i];
     1150              mod_syscall_addr = 1;
     1151              sh_syscalls[i].addr = kinfo->kmem_call_table[i];
     1152            }
     1153#endif
     1154
     1155
     1156          /* -- Check the code at syscall address
     1157           *
     1158           * Stored(old) is sh_syscalls[]
     1159           */
     1160          if ( (mod_syscall_addr == 0) &&
     1161               ((sh_syscalls[i].code[0] != kinfo->kmem_code_table[i][0]) ||
     1162                (sh_syscalls[i].code[1] != kinfo->kmem_code_table[i][1]))
     1163               )
     1164            {
     1165              mtime_old = sh_syscalls[i].code[0];
     1166              mtime_new = kinfo->kmem_code_table[i][0];
     1167              ctime_old = sh_syscalls[i].code[1];
     1168              ctime_new = kinfo->kmem_code_table[i][1];
     1169              mod_syscall_code = 1;
     1170
     1171#ifdef SH_USE_LKM
     1172              if (i == copy_if_next)
     1173                {
     1174                  mod_syscall_code =  0;
     1175                  copy_if_next     = -1;
     1176                }
     1177              if (i == copy_if_next_64)
     1178                {
     1179                  mod_syscall_code =  0;
     1180                  copy_if_next_64  = -1;
     1181                }
     1182#endif
     1183
     1184              sh_syscalls[i].code[0] = kinfo->kmem_code_table[i][0];
     1185              sh_syscalls[i].code[1] = kinfo->kmem_code_table[i][1];
     1186            }
     1187
     1188          /* Build the error message, if something has been
     1189           * detected.
     1190           */
     1191          if ((mod_syscall_addr != 0) || (mod_syscall_code != 0))
     1192            {
     1193#ifdef SH_USE_XML
     1194              sl_snprintf(tmp, 128, "path=\"K_%s_%04d\" ",
     1195                          _("syscall"), i);
     1196#else
     1197              sl_snprintf(tmp, 128, "path=<K_%s_%04d>, ",
     1198                          _("syscall"), i);
     1199#endif
     1200              sl_strlcpy(msg, tmp, SH_BUFSIZE);
     1201
     1202              if (mod_syscall_addr != 0)
     1203                {
     1204                  sl_snprintf(tmp, 128, sh_hash_size_format(),
     1205                              size_old, size_new);
     1206                  sl_strlcat(msg, tmp, SH_BUFSIZE);
     1207                }
     1208              if (mod_syscall_code != 0)
     1209                {
     1210                  sl_strlcpy (timstr_o, sh_unix_gmttime (ctime_old), 32);
     1211                  sl_strlcpy (timstr_n, sh_unix_gmttime (ctime_new), 32);
     1212#ifdef SH_USE_XML
     1213                  sl_snprintf(tmp, 128,
     1214                              _("ctime_old=\"%s\" ctime_new=\"%s\" "),
     1215                              timstr_o, timstr_n);
     1216#else
     1217                  sl_snprintf(tmp, 128,
     1218                              _("ctime_old=<%s>, ctime_new=<%s>, "),
     1219                              timstr_o, timstr_n);
     1220#endif
     1221                  sl_strlcat(msg, tmp, SH_BUFSIZE);
     1222                  sl_strlcpy (timstr_o, sh_unix_gmttime (mtime_old), 32);
     1223                  sl_strlcpy (timstr_n, sh_unix_gmttime (mtime_new), 32);
     1224#ifdef SH_USE_XML
     1225                  sl_snprintf(tmp, 128,
     1226                              _("mtime_old=\"%s\" mtime_new=\"%s\" "),
     1227                              timstr_o, timstr_n);
     1228#else
     1229                  sl_snprintf(tmp, 128,
     1230                              _("mtime_old=<%s>, mtime_new=<%s> "),
     1231                              timstr_o, timstr_n);
     1232#endif
     1233                  sl_strlcat(msg, tmp, SH_BUFSIZE);
     1234                }
     1235              sh_error_handle (ShKernSeverity, FIL__, __LINE__,
     1236                               0, MSG_KERN_SYSCALL,
     1237                               i, _(sh_syscalls[i].name), msg);
     1238              mod_syscall_addr = 0;
     1239              mod_syscall_code = 0;
     1240            }
     1241        }
     1242    }
     1243  return;
     1244}
     1245 
     1246int sh_kern_check_internal ()
     1247{
     1248  int kd;
     1249  int is_init;
     1250  pid_t mpid;
     1251  int mpipe[2];
     1252  int status = 0;
     1253
     1254  struct sh_kernel_info kinfo;
     1255
     1256
     1257  SL_ENTER(_("sh_kern_check_internal"));
     1258
     1259  /* -- Check whether initialisation is required; if yes, initialize.
     1260   */
     1261
     1262  if (0 != check_init(&is_init))
     1263    {
     1264      SL_RETURN( (-1), _("sh_kern_check_internal"));
     1265    }
     1266
     1267
     1268  /* -- Open /dev/kmem and fork subprocess to read from it.
     1269   */
     1270   
     1271  if (kaddr == (unsigned int) -1) /* kaddr = address of the sys_call_table */
     1272    {
     1273      sh_error_handle (ShKernSeverity, FIL__, __LINE__, status, MSG_E_SUBGEN,
     1274                       _("no address for sys_call_table - switching off"),
     1275                       _("kern_check_internal") );
     1276      ShKernActive = S_FALSE;
     1277      SL_RETURN( (-1), _("sh_kern_check_internal"));
     1278    }
     1279 
     1280  kd = aud_open(FIL__, __LINE__, SL_YESPRIV, _("/dev/kmem"), O_RDONLY, 0);
     1281 
     1282  if (kd < 0)
     1283    {
     1284      status = errno;
     1285      sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
     1286                       _("error opening /dev/kmem"),
     1287                       _("kern_check_internal") );
     1288      SL_RETURN( (-1), _("sh_kern_check_internal"));
     1289    }
     1290
     1291  status = aud_pipe(FIL__, __LINE__, mpipe);
     1292
     1293  if (status == 0)
     1294    {
     1295      mpid = aud_fork(FIL__, __LINE__);
     1296
     1297      switch (mpid)
     1298        {
     1299        case -1:
     1300          status = -1;
     1301          break;
     1302        case 0:
     1303
     1304          /* -- Child process reads /dev/kmem and writes to pipe
     1305           */
     1306          run_child(kd, mpipe);
     1307          break;
     1308         
     1309          /* -- Parent process reads from child via pipe
     1310           */
     1311        default:
     1312          close(kd);
     1313          status = read_from_child(mpid, mpipe, &kinfo);
     1314          break;
     1315        }
     1316    }
     1317
     1318  if ( status < 0)
     1319    {
     1320      sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
     1321                       _("error reading from /dev/kmem"),
     1322                       _("kern_check_internal") );
     1323      SL_RETURN( (-1), _("sh_kern_check_internal"));
     1324    }
     1325
     1326  /* -- Check the proc_root inode.
     1327   *
     1328   * This will detect adore-ng.
     1329   */
     1330  check_proc_root( &kinfo );
     1331
     1332
     1333  /* -- Check the system_call syscall gate.
     1334   *
     1335   * Stored(old) is system_call_code[]
     1336   */
     1337  check_syscall_gate( is_init, &kinfo );
     1338
     1339  /* -- Check the individual syscalls
     1340   *
     1341   * Stored(old) is sh_syscalls[] array.
     1342   */
     1343  check_system_calls ( is_init, &kinfo );
     1344
     1345  /* -- Check the Interrupt Descriptor Table
     1346   */
     1347  check_idt_table(is_init);
     1348
     1349  /* -- Check PCI ROM
     1350   */
     1351  check_pci();
    13301352
    13311353  SL_RETURN( (0), _("sh_kern_check_internal"));
     
    13331355/* ifdef HOST_IS_LINUX */
    13341356#else
     1357
     1358/********************************************************
     1359 *
     1360 *  --- BSD ---
     1361 *
     1362 ********************************************************/
    13351363
    13361364#include <err.h>
     
    13701398      databuf = sh_kern_db_syscall (i, _("syscall"),
    13711399                                    NULL, &store0, &store1, &store2,
    1372                                     &datasize, 1);
     1400                                    &datasize, SH_KERN_DBPOP);
    13731401      sh_syscalls[i].addr = store0;
    13741402      if (databuf != NULL) { SH_FREE(databuf); }
     
    15611589          sh_kern_db_syscall (i, _("syscall"),
    15621590                              NULL, &store0, &store1, &store2,
    1563                               0, 0);
     1591                              0, SH_KERN_DBPUSH);
    15641592        }
    15651593    }
     
    16151643              sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    16161644                               status, MSG_KERN_SYSCALL,
    1617                                /*
    1618                                syscall_addr,
    1619                                sh_syscalls[i].addr,
    1620                                */
    16211645                               i, _(sh_syscalls[i].name),
    16221646                               msg);
     
    16821706                  sh_error_handle (ShKernSeverity, FIL__, __LINE__,
    16831707                                   status, MSG_KERN_SYSCALL,
    1684                                    /*
    1685                                    syscall_code[0],  syscall_code[1],
    1686                                    sh_syscalls[i].code[0], sh_syscalls[i].code[1],
    1687                                    */
    16881708                                   i, _(sh_syscalls[i].name),
    16891709                                   msg);
     
    19601980/* #ifdef SH_USE_KERN */
    19611981#endif
    1962 
    1963 
    1964 
  • trunk/src/sh_tiger0.c

    r76 r93  
    15891589    }
    15901590
    1591    SL_RETURN( _("000000000000000000000000000000000000000000000000"),
    1592               _("sh_tiger_hash_internal"));
     1591   SL_RETURN( SH_KEY_NULL, _("sh_tiger_hash_internal"));
    15931592}
    15941593
  • trunk/src/sh_unix.c

    r92 r93  
    893893  sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN,
    894894                  message, _("sh_unix_self_hash"));
    895   if (0 == sl_strcmp(sh.exec.hash,
    896                      _("000000000000000000000000000000000000000000000000")
    897                      ))
     895  if (0 == sl_strcmp(sh.exec.hash, SH_KEY_NULL ))
    898896    {
    899897      dlog(1, FIL__, __LINE__,
     
    28952893
    28962894 out:
    2897   sl_strlcpy(fileHash,
    2898              _("000000000000000000000000000000000000000000000000"),
    2899              KEY_LEN+1);
     2895  sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1);
    29002896  SL_RETURN( -1, _("sh_unix_checksum_size"));
    29012897}
     
    31933189    {
    31943190      if (fileHash != NULL)
    3195         sl_strlcpy(fileHash,
    3196                    _("000000000000000000000000000000000000000000000000"),
    3197                    KEY_LEN+1);
     3191        sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1);
    31983192    }
    31993193 
     
    32113205          if ((theFile->check_mask & MODI_CHK) == 0)
    32123206            {
    3213               sl_strlcpy(fileHash,
    3214                          _("000000000000000000000000000000000000000000000000"),
    3215                          KEY_LEN+1);
     3207              sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1);
    32163208            }
    32173209          else if ((theFile->check_mask & MODI_PREL) != 0 &&
     
    32213213              if (0 != sh_prelink_run (theFile->fullpath,
    32223214                                       fileHash, alert_timeout))
    3223                 sl_strlcpy(fileHash,
    3224                            _("000000000000000000000000000000000000000000000000"),
    3225                            KEY_LEN+1);
     3215                sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1);
    32263216            }
    32273217          else
     
    32553245          if ((theFile->check_mask & MODI_CHK) == 0)
    32563246            {
    3257               sl_strlcpy(fileHash,
    3258                          _("000000000000000000000000000000000000000000000000"),
    3259                          KEY_LEN+1);
     3247              sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1);
    32603248            }
    32613249          else if (policy == SH_LEVEL_PRELINK &&
     
    32653253              if (0 != sh_prelink_run (theFile->fullpath,
    32663254                                       fileHash, alert_timeout))
    3267                 sl_strlcpy(fileHash,
    3268                            _("000000000000000000000000000000000000000000000000"),
    3269                            KEY_LEN+1);
     3255                sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1);
    32703256            }
    32713257          else
     
    32953281      fstat_return = errno;
    32963282      if (fileHash != NULL)
    3297         sl_strlcpy(fileHash,
    3298                    _("000000000000000000000000000000000000000000000000"),
    3299                    KEY_LEN + 1);
     3283        sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1);
    33003284
    33013285      if ((theFile->check_mask & MODI_CHK) != 0)
     
    34833467      {
    34843468        tmp = sh_util_dirname(theFile->fullpath);
    3485         sl_strlcpy (theFile->linkpath,
    3486                     tmp,
    3487                     PATH_MAX);
    3488         SH_FREE(tmp);
    3489         sl_strlcat (theFile->linkpath,
    3490                     "/", PATH_MAX);
    3491         sl_strlcat (theFile->linkpath,
    3492                     linknamebuf,
    3493                     PATH_MAX);
     3469        if (tmp) {
     3470          sl_strlcpy (theFile->linkpath, tmp, PATH_MAX);
     3471          SH_FREE(tmp);
     3472        } else {
     3473          theFile->linkpath[0] = '\0';
     3474        }
     3475        /*
     3476         * Only attach '/' if not root directory. Handle "//", which
     3477         * according to POSIX is implementation-defined, and may be
     3478         * different from "/" (however, three or more '/' will collapse
     3479         * to one).
     3480         */
     3481        tmp = theFile->linkpath; while (*tmp == '/') ++tmp;
     3482        if (*tmp != '\0')
     3483          {
     3484            sl_strlcat (theFile->linkpath, "/", PATH_MAX);
     3485          }
     3486        sl_strlcat (theFile->linkpath, linknamebuf, PATH_MAX);
    34943487      }
    34953488   
  • trunk/src/sh_utils.c

    r76 r93  
    554554}
    555555
    556 /* can't inline (AIX)
     556/* read a hexchar, return int value (0-15)
     557 * can't inline (AIX)
    557558 */
    558559int sh_util_hexchar( const char c )
     
    567568  else return -1;
    568569  /*@-charint@*/
     570}
     571
     572char * sh_util_charhex( unsigned char i )
     573{
     574  static char i2h[2];
     575  int j, k;
     576
     577  j = i / 16;
     578  k = i - (j*16);
     579
     580  if (j < 10) i2h[0] = '0'+j;
     581  else        i2h[0] = 'A'+(j-10);
     582 
     583  if (k < 10) i2h[1] = '0'+k;
     584  else        i2h[1] = 'A'+(k-10);
     585
     586  return i2h;
    569587}
    570588
     
    17181736  char * retval;
    17191737  size_t len;
     1738  char * tmp;
    17201739
    17211740  SL_ENTER(_("sh_util_dirname"));
    17221741
    17231742  ASSERT_RET ((fullpath != NULL), _("fullpath != NULL"), (NULL))
    1724 
    1725   len = sl_strlen (fullpath);  /* fullpath[i] is terminating '\0' */
    1726 
    1727   if (len > 1 && fullpath[len-1] == '/') /* skip trailing '/' */
     1743  ASSERT_RET ((*fullpath == '/'), _("*fullpath == '/'"), (NULL))
     1744
     1745  retval = sh_util_strdup(fullpath);
     1746
     1747  tmp    = retval;
     1748  while (*tmp == '/') ++tmp;
     1749
     1750  /* (1) only leading slashes -- return exact copy
     1751   */
     1752  if (*tmp == '\0')
     1753    {
     1754      SL_RETURN(retval, _("sh_util_dirname"));
     1755    }
     1756
     1757  /* (2) there are non-slash characters, so delete trailing slashes
     1758   */
     1759  len    = sl_strlen (retval);     /* retval[len] is terminating '\0' */
     1760
     1761  while (len > 1 && retval[len-1] == '/')    /* delete trailing slash */
     1762    {
     1763      retval[len-1] = '\0';
     1764      --len;
     1765    }
     1766
     1767  /* (3) now delete all non-slash characters up to the preceding slash
     1768   */
     1769  while (len > 1 && retval[len-1] != '/') {
     1770    retval[len-1] = '\0';
    17281771    --len;
    1729 
    1730   while (len > 0) {
     1772  }
     1773
     1774  /* (4a) only leading slashes left, so return this
     1775   */
     1776  if (&(retval[len]) == tmp)
     1777    {
     1778      SL_RETURN(retval, _("sh_util_dirname"));
     1779    }
     1780
     1781  /* (4b) strip trailing slash(es) of parent directory
     1782   */
     1783  while (len > 1 && retval[len-1] == '/') {
     1784    retval[len-1] = '\0';
    17311785    --len;
    1732     if (fullpath[len] == '/')
    1733       {
    1734         if (len == 0) ++len; /* copy the '/' to output */
    1735         break;
    1736       }
    17371786  }
    1738 
    1739   /* -- Not an absolute path. --
    1740    */
    1741   if ((len == 0) && (fullpath[len] != '/'))
    1742     {
    1743       SL_RETURN(NULL, _("sh_util_dirname"));
    1744     }
    1745 
    1746   retval = SH_ALLOC(len + 1);
    1747   (void) sl_strlcpy (retval, fullpath, len+1);
    1748 
    17491787  SL_RETURN(retval, _("sh_util_dirname"));
     1788
    17501789}
    17511790
     
    17541793char * sh_util_basename(const char * fullpath)
    17551794{
    1756   char * retval = NULL;
    1757   char * tmp;
    1758   char * c;
    1759   size_t len;
     1795  char       * retval = NULL;
     1796  const char * tmp;
     1797  char       * tmp2;
     1798  char       * c;
     1799  size_t       len;
    17601800
    17611801  SL_ENTER(_("sh_util_basename"));
     
    17631803  ASSERT_RET ((fullpath != NULL), _("fullpath != NULL"), (NULL))
    17641804
    1765   c = strrchr(fullpath, '/');
    1766   len = sl_strlen (c);
    1767 
    1768   if (c == fullpath)
    1769     {
    1770       if (len <= 1)
    1771         retval = sh_util_strdup(c);
     1805  tmp = fullpath; while (*tmp == '/') ++tmp;
     1806  if (*tmp == '\0')
     1807    {
     1808      retval = sh_util_strdup(fullpath);
     1809    }
     1810  else
     1811    {
     1812      tmp2 = sh_util_strdup(tmp);
     1813      len  = sl_strlen (tmp2);
     1814
     1815      while (len > 1 && tmp2[len-1] == '/')
     1816        {
     1817          tmp2[len-1] = '\0';
     1818          --len;
     1819        }
     1820
     1821      c = strrchr(tmp2, '/');
     1822      if (c)
     1823        {
     1824          retval = sh_util_strdup(++c);
     1825          SH_FREE(tmp2);
     1826        }
    17721827      else
    1773         retval = sh_util_strdup(++c);
    1774     }
    1775   else
    1776     {
    1777       if (len > 1)
    1778         {
    1779           retval = sh_util_strdup(++c);
    1780         }
    1781       else
    1782         {
    1783           /* input ends in '/' */
    1784           tmp = sh_util_strdup(fullpath);
    1785           tmp[strlen(tmp)-1] = '\0';
    1786           retval = sh_util_basename(tmp);
    1787           SH_FREE(tmp);
     1828        {
     1829          retval = tmp2;
    17881830        }
    17891831    }
Note: See TracChangeset for help on using the changeset viewer.