- Timestamp:
- Feb 26, 2007, 10:48:51 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/docs/Changelog
r92 r93 1 2.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 1 10 2.3.2: 2 * move file descriptor closing more towards program startup3 * fix samhain_hide module (in-)compatibility with recent kernels4 11 * fix regression in full stealth mode (incorrect comparison of 5 12 bytes read vs. maximum capacity), reported by B. Fleming -
trunk/docs/README.UPGRADE
r73 r93 1 1 2 from lower to 2.3.x: database scheme has changed slightly 2 to 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 11 from 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: 3 14 4 15 -- MySQL: -
trunk/include/samhain.h
r76 r93 124 124 SH_CHECK_CHECK = 2 125 125 }; 126 127 #define SH_KEY_NULL _("000000000000000000000000000000000000000000000000") 126 128 127 129 /************************************************** -
trunk/include/sh_utils.h
r76 r93 102 102 int sh_util_obscure_ok (const char * str); 103 103 104 /* read a hexchar 104 /* output a hexchar[2] 105 */ 106 char * sh_util_charhex( unsigned char c ); 107 108 /* read a hexchar, return int value (0-15) 105 109 */ 106 110 int sh_util_hexchar( char c ); -
trunk/src/cutest_sh_utils.c
r76 r93 143 143 char res3[] = "/"; 144 144 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 145 163 ret = sh_util_dirname(input0); 146 164 CuAssertPtrNotNull(tc, ret); … … 158 176 CuAssertPtrNotNull(tc, ret); 159 177 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); 160 202 return; 161 203 } … … 179 221 char res4[] = "bar"; 180 222 223 char input5[] = "/foo///bar///"; 224 char res5[] = "bar"; 225 226 char input6[] = "//foo"; 227 char res6[] = "foo"; 228 181 229 ret = sh_util_basename(input0); 182 230 CuAssertPtrNotNull(tc, ret); … … 198 246 CuAssertPtrNotNull(tc, ret); 199 247 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); 200 256 201 257 return; -
trunk/src/sh_hash.c
r77 r93 1926 1926 ******************************************************************/ 1927 1927 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 1945 1928 void sh_hash_push2db (char * key, unsigned long val1, 1946 1929 unsigned long val2, unsigned long val3, … … 1975 1958 for (i = 0; i < size; ++i) 1976 1959 { 1977 p = sh_ hash_charhex (str[i]);1960 p = sh_util_charhex (str[i]); 1978 1961 tmpFile.linkpath[2*i] = p[0]; 1979 1962 tmpFile.linkpath[2*i+1] = p[1]; … … 1983 1966 else 1984 1967 { 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'; 1992 1973 } 1993 1974 1994 1975 if (sh.flag.checkSum == SH_CHECK_CHECK && 1995 1976 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); 2001 1980 2002 1981 return; … … 2018 1997 if (0 == sh_hash_get_it (key, &tmpFile)) 2019 1998 { 2020 *val1 1999 *val1 = tmpFile.size; 2021 2000 *val2 = tmpFile.mtime; 2022 2001 *val3 = tmpFile.ctime; … … 2701 2680 maxcomp = KEY_LEN; 2702 2681 } 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 } 2711 2691 } 2712 2692 -
trunk/src/sh_kern.c
r83 r93 23 23 #define SH_SYSCALL_CODE 24 24 25 #ifdef HOST_IS_I86LINUX26 #define SH_IDT_TABLE27 #define SH_PROC_CHECK28 #endif29 25 30 26 #include <stdio.h> … … 156 152 #endif 157 153 154 /* This is the module 'reconfigure' function, which is a no-op. 155 */ 158 156 int sh_kern_null() 159 157 { … … 161 159 } 162 160 163 #ifdef SH_IDT_TABLE 161 #define SH_KERN_DBPUSH 0 162 #define SH_KERN_DBPOP 1 163 164 char * 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 193 static 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 */ 164 266 165 267 #include <asm/segment.h> 166 268 167 269 #define SH_MAXIDT 256 168 unsigned char sh_idt_table[SH_MAXIDT * 8]; 169 char * sh_strseg(unsigned short segment) 270 271 static unsigned char sh_idt_table[SH_MAXIDT * 8]; 272 273 static char * sh_strseg(unsigned short segment) 170 274 { 171 275 switch (segment) { … … 182 286 } 183 287 } 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 290 static int sh_kern_data_init () 342 291 { 343 292 unsigned long store0 = 0; … … 346 295 char * databuf; 347 296 348 #ifdef SH_SYSCALL_CODE349 297 /* system_call code 350 298 */ 351 299 databuf = sh_kern_db_syscall (0, _("system_call"), 352 300 NULL, &store0, &store1, &store2, 353 &datasize, 1);301 &datasize, SH_KERN_DBPOP); 354 302 if (datasize == sizeof(system_call_code)) 355 303 { … … 364 312 return -1; 365 313 } 366 #endif367 314 368 315 /* syscall address and code … … 372 319 databuf = sh_kern_db_syscall (i, _("syscall"), 373 320 NULL, &store0, &store1, &store2, 374 &datasize, 1);321 &datasize, SH_KERN_DBPOP); 375 322 sh_syscalls[i].addr = store0; 376 323 if (store0 == 0) { … … 380 327 return -1; 381 328 } 382 #ifdef SH_SYSCALL_CODE 329 383 330 sh_syscalls[i].code[0] = (unsigned int) store1; 384 331 sh_syscalls[i].code[1] = (unsigned int) store2; … … 387 334 _("syscall code not found in database"), 388 335 _("sh_kern_data_init")); 389 /* fprintf(stderr, "Syscall #%d\n", i); */390 /* return -1; */391 336 } 392 #endif 337 393 338 if (databuf != NULL) { 394 339 SH_FREE(databuf); … … 397 342 } 398 343 399 #ifdef SH_IDT_TABLE400 344 if (ShKernIDT == S_TRUE) 401 345 { … … 405 349 NULL, 406 350 &store0, &store1, &store2, 407 &datasize, 1);351 &datasize, SH_KERN_DBPOP); 408 352 if (datasize == 8) { 409 353 memcpy(&idt_table[j*8], databuf, 8); … … 417 361 } 418 362 } 419 #endif420 363 421 364 return 0; 422 365 } 423 366 424 #ifdef SH_PROC_CHECK425 367 426 368 /* … … 495 437 */ 496 438 }; 497 #endif 439 498 440 499 441 static int sh_kern_kmem_read (int fd, unsigned long addr, … … 540 482 } 541 483 542 int sh_kern_check_internal () 484 485 static int check_init (int * init_retval) 543 486 { 544 487 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 528 static 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 562 535 unsigned char buf[6]; 563 536 unsigned short idt_size; 564 537 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 668 struct 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 678 static 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 765 static void check_idt_table(int is_init) 766 { 767 int i, j; 768 566 769 unsigned short idt_offset_lo, idt_offset_hi, idt_selector; 567 770 unsigned char idt_reserved, idt_flag; … … 573 776 unsigned long sh_idt_iaddr; 574 777 char idt_type, sh_idt_type; 575 #endif576 577 unsigned char new_system_call_code[256];578 579 #ifdef SH_USE_LKM580 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 #endif587 778 588 779 unsigned long store0; 589 780 unsigned int store1, store2; 590 781 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];597 782 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 1192 784 if (ShKernIDT == S_TRUE) 1193 785 { … … 1200 792 &sh_idt_table[j*8], 1201 793 &store0, &store1, &store2, 1202 &datasize, 0);794 &datasize, SH_KERN_DBPUSH); 1203 795 } 1204 796 } … … 1275 867 else { sh_dpl = -1; sh_idt_type = 'U'; } 1276 868 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); 1312 873 1313 874 sh_error_handle (ShKernSeverity, FIL__, __LINE__, 1314 status, MSG_KERN_IDT,875 0, MSG_KERN_IDT, 1315 876 j, 1316 877 sh_idt_iaddr, sh_strseg(sh_idt_selector), … … 1319 880 (int) dpl, idt_type, msg); 1320 881 1321 SH_FREE(linkpath_old);1322 SH_FREE(linkpath_new);1323 1324 882 memcpy(&idt_table[i], &sh_idt_table[i], 8); 1325 883 } … … 1327 885 } 1328 886 } 1329 #endif 887 } 888 889 890 #define SYS_BUS_PCI _("/sys/bus/pci/devices") 891 #include <dirent.h> 892 893 static 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 933 static 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 956 static 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 */ 987 static 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 */ 1015 static 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 1062 static 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 1246 int 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(); 1330 1352 1331 1353 SL_RETURN( (0), _("sh_kern_check_internal")); … … 1333 1355 /* ifdef HOST_IS_LINUX */ 1334 1356 #else 1357 1358 /******************************************************** 1359 * 1360 * --- BSD --- 1361 * 1362 ********************************************************/ 1335 1363 1336 1364 #include <err.h> … … 1370 1398 databuf = sh_kern_db_syscall (i, _("syscall"), 1371 1399 NULL, &store0, &store1, &store2, 1372 &datasize, 1);1400 &datasize, SH_KERN_DBPOP); 1373 1401 sh_syscalls[i].addr = store0; 1374 1402 if (databuf != NULL) { SH_FREE(databuf); } … … 1561 1589 sh_kern_db_syscall (i, _("syscall"), 1562 1590 NULL, &store0, &store1, &store2, 1563 0, 0);1591 0, SH_KERN_DBPUSH); 1564 1592 } 1565 1593 } … … 1615 1643 sh_error_handle (ShKernSeverity, FIL__, __LINE__, 1616 1644 status, MSG_KERN_SYSCALL, 1617 /*1618 syscall_addr,1619 sh_syscalls[i].addr,1620 */1621 1645 i, _(sh_syscalls[i].name), 1622 1646 msg); … … 1682 1706 sh_error_handle (ShKernSeverity, FIL__, __LINE__, 1683 1707 status, MSG_KERN_SYSCALL, 1684 /*1685 syscall_code[0], syscall_code[1],1686 sh_syscalls[i].code[0], sh_syscalls[i].code[1],1687 */1688 1708 i, _(sh_syscalls[i].name), 1689 1709 msg); … … 1960 1980 /* #ifdef SH_USE_KERN */ 1961 1981 #endif 1962 1963 1964 -
trunk/src/sh_tiger0.c
r76 r93 1589 1589 } 1590 1590 1591 SL_RETURN( _("000000000000000000000000000000000000000000000000"), 1592 _("sh_tiger_hash_internal")); 1591 SL_RETURN( SH_KEY_NULL, _("sh_tiger_hash_internal")); 1593 1592 } 1594 1593 -
trunk/src/sh_unix.c
r92 r93 893 893 sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN, 894 894 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 )) 898 896 { 899 897 dlog(1, FIL__, __LINE__, … … 2895 2893 2896 2894 out: 2897 sl_strlcpy(fileHash, 2898 _("000000000000000000000000000000000000000000000000"), 2899 KEY_LEN+1); 2895 sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1); 2900 2896 SL_RETURN( -1, _("sh_unix_checksum_size")); 2901 2897 } … … 3193 3189 { 3194 3190 if (fileHash != NULL) 3195 sl_strlcpy(fileHash, 3196 _("000000000000000000000000000000000000000000000000"), 3197 KEY_LEN+1); 3191 sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1); 3198 3192 } 3199 3193 … … 3211 3205 if ((theFile->check_mask & MODI_CHK) == 0) 3212 3206 { 3213 sl_strlcpy(fileHash, 3214 _("000000000000000000000000000000000000000000000000"), 3215 KEY_LEN+1); 3207 sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1); 3216 3208 } 3217 3209 else if ((theFile->check_mask & MODI_PREL) != 0 && … … 3221 3213 if (0 != sh_prelink_run (theFile->fullpath, 3222 3214 fileHash, alert_timeout)) 3223 sl_strlcpy(fileHash, 3224 _("000000000000000000000000000000000000000000000000"), 3225 KEY_LEN+1); 3215 sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1); 3226 3216 } 3227 3217 else … … 3255 3245 if ((theFile->check_mask & MODI_CHK) == 0) 3256 3246 { 3257 sl_strlcpy(fileHash, 3258 _("000000000000000000000000000000000000000000000000"), 3259 KEY_LEN+1); 3247 sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1); 3260 3248 } 3261 3249 else if (policy == SH_LEVEL_PRELINK && … … 3265 3253 if (0 != sh_prelink_run (theFile->fullpath, 3266 3254 fileHash, alert_timeout)) 3267 sl_strlcpy(fileHash, 3268 _("000000000000000000000000000000000000000000000000"), 3269 KEY_LEN+1); 3255 sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1); 3270 3256 } 3271 3257 else … … 3295 3281 fstat_return = errno; 3296 3282 if (fileHash != NULL) 3297 sl_strlcpy(fileHash, 3298 _("000000000000000000000000000000000000000000000000"), 3299 KEY_LEN + 1); 3283 sl_strlcpy(fileHash, SH_KEY_NULL, KEY_LEN+1); 3300 3284 3301 3285 if ((theFile->check_mask & MODI_CHK) != 0) … … 3483 3467 { 3484 3468 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); 3494 3487 } 3495 3488 -
trunk/src/sh_utils.c
r76 r93 554 554 } 555 555 556 /* can't inline (AIX) 556 /* read a hexchar, return int value (0-15) 557 * can't inline (AIX) 557 558 */ 558 559 int sh_util_hexchar( const char c ) … … 567 568 else return -1; 568 569 /*@-charint@*/ 570 } 571 572 char * 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; 569 587 } 570 588 … … 1718 1736 char * retval; 1719 1737 size_t len; 1738 char * tmp; 1720 1739 1721 1740 SL_ENTER(_("sh_util_dirname")); 1722 1741 1723 1742 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'; 1728 1771 --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'; 1731 1785 --len; 1732 if (fullpath[len] == '/')1733 {1734 if (len == 0) ++len; /* copy the '/' to output */1735 break;1736 }1737 1786 } 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 1749 1787 SL_RETURN(retval, _("sh_util_dirname")); 1788 1750 1789 } 1751 1790 … … 1754 1793 char * sh_util_basename(const char * fullpath) 1755 1794 { 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; 1760 1800 1761 1801 SL_ENTER(_("sh_util_basename")); … … 1763 1803 ASSERT_RET ((fullpath != NULL), _("fullpath != NULL"), (NULL)) 1764 1804 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 } 1772 1827 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; 1788 1830 } 1789 1831 }
Note:
See TracChangeset
for help on using the changeset viewer.