Changeset 180
- Timestamp:
- 03/14/10 16:02:38 (15 years ago)
- Files:
-
- 3 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Makefile
r159 r180 14 14 #OPTS=-std=gnu99 -pedantic -Wall 15 15 INC:=-I$(PWD)/include -I/usr/local/include 16 LIB=-L/usr/local/lib -lm 16 LIB=-L/usr/local/lib -lm -lpthread 17 17 BIN_EXT= 18 18 EXTRA_OBJ= -
trunk/include/regfi.h
r178 r180 69 69 #include <unistd.h> 70 70 #include <iconv.h> 71 #include <pthread.h> 71 72 72 73 #include "byteorder.h" … … 674 675 REGFI_RAW_FILE* cb; 675 676 677 /* Mutex for all cb access. This is done to prevent one thread from moving 678 * the file offset while another thread is in the middle of a multi-read 679 * parsing transaction */ 680 pthread_mutex_t* cb_lock; 681 676 682 /* For sanity checking (not part of the registry header) */ 677 683 uint32_t file_length; … … 680 686 range_list* hbins; 681 687 688 /* Multiple read access allowed, write access is exclusive */ 689 pthread_rwlock_t* hbins_lock; 690 682 691 /* SK record cached since they're repeatedly reused */ 683 692 lru_cache* sk_cache; 693 694 /* Need exclusive access for LRUs, since lookups make changes */ 695 pthread_mutex_t* sk_lock; 684 696 685 697 /* Error/warning/info messages returned by lower layer functions */ -
trunk/lib/regfi.c
r178 r180 422 422 423 423 424 bool regfi_read_lock(REGFI_FILE* file, pthread_rwlock_t* lock, const char* context) 425 { 426 int lock_ret = pthread_rwlock_rdlock(lock); 427 if(lock_ret != 0) 428 { 429 regfi_add_message(file, REGFI_MSG_ERROR, "Error obtaining read lock in" 430 "%s due to: %s\n", context, strerror(lock_ret)); 431 return false; 432 } 433 434 return true; 435 } 436 437 438 bool regfi_write_lock(REGFI_FILE* file, pthread_rwlock_t* lock, const char* context) 439 { 440 int lock_ret = pthread_rwlock_wrlock(lock); 441 if(lock_ret != 0) 442 { 443 regfi_add_message(file, REGFI_MSG_ERROR, "Error obtaining write lock in" 444 "%s due to: %s\n", context, strerror(lock_ret)); 445 return false; 446 } 447 448 return true; 449 } 450 451 452 bool regfi_rw_unlock(REGFI_FILE* file, pthread_rwlock_t* lock, const char* context) 453 { 454 int lock_ret = pthread_rwlock_unlock(lock); 455 if(lock_ret != 0) 456 { 457 regfi_add_message(file, REGFI_MSG_ERROR, "Error releasing lock in" 458 "%s due to: %s\n", context, strerror(lock_ret)); 459 return false; 460 } 461 462 return true; 463 } 464 465 466 bool regfi_lock(REGFI_FILE* file, pthread_mutex_t* lock, const char* context) 467 { 468 int lock_ret = pthread_mutex_lock(lock); 469 if(lock_ret != 0) 470 { 471 regfi_add_message(file, REGFI_MSG_ERROR, "Error obtaining mutex lock in" 472 "%s due to: %s\n", context, strerror(lock_ret)); 473 return false; 474 } 475 476 return true; 477 } 478 479 480 bool regfi_unlock(REGFI_FILE* file, pthread_mutex_t* lock, const char* context) 481 { 482 int lock_ret = pthread_mutex_unlock(lock); 483 if(lock_ret != 0) 484 { 485 regfi_add_message(file, REGFI_MSG_ERROR, "Error releasing mutex lock in" 486 "%s due to: %s\n", context, strerror(lock_ret)); 487 return false; 488 } 489 490 return true; 491 } 492 493 424 494 off_t regfi_raw_seek(REGFI_RAW_FILE* self, off_t offset, int whence) 425 495 { … … 655 725 bool recursive_type; 656 726 727 if(!regfi_lock(file, file->cb_lock, "regfi_parse_subkeylist")) 728 goto fail; 729 657 730 if(!regfi_parse_cell(file->cb, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN, 658 731 &cell_length, &unalloc)) … … 660 733 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while " 661 734 "parsing subkey-list at offset 0x%.8X.", offset); 662 return NULL;735 goto fail_locked; 663 736 } 664 737 … … 668 741 " while parsing subkey-list at offset 0x%.8X.", offset); 669 742 if(strict) 670 return NULL;743 goto fail_locked; 671 744 cell_length = max_size & 0xFFFFFFF8; 672 745 } … … 687 760 " (0x%.2X, 0x%.2X) encountered while parsing" 688 761 " subkey-list at offset 0x%.8X.", buf[0], buf[1], offset); 689 return NULL;762 goto fail_locked; 690 763 } 691 764 692 765 ret_val = talloc(NULL, REGFI_SUBKEY_LIST); 693 766 if(ret_val == NULL) 694 return NULL;767 goto fail_locked; 695 768 696 769 ret_val->offset = offset; … … 711 784 offset); 712 785 if(strict) 713 goto fail ;786 goto fail_locked; 714 787 length = cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32_t); 715 788 } … … 718 791 ret_val->num_children); 719 792 if(ret_val->elements == NULL) 720 goto fail ;793 goto fail_locked; 721 794 722 795 elements = (uint8_t*)malloc(length); 723 796 if(elements == NULL) 724 goto fail ;797 goto fail_locked; 725 798 726 799 read_len = length; 727 800 if(regfi_read(file->cb, elements, &read_len) != 0 || read_len!=length) 728 goto fail; 801 goto fail_locked; 802 803 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_subkeylist")) 804 goto fail; 729 805 730 806 if(elem_size == sizeof(uint32_t)) … … 748 824 return ret_val; 749 825 826 fail_locked: 827 regfi_unlock(file, file->cb_lock, "regfi_parse_subkeylist"); 750 828 fail: 751 829 if(elements != NULL) … … 817 895 bool strict) 818 896 { 819 REGFI_SK_REC* ret_val ;897 REGFI_SK_REC* ret_val = NULL; 820 898 uint8_t* sec_desc_buf = NULL; 821 899 uint32_t cell_length, length; … … 823 901 bool unalloc = false; 824 902 903 if(!regfi_lock(file, file->cb_lock, "regfi_parse_sk")) 904 goto fail; 905 825 906 if(!regfi_parse_cell(file->cb, offset, sk_header, REGFI_SK_MIN_LENGTH, 826 907 &cell_length, &unalloc)) … … 828 909 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse SK record cell" 829 910 " at offset 0x%.8X.", offset); 830 return NULL;911 goto fail_locked; 831 912 } 832 913 … … 835 916 regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing" 836 917 " SK record at offset 0x%.8X.", offset); 837 return NULL;918 goto fail_locked; 838 919 } 839 920 840 921 ret_val = talloc(NULL, REGFI_SK_REC); 841 922 if(ret_val == NULL) 842 return NULL;923 goto fail_locked; 843 924 844 925 ret_val->offset = offset; … … 855 936 regfi_add_message(file, REGFI_MSG_WARN, "Invalid cell size found while" 856 937 " parsing SK record at offset 0x%.8X.", offset); 857 goto fail ;938 goto fail_locked; 858 939 } 859 940 … … 873 954 " are not a multiple of 8 while parsing SK record at" 874 955 " offset 0x%.8X.", offset); 875 goto fail ;956 goto fail_locked; 876 957 } 877 958 … … 881 962 " cell while parsing SK record at offset 0x%.8X.", 882 963 offset); 883 goto fail ;964 goto fail_locked; 884 965 } 885 966 886 967 sec_desc_buf = (uint8_t*)malloc(ret_val->desc_size); 887 968 if(sec_desc_buf == NULL) 888 goto fail ;969 goto fail_locked; 889 970 890 971 length = ret_val->desc_size; … … 895 976 " descriptor while parsing SK record at offset 0x%.8X.", 896 977 offset); 897 goto fail; 898 } 978 goto fail_locked; 979 } 980 981 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_sk")) 982 goto fail; 899 983 900 984 if(!(ret_val->sec_desc = winsec_parse_desc(ret_val, sec_desc_buf, … … 910 994 return ret_val; 911 995 996 fail_locked: 997 regfi_unlock(file, file->cb_lock, "regfi_parse_sk"); 912 998 fail: 913 999 if(sec_desc_buf != NULL) … … 925 1011 bool unalloc; 926 1012 1013 if(!regfi_lock(file, file->cb_lock, "regfi_parse_valuelist")) 1014 goto fail; 1015 927 1016 if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc)) 928 1017 { 929 1018 regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read cell header" 930 1019 " while parsing value list at offset 0x%.8X.", offset); 931 return NULL;1020 goto fail_locked; 932 1021 } 933 1022 … … 937 1026 " while parsing value list at offset 0x%.8X.", offset); 938 1027 if(strict) 939 return NULL;1028 goto fail_locked; 940 1029 cell_length = cell_length & 0xFFFFFFF8; 941 1030 } … … 946 1035 " while parsing value list at offset 0x%.8X.", offset); 947 1036 if(strict) 948 return NULL;1037 goto fail_locked; 949 1038 num_values = cell_length/sizeof(uint32_t) - sizeof(uint32_t); 950 1039 } … … 953 1042 ret_val = talloc(NULL, REGFI_VALUE_LIST); 954 1043 if(ret_val == NULL) 955 return NULL;1044 goto fail_locked; 956 1045 957 1046 ret_val->elements = (REGFI_VALUE_LIST_ELEM*)talloc_size(ret_val, read_len); 958 1047 if(ret_val->elements == NULL) 959 { 960 talloc_free(ret_val); 961 return NULL; 962 } 1048 goto fail_locked; 1049 963 1050 ret_val->num_values = num_values; 964 1051 … … 969 1056 regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read value pointers" 970 1057 " while parsing value list at offset 0x%.8X.", offset); 971 talloc_free(ret_val); 972 return NULL; 973 } 974 1058 goto fail_locked; 1059 } 1060 1061 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_valuelist")) 1062 goto fail; 1063 975 1064 for(i=0; i < num_values; i++) 976 1065 { … … 989 1078 " (0x%.8X) found while parsing value list at offset" 990 1079 " 0x%.8X.", ret_val->elements[i], offset); 991 talloc_free(ret_val); 992 return NULL; 1080 goto fail; 993 1081 } 994 1082 } … … 996 1084 997 1085 return ret_val; 1086 1087 fail_locked: 1088 regfi_unlock(file, file->cb_lock, "regfi_parse_valuelist"); 1089 fail: 1090 talloc_free(ret_val); 1091 return NULL; 998 1092 } 999 1093 … … 1195 1289 } 1196 1290 } 1197 talloc_ steal(nk, nk->values);1291 talloc_reference(nk, nk->values); 1198 1292 } 1199 1293 } … … 1225 1319 nk->num_subkeys = 0; 1226 1320 } 1227 talloc_ steal(nk, nk->subkeys);1321 talloc_reference(nk, nk->subkeys); 1228 1322 } 1229 1323 } … … 1241 1335 void* failure_ptr = NULL; 1242 1336 1337 if(!regfi_lock(file, file->sk_lock, "regfi_load_sk")) 1338 return NULL; 1339 1243 1340 /* First look if we have already parsed it */ 1244 1341 ret_val = (REGFI_SK_REC*)lru_cache_find(file->sk_cache, &offset, 4); … … 1268 1365 } 1269 1366 1367 if(!regfi_unlock(file, file->sk_lock, "regfi_load_sk")) 1368 return NULL; 1369 1270 1370 return ret_val; 1271 1371 } … … 1286 1386 while(cur_offset < hbin_end) 1287 1387 { 1388 1389 if(!regfi_lock(file, file->cb_lock, "regfi_find_root_nk")) 1390 return NULL; 1391 1288 1392 if(!regfi_parse_cell(file->cb, cur_offset, NULL, 0, &cell_length, &unalloc)) 1289 1393 { … … 1292 1396 return NULL; 1293 1397 } 1294 1398 1399 if(!regfi_unlock(file, file->cb_lock, "regfi_find_root_nk")) 1400 return NULL; 1401 1295 1402 if(!unalloc) 1296 1403 { … … 1335 1442 1336 1443 /* In this case, we want file_cb to be freed when ret_val is */ 1337 talloc_ steal(ret_val, file_cb);1444 talloc_reference(ret_val, file_cb); 1338 1445 return ret_val; 1339 1446 … … 1369 1476 rb->file_length = file_length; 1370 1477 rb->cb = file_cb; 1478 rb->cb_lock = NULL; 1479 rb->hbins_lock = NULL; 1480 rb->sk_lock = NULL; 1481 1482 rb->cb_lock = talloc(rb, pthread_mutex_t); 1483 if(rb->cb_lock == NULL || pthread_mutex_init(rb->cb_lock, NULL) != 0) 1484 goto fail; 1485 1486 rb->hbins_lock = talloc(rb, pthread_rwlock_t); 1487 if(rb->hbins_lock == NULL || pthread_rwlock_init(rb->hbins_lock, NULL) != 0) 1488 goto fail; 1489 1490 rb->sk_lock = talloc(rb, pthread_mutex_t); 1491 if(rb->sk_lock == NULL || pthread_mutex_init(rb->sk_lock, NULL) != 0) 1492 goto fail; 1371 1493 1372 1494 rb->hbins = range_list_new(); 1373 1495 if(rb->hbins == NULL) 1374 { 1375 /* fprintf(stderr, "regfi_alloc_cb: Failed to create HBIN list.\n"); */ 1376 talloc_free(rb); 1377 return NULL; 1378 } 1379 talloc_steal(rb, rb->hbins); 1496 goto fail; 1497 talloc_reference(rb, rb->hbins); 1380 1498 1381 1499 rla = true; … … 1386 1504 rla = range_list_add(rb->hbins, hbin->file_off, hbin->block_size, hbin); 1387 1505 if(rla) 1388 talloc_steal(rb->hbins, hbin); 1506 talloc_reference(rb->hbins, hbin); 1507 1389 1508 hbin_off = hbin->file_off + hbin->block_size; 1390 1509 hbin = regfi_parse_hbin(rb, hbin_off, true); … … 1405 1524 /* success */ 1406 1525 return rb; 1526 1527 fail: 1528 if(rb->cb_lock != NULL) 1529 pthread_mutex_destroy(rb->cb_lock); 1530 if(rb->hbins_lock != NULL) 1531 pthread_rwlock_destroy(rb->hbins_lock); 1532 if(rb->sk_lock != NULL) 1533 pthread_mutex_destroy(rb->sk_lock); 1534 1535 range_list_free(rb->hbins); 1536 talloc_free(rb->cb_lock); 1537 talloc_free(rb->hbins_lock); 1538 talloc_free(rb); 1539 return NULL; 1407 1540 } 1408 1541 … … 1415 1548 free(file->last_message); 1416 1549 1550 pthread_mutex_destroy(file->cb_lock); 1551 pthread_rwlock_destroy(file->hbins_lock); 1552 pthread_mutex_destroy(file->sk_lock); 1417 1553 talloc_free(file); 1418 1554 } … … 1447 1583 * block at a time looking for an NK record with a root key type. 1448 1584 */ 1585 1586 if(!regfi_read_lock(file, file->hbins_lock, "regfi_rootkey")) 1587 return NULL; 1588 1449 1589 num_hbins = range_list_size(file->hbins); 1450 1590 for(i=0; i < num_hbins && nk == NULL; i++) … … 1453 1593 nk = regfi_find_root_nk(file, hbin, output_encoding); 1454 1594 } 1595 1596 if(!regfi_rw_unlock(file, file->hbins_lock, "regfi_rootkey")) 1597 return NULL; 1455 1598 1456 1599 return nk; … … 1519 1662 return NULL; 1520 1663 } 1521 talloc_ steal(ret_val, ret_val->key_positions);1664 talloc_reference(ret_val, ret_val->key_positions); 1522 1665 1523 1666 ret_val->f = file; … … 1567 1710 return false; 1568 1711 } 1569 talloc_ steal(i, subkey);1712 talloc_reference(i, subkey); 1570 1713 1571 1714 i->cur_key = subkey; … … 1852 1995 ret_val->raw = raw; 1853 1996 ret_val->size = parse_length; 1854 talloc_ steal(ret_val, raw);1997 talloc_reference(ret_val, raw); 1855 1998 1856 1999 interpreted = talloc_array(NULL, char, parse_length); … … 1872 2015 interpreted = talloc_realloc(NULL, interpreted, char, conv_size); 1873 2016 ret_val->interpreted = interpreted; 1874 talloc_ steal(ret_val, interpreted);2017 talloc_reference(ret_val, interpreted); 1875 2018 } 1876 2019 … … 1952 2095 return NULL; 1953 2096 1954 talloc_ steal(ret_val, raw_data.buf);2097 talloc_reference(ret_val, raw_data.buf); 1955 2098 ret_val->raw = raw_data.buf; 1956 2099 ret_val->size = raw_data.len; … … 2007 2150 data->interpreted.string = tmp_str; 2008 2151 data->interpreted_size = tmp_size; 2009 talloc_ steal(data, tmp_str);2152 talloc_reference(data, tmp_str); 2010 2153 break; 2011 2154 … … 2092 2235 /* XXX: how meaningful is this? should we store number of strings instead? */ 2093 2236 data->interpreted_size = tmp_size; 2094 talloc_ steal(tmp_array, tmp_str);2095 talloc_ steal(data, tmp_array);2237 talloc_reference(tmp_array, tmp_str); 2238 talloc_reference(data, tmp_array); 2096 2239 break; 2097 2240 … … 2281 2424 2282 2425 if(offset >= file->file_length) 2283 return NULL; 2426 goto fail; 2427 2428 if(!regfi_lock(file, file->cb_lock, "regfi_parse_hbin")) 2429 goto fail; 2284 2430 2285 2431 if(regfi_seek(file->cb, offset, SEEK_SET) == -1) … … 2287 2433 regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed" 2288 2434 " while parsing hbin at offset 0x%.8X.", offset); 2289 return NULL;2435 goto fail_locked; 2290 2436 } 2291 2437 … … 2293 2439 if((regfi_read(file->cb, hbin_header, &length) != 0) 2294 2440 || length != REGFI_HBIN_HEADER_SIZE) 2295 return NULL; 2296 2297 if(regfi_seek(file->cb, offset, SEEK_SET) == -1) 2298 { 2299 regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed" 2300 " while parsing hbin at offset 0x%.8X.", offset); 2301 return NULL; 2302 } 2441 goto fail_locked; 2442 2443 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_hbin")) 2444 goto fail; 2303 2445 2304 2446 hbin = talloc(NULL, REGFI_HBIN); 2305 2447 if(hbin == NULL) 2306 return NULL;2448 goto fail; 2307 2449 hbin->file_off = offset; 2308 2450 … … 2314 2456 " 0x%.8X.", hbin->magic[0], hbin->magic[1], 2315 2457 hbin->magic[2], hbin->magic[3], offset); 2316 talloc_free(hbin); 2317 return NULL; 2458 goto fail; 2318 2459 } 2319 2460 … … 2336 2477 " or runs off the end of the file" 2337 2478 " while parsing hbin at offset 0x%.8X.", offset); 2338 talloc_free(hbin); 2339 return NULL; 2479 goto fail; 2340 2480 } 2341 2481 2342 2482 return hbin; 2483 2484 fail_locked: 2485 regfi_unlock(file, file->cb_lock, "regfi_parse_hbin"); 2486 fail: 2487 talloc_free(hbin); 2488 return NULL; 2343 2489 } 2344 2490 … … 2354 2500 bool unalloc = false; 2355 2501 2502 ret_val = talloc(NULL, REGFI_NK_REC); 2503 if(ret_val == NULL) 2504 { 2505 regfi_add_message(file, REGFI_MSG_ERROR, "Failed to allocate memory while" 2506 " parsing NK record at offset 0x%.8X.", offset); 2507 goto fail; 2508 } 2509 2510 if(!regfi_lock(file, file->cb_lock, "regfi_parse_nk")) 2511 goto fail; 2512 2356 2513 if(!regfi_parse_cell(file->cb, offset, nk_header, REGFI_NK_MIN_LENGTH, 2357 2514 &cell_length, &unalloc)) … … 2359 2516 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header" 2360 2517 " while parsing NK record at offset 0x%.8X.", offset); 2361 return NULL; 2362 } 2363 2364 /* A bit of validation before bothering to allocate memory */ 2518 goto fail_locked; 2519 } 2520 2365 2521 if((nk_header[0x0] != 'n') || (nk_header[0x1] != 'k')) 2366 2522 { 2367 2523 regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing" 2368 2524 " NK record at offset 0x%.8X.", offset); 2369 return NULL; 2370 } 2371 2372 ret_val = talloc(NULL, REGFI_NK_REC); 2373 if(ret_val == NULL) 2374 { 2375 regfi_add_message(file, REGFI_MSG_ERROR, "Failed to allocate memory while" 2376 " parsing NK record at offset 0x%.8X.", offset); 2377 return NULL; 2525 goto fail_locked; 2378 2526 } 2379 2527 … … 2390 2538 regfi_add_message(file, REGFI_MSG_WARN, "A length check failed while" 2391 2539 " parsing NK record at offset 0x%.8X.", offset); 2392 talloc_free(ret_val); 2393 return NULL; 2540 goto fail_locked; 2394 2541 } 2395 2542 … … 2414 2561 && (ret_val->mtime.high < REGFI_MTIME_MIN_HIGH 2415 2562 || ret_val->mtime.high > REGFI_MTIME_MAX_HIGH)) 2416 { 2417 talloc_free(ret_val); 2418 return NULL; 2419 } 2563 { goto fail_locked; } 2420 2564 2421 2565 ret_val->unknown1 = IVAL(nk_header, 0xC); … … 2446 2590 regfi_add_message(file, REGFI_MSG_ERROR, "Contents too large for cell" 2447 2591 " while parsing NK record at offset 0x%.8X.", offset); 2448 talloc_free(ret_val); 2449 return NULL; 2592 goto fail_locked; 2450 2593 } 2451 2594 else … … 2466 2609 ret_val->keyname_raw = talloc_array(ret_val, uint8_t, ret_val->name_length); 2467 2610 if(ret_val->keyname_raw == NULL) 2468 { 2469 talloc_free(ret_val); 2470 return NULL; 2471 } 2611 goto fail_locked; 2472 2612 2473 2613 /* Don't need to seek, should be at the right offset */ … … 2478 2618 regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read key name" 2479 2619 " while parsing NK record at offset 0x%.8X.", offset); 2480 talloc_free(ret_val); 2481 return NULL; 2482 } 2620 goto fail_locked; 2621 } 2622 2623 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_nk")) 2624 goto fail; 2483 2625 2484 2626 return ret_val; 2627 2628 fail_locked: 2629 regfi_unlock(file, file->cb_lock, "regfi_parse_nk"); 2630 fail: 2631 talloc_free(ret_val); 2632 return NULL; 2485 2633 } 2486 2634 … … 2494 2642 bool unalloc = false; 2495 2643 2496 if(*name_length > 0 && offset != REGFI_OFFSET_NONE 2497 && (offset & 0x00000007) == 0) 2498 { 2499 if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc)) 2500 { 2501 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header" 2644 if(*name_length <= 0 || offset == REGFI_OFFSET_NONE 2645 || (offset & 0x00000007) != 0) 2646 { goto fail; } 2647 2648 if(!regfi_lock(file, file->cb_lock, "regfi_parse_classname")) 2649 goto fail; 2650 2651 if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc)) 2652 { 2653 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header" 2654 " while parsing class name at offset 0x%.8X.", offset); 2655 goto fail_locked; 2656 } 2657 2658 if((cell_length & 0x0000007) != 0) 2659 { 2660 regfi_add_message(file, REGFI_MSG_ERROR, "Cell length not a multiple of 8" 2661 " while parsing class name at offset 0x%.8X.", offset); 2662 goto fail_locked; 2663 } 2664 2665 if(cell_length > max_size) 2666 { 2667 regfi_add_message(file, REGFI_MSG_WARN, "Cell stretches past hbin " 2668 "boundary while parsing class name at offset 0x%.8X.", 2669 offset); 2670 if(strict) 2671 goto fail_locked; 2672 cell_length = max_size; 2673 } 2674 2675 if((cell_length - 4) < *name_length) 2676 { 2677 regfi_add_message(file, REGFI_MSG_WARN, "Class name is larger than" 2678 " cell_length while parsing class name at offset" 2679 " 0x%.8X.", offset); 2680 if(strict) 2681 goto fail_locked; 2682 *name_length = cell_length - 4; 2683 } 2684 2685 ret_val = talloc_array(NULL, uint8_t, *name_length); 2686 if(ret_val != NULL) 2687 { 2688 length = *name_length; 2689 if((regfi_read(file->cb, ret_val, &length) != 0) 2690 || length != *name_length) 2691 { 2692 regfi_add_message(file, REGFI_MSG_ERROR, "Could not read class name" 2502 2693 " while parsing class name at offset 0x%.8X.", offset); 2503 return NULL; 2504 } 2505 2506 if((cell_length & 0x0000007) != 0) 2507 { 2508 regfi_add_message(file, REGFI_MSG_ERROR, "Cell length not a multiple of 8" 2509 " while parsing class name at offset 0x%.8X.", offset); 2510 return NULL; 2511 } 2512 2513 if(cell_length > max_size) 2514 { 2515 regfi_add_message(file, REGFI_MSG_WARN, "Cell stretches past hbin " 2516 "boundary while parsing class name at offset 0x%.8X.", 2517 offset); 2518 if(strict) 2519 return NULL; 2520 cell_length = max_size; 2521 } 2522 2523 if((cell_length - 4) < *name_length) 2524 { 2525 regfi_add_message(file, REGFI_MSG_WARN, "Class name is larger than" 2526 " cell_length while parsing class name at offset" 2527 " 0x%.8X.", offset); 2528 if(strict) 2529 return NULL; 2530 *name_length = cell_length - 4; 2531 } 2532 2533 ret_val = talloc_array(NULL, uint8_t, *name_length); 2534 if(ret_val != NULL) 2535 { 2536 length = *name_length; 2537 if((regfi_read(file->cb, ret_val, &length) != 0) 2538 || length != *name_length) 2539 { 2540 regfi_add_message(file, REGFI_MSG_ERROR, "Could not read class name" 2541 " while parsing class name at offset 0x%.8X.", offset); 2542 talloc_free(ret_val); 2543 return NULL; 2544 } 2545 } 2546 } 2694 goto fail_locked; 2695 } 2696 } 2697 2698 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_classname")) 2699 goto fail; 2547 2700 2548 2701 return ret_val; 2702 2703 fail_locked: 2704 regfi_unlock(file, file->cb_lock, "regfi_parse_classname"); 2705 fail: 2706 talloc_free(ret_val); 2707 return NULL; 2549 2708 } 2550 2709 … … 2560 2719 bool unalloc = false; 2561 2720 2721 ret_val = talloc(NULL, REGFI_VK_REC); 2722 if(ret_val == NULL) 2723 goto fail; 2724 2725 if(!regfi_lock(file, file->cb_lock, "regfi_parse_nk")) 2726 goto fail; 2727 2562 2728 if(!regfi_parse_cell(file->cb, offset, vk_header, REGFI_VK_MIN_LENGTH, 2563 2729 &cell_length, &unalloc)) … … 2565 2731 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header" 2566 2732 " while parsing VK record at offset 0x%.8X.", offset); 2567 return NULL; 2568 } 2569 2570 ret_val = talloc(NULL, REGFI_VK_REC); 2571 if(ret_val == NULL) 2572 return NULL; 2733 goto fail_locked; 2734 } 2573 2735 2574 2736 ret_val->offset = offset; … … 2584 2746 regfi_add_message(file, REGFI_MSG_WARN, "Invalid cell size encountered" 2585 2747 " while parsing VK record at offset 0x%.8X.", offset); 2586 talloc_free(ret_val); 2587 return NULL; 2748 goto fail_locked; 2588 2749 } 2589 2750 … … 2598 2759 regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch" 2599 2760 " while parsing VK record at offset 0x%.8X.", offset); 2600 talloc_free(ret_val); 2601 return NULL; 2761 goto fail_locked; 2602 2762 } 2603 2763 … … 2622 2782 offset); 2623 2783 if(strict) 2624 { 2625 talloc_free(ret_val); 2626 return NULL; 2627 } 2784 goto fail_locked; 2628 2785 else 2629 2786 ret_val->name_length = ret_val->cell_size - REGFI_VK_MIN_LENGTH - 4; … … 2637 2794 ret_val->valuename_raw = talloc_array(ret_val, uint8_t, ret_val->name_length); 2638 2795 if(ret_val->valuename_raw == NULL) 2639 { 2640 talloc_free(ret_val); 2641 return NULL; 2642 } 2796 goto fail_locked; 2643 2797 2644 2798 length = ret_val->name_length; … … 2648 2802 regfi_add_message(file, REGFI_MSG_ERROR, "Could not read value name" 2649 2803 " while parsing VK record at offset 0x%.8X.", offset); 2650 talloc_free(ret_val); 2651 return NULL; 2804 goto fail_locked; 2652 2805 } 2653 2806 } 2654 2807 else 2655 2808 cell_length = REGFI_VK_MIN_LENGTH + 4; 2809 2810 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_nk")) 2811 goto fail; 2656 2812 2657 2813 if(unalloc) … … 2663 2819 2664 2820 return ret_val; 2821 2822 fail_locked: 2823 regfi_unlock(file, file->cb_lock, "regfi_parse_vk"); 2824 fail: 2825 talloc_free(ret_val); 2826 return NULL; 2665 2827 } 2666 2828 … … 2711 2873 } 2712 2874 2875 if(!regfi_lock(file, file->cb_lock, "regfi_load_data")) 2876 goto fail; 2877 2713 2878 if(!regfi_parse_cell(file->cb, offset, NULL, 0, 2714 2879 &cell_length, &unalloc)) … … 2716 2881 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while" 2717 2882 " parsing data record at offset 0x%.8X.", offset); 2883 goto fail_locked; 2884 } 2885 2886 if(!regfi_unlock(file, file->cb_lock, "regfi_load_data")) 2718 2887 goto fail; 2719 }2720 2888 2721 2889 if((cell_length & 0x00000007) != 0) … … 2765 2933 return ret_val; 2766 2934 2935 fail_locked: 2936 regfi_unlock(file, file->cb_lock, "regfi_load_data"); 2767 2937 fail: 2768 2938 ret_val.buf = NULL; … … 2784 2954 ret_val.len = 0; 2785 2955 2956 if((ret_val.buf = talloc_array(NULL, uint8_t, length)) == NULL) 2957 goto fail; 2958 ret_val.len = length; 2959 2960 if(!regfi_lock(file, file->cb_lock, "regfi_parse_data")) 2961 goto fail; 2962 2786 2963 if(regfi_seek(file->cb, offset+4, SEEK_SET) == -1) 2787 2964 { 2788 2965 regfi_add_message(file, REGFI_MSG_WARN, "Could not seek while " 2789 2966 "reading data at offset 0x%.8X.", offset); 2790 return ret_val; 2791 } 2792 2793 if((ret_val.buf = talloc_array(NULL, uint8_t, length)) == NULL) 2794 return ret_val; 2795 ret_val.len = length; 2967 goto fail_locked; 2968 } 2796 2969 2797 2970 read_length = length; … … 2801 2974 regfi_add_message(file, REGFI_MSG_ERROR, "Could not read data block while" 2802 2975 " parsing data record at offset 0x%.8X.", offset); 2803 talloc_free(ret_val.buf); 2804 ret_val.buf = NULL; 2805 ret_val.buf = 0; 2806 } 2807 2976 goto fail_locked; 2977 } 2978 2979 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_data")) 2980 goto fail; 2981 2982 return ret_val; 2983 2984 fail_locked: 2985 regfi_unlock(file, file->cb_lock, "regfi_parse_data"); 2986 fail: 2987 talloc_free(ret_val.buf); 2988 ret_val.buf = NULL; 2989 ret_val.buf = 0; 2808 2990 return ret_val; 2809 2991 } … … 2862 3044 } 2863 3045 3046 if(!regfi_lock(file, file->cb_lock, "regfi_parse_big_data_header")) 3047 goto fail; 3048 3049 2864 3050 if(!regfi_parse_cell(file->cb, offset, ret_val.buf, REGFI_BIG_DATA_MIN_LENGTH, 2865 3051 &cell_length, &unalloc)) … … 2867 3053 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while" 2868 3054 " parsing big data header at offset 0x%.8X.", offset); 2869 goto fail; 2870 } 3055 goto fail_locked; 3056 } 3057 3058 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_big_data_header")) 3059 goto fail; 2871 3060 2872 3061 if((ret_val.buf[0] != 'd') || (ret_val.buf[1] != 'b')) … … 2882 3071 return ret_val; 2883 3072 3073 fail_locked: 3074 regfi_unlock(file, file->cb_lock, "regfi_parse_big_data_header"); 2884 3075 fail: 2885 if(ret_val.buf != NULL) 2886 { 2887 talloc_free(ret_val.buf); 2888 ret_val.buf = NULL; 2889 } 3076 talloc_free(ret_val.buf); 3077 ret_val.buf = NULL; 2890 3078 ret_val.len = 0; 2891 3079 return ret_val; … … 2916 3104 goto fail; 2917 3105 3106 if(!regfi_lock(file, file->cb_lock, "regfi_parse_big_data_indirect")) 3107 goto fail; 3108 2918 3109 if(!regfi_parse_cell(file->cb, offset, (uint8_t*)ret_val, 2919 3110 num_chunks*sizeof(uint32_t), … … 2923 3114 " parsing big data indirect record at offset 0x%.8X.", 2924 3115 offset); 2925 goto fail; 2926 } 3116 goto fail_locked; 3117 } 3118 3119 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_big_data_indirect")) 3120 goto fail; 2927 3121 2928 3122 /* Convert pointers to proper endianess, verify they are aligned. */ … … 2936 3130 return ret_val; 2937 3131 3132 fail_locked: 3133 regfi_unlock(file, file->cb_lock, "regfi_parse_big_data_indirect"); 2938 3134 fail: 2939 if(ret_val != NULL) 2940 talloc_free(ret_val); 3135 talloc_free(ret_val); 2941 3136 return NULL; 2942 3137 } … … 2970 3165 for(i=0; i<num_chunks; i++) 2971 3166 { 3167 if(!regfi_lock(file, file->cb_lock, "regfi_parse_big_data_cells")) 3168 goto fail; 3169 2972 3170 chunk_offset = offsets[i]+REGFI_REGF_SIZE; 2973 3171 if(!regfi_parse_cell(file->cb, chunk_offset, NULL, 0, … … 2977 3175 " parsing big data chunk at offset 0x%.8X.", 2978 3176 chunk_offset); 3177 goto fail_locked; 3178 } 3179 3180 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_big_data_cells")) 2979 3181 goto fail; 2980 }2981 3182 2982 3183 if(!range_list_add(ret_val, chunk_offset, cell_length, NULL)) … … 2986 3187 return ret_val; 2987 3188 3189 fail_locked: 3190 regfi_unlock(file, file->cb_lock, "regfi_parse_big_data_cells"); 2988 3191 fail: 2989 3192 if(ret_val != NULL) … … 3079 3282 } 3080 3283 3284 if(!regfi_lock(file, file->cb_lock, "regfi_load_big_data")) 3285 goto fail; 3286 3081 3287 if(regfi_seek(file->cb, cell_info->offset+sizeof(uint32_t), SEEK_SET) == -1) 3082 3288 { … … 3084 3290 "constructing big data at offset 0x%.8X " 3085 3291 "(chunk offset 0x%.8X).", offset, cell_info->offset); 3086 goto fail ;3292 goto fail_locked; 3087 3293 } 3088 3294 … … 3094 3300 " constructing big data at offset 0x%.8X" 3095 3301 " (chunk offset 0x%.8X).", offset, cell_info->offset); 3302 goto fail_locked; 3303 } 3304 3305 if(!regfi_unlock(file, file->cb_lock, "regfi_load_big_data")) 3096 3306 goto fail; 3097 }3098 3307 3099 3308 if(used_ranges != NULL) … … 3108 3317 return ret_val; 3109 3318 3319 fail_locked: 3320 regfi_unlock(file, file->cb_lock, "regfi_load_big_data"); 3110 3321 fail: 3111 if(ret_val.buf != NULL) 3112 talloc_free(ret_val.buf); 3113 if(indirect_ptrs != NULL) 3114 talloc_free(indirect_ptrs); 3322 talloc_free(ret_val.buf); 3323 talloc_free(indirect_ptrs); 3115 3324 if(bd_cells != NULL) 3116 3325 range_list_free(bd_cells); … … 3133 3342 return NULL; 3134 3343 3344 if(!regfi_read_lock(file, file->hbins_lock, "regfi_parse_unalloc_cells")) 3345 { 3346 range_list_free(ret_val); 3347 return NULL; 3348 } 3349 3135 3350 num_hbins = range_list_size(file->hbins); 3136 3351 for(i=0; i<num_hbins; i++) … … 3144 3359 while(curr_off < hbin->block_size) 3145 3360 { 3361 if(!regfi_lock(file, file->cb_lock, "regfi_parse_unalloc_cells")) 3362 break; 3363 3146 3364 if(!regfi_parse_cell(file->cb, hbin->file_off+curr_off, NULL, 0, 3147 3365 &cell_len, &is_unalloc)) 3366 { 3367 regfi_unlock(file, file->cb_lock, "regfi_parse_unalloc_cells"); 3148 3368 break; 3149 3369 } 3370 3371 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_unalloc_cells")) 3372 break; 3373 3150 3374 if((cell_len == 0) || ((cell_len & 0x00000007) != 0)) 3151 3375 { … … 3171 3395 } 3172 3396 3397 if(!regfi_rw_unlock(file, file->hbins_lock, "regfi_parse_unalloc_cells")) 3398 { 3399 range_list_free(ret_val); 3400 return NULL; 3401 } 3402 3173 3403 return ret_val; 3174 3404 }
Note: See TracChangeset
for help on using the changeset viewer.