diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-10-11 14:31:18 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-10-28 15:47:16 +0900 |
commit | ffa27c70825161606a06cda017d2a82c50cfb34f (patch) | |
tree | 2644920cf9030c46a475a822ddf659a064bc31ae /src/lib/evas/cserve2/evas_cs2_client.c | |
parent | 745b4d4acc64432b5b531054b94592bee6d55340 (diff) |
evas/cserve2: prevent unwanted remap of strings table
In the client, string_get() can cause a remapping of the
strings index & mempool. This means that all pointers to
string data are invalid past that call.
Solution: add a safe_get() function that prevents remap
during search. It might prove faster also, but will
return NULL more often.
Diffstat (limited to '')
-rw-r--r-- | src/lib/evas/cserve2/evas_cs2_client.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c index 6fc1a4a112..df3573f6ef 100644 --- a/src/lib/evas/cserve2/evas_cs2_client.c +++ b/src/lib/evas/cserve2/evas_cs2_client.c | |||
@@ -74,9 +74,11 @@ static Eina_Hash *_file_entries = NULL; | |||
74 | // Shared index table | 74 | // Shared index table |
75 | static Index_Table _index; | 75 | static Index_Table _index; |
76 | static const char *_shared_string_get(int id); | 76 | static const char *_shared_string_get(int id); |
77 | static const char *_shared_string_safe_get(int id); // Do not allow remap during search | ||
78 | static Eina_Bool _string_index_refresh(void); | ||
77 | static int _server_index_list_set(Msg_Base *data, int size); | 79 | static int _server_index_list_set(Msg_Base *data, int size); |
78 | static const File_Data *_shared_file_data_get_by_id(unsigned int id); | 80 | static const File_Data *_shared_file_data_get_by_id(unsigned int id); |
79 | static const Shm_Object *_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id); | 81 | static const Shm_Object *_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id, Eina_Bool safe); |
80 | static const File_Data *_shared_image_entry_file_data_find(Image_Entry *ie); | 82 | static const File_Data *_shared_image_entry_file_data_find(Image_Entry *ie); |
81 | static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie); | 83 | static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie); |
82 | static const Font_Data *_shared_font_entry_data_find(Font_Entry *fe); | 84 | static const Font_Data *_shared_font_entry_data_find(Font_Entry *fe); |
@@ -1788,6 +1790,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints) | |||
1788 | int cnt = 0; | 1790 | int cnt = 0; |
1789 | const char *idxpath = NULL, *datapath = NULL; | 1791 | const char *idxpath = NULL, *datapath = NULL; |
1790 | 1792 | ||
1793 | _string_index_refresh(); | ||
1791 | if (!fe->map) | 1794 | if (!fe->map) |
1792 | { | 1795 | { |
1793 | const Font_Data *fd; | 1796 | const Font_Data *fd; |
@@ -1795,8 +1798,8 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints) | |||
1795 | fd = _shared_font_entry_data_find(fe); | 1798 | fd = _shared_font_entry_data_find(fe); |
1796 | if (!fd) return -1; | 1799 | if (!fd) return -1; |
1797 | 1800 | ||
1798 | idxpath = _shared_string_get(fd->glyph_index_shm); | 1801 | idxpath = _shared_string_safe_get(fd->glyph_index_shm); |
1799 | datapath = _shared_string_get(fd->mempool_shm); | 1802 | datapath = _shared_string_safe_get(fd->mempool_shm); |
1800 | if (!idxpath || !datapath) return -1; | 1803 | if (!idxpath || !datapath) return -1; |
1801 | 1804 | ||
1802 | fe->map =_glyph_map_open(fe, idxpath, datapath); | 1805 | fe->map =_glyph_map_open(fe, idxpath, datapath); |
@@ -2527,7 +2530,7 @@ _server_index_list_set(Msg_Base *data, int size) | |||
2527 | 2530 | ||
2528 | // FIXME: (almost) copy & paste from evas_cserve2_cache.c | 2531 | // FIXME: (almost) copy & paste from evas_cserve2_cache.c |
2529 | static const char * | 2532 | static const char * |
2530 | _shared_string_get(int id) | 2533 | _shared_string_internal_get(int id, Eina_Bool safe) |
2531 | { | 2534 | { |
2532 | Index_Entry *ie; | 2535 | Index_Entry *ie; |
2533 | 2536 | ||
@@ -2538,19 +2541,20 @@ _shared_string_get(int id) | |||
2538 | } | 2541 | } |
2539 | 2542 | ||
2540 | ie = (Index_Entry *) | 2543 | ie = (Index_Entry *) |
2541 | _shared_index_item_get_by_id(&_index.strings_index, sizeof(*ie), id); | 2544 | _shared_index_item_get_by_id(&_index.strings_index, sizeof(*ie), id, safe); |
2542 | if (!ie) return NULL; | 2545 | if (!ie) return NULL; |
2543 | if (ie->offset < 0) return NULL; | 2546 | if (ie->offset < 0) return NULL; |
2544 | if (!ie->refcount) return NULL; | 2547 | if (!ie->refcount) return NULL; |
2545 | if (ie->offset + ie->length > _index.strings_entries.size) | 2548 | if (ie->offset + ie->length > _index.strings_entries.size) |
2546 | { | 2549 | { |
2550 | if (safe) return NULL; | ||
2547 | if (eina_file_refresh(_index.strings_entries.f) | 2551 | if (eina_file_refresh(_index.strings_entries.f) |
2548 | || (_index.strings_entries.size != (int) eina_file_size_get(_index.strings_entries.f))) | 2552 | || (_index.strings_entries.size != (int) eina_file_size_get(_index.strings_entries.f))) |
2549 | { | 2553 | { |
2550 | DBG("String entries size has changed from %d to %d", | 2554 | DBG("String entries size has changed from %d to %d", |
2551 | _index.strings_entries.size, (int) eina_file_size_get(_index.strings_entries.f)); | 2555 | _index.strings_entries.size, (int) eina_file_size_get(_index.strings_entries.f)); |
2552 | if (_string_index_refresh()) | 2556 | if (_string_index_refresh()) |
2553 | return _shared_string_get(id); | 2557 | return _shared_string_internal_get(id, EINA_FALSE); |
2554 | } | 2558 | } |
2555 | return NULL; | 2559 | return NULL; |
2556 | } | 2560 | } |
@@ -2558,6 +2562,18 @@ _shared_string_get(int id) | |||
2558 | return _index.strings_entries.data + ie->offset; | 2562 | return _index.strings_entries.data + ie->offset; |
2559 | } | 2563 | } |
2560 | 2564 | ||
2565 | static const char * | ||
2566 | _shared_string_safe_get(int id) | ||
2567 | { | ||
2568 | return _shared_string_internal_get(id, EINA_TRUE); | ||
2569 | } | ||
2570 | |||
2571 | static const char * | ||
2572 | _shared_string_get(int id) | ||
2573 | { | ||
2574 | return _shared_string_internal_get(id, EINA_FALSE); | ||
2575 | } | ||
2576 | |||
2561 | #define SHARED_INDEX_CHECK(si, typ) \ | 2577 | #define SHARED_INDEX_CHECK(si, typ) \ |
2562 | do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \ | 2578 | do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \ |
2563 | CRIT("Failed to remap index"); return NULL; } } while (0) | 2579 | CRIT("Failed to remap index"); return NULL; } } while (0) |
@@ -2597,6 +2613,7 @@ _shared_image_entry_file_data_find(Image_Entry *ie) | |||
2597 | return fdata; | 2613 | return fdata; |
2598 | 2614 | ||
2599 | // Scan shared index | 2615 | // Scan shared index |
2616 | _string_index_refresh(); | ||
2600 | for (k = _index.files.last_entry_in_hash; | 2617 | for (k = _index.files.last_entry_in_hash; |
2601 | k < _index.files.count && k < _index.files.header->emptyidx; k++) | 2618 | k < _index.files.count && k < _index.files.header->emptyidx; k++) |
2602 | { | 2619 | { |
@@ -2609,8 +2626,8 @@ _shared_image_entry_file_data_find(Image_Entry *ie) | |||
2609 | if (!fd->id) break; | 2626 | if (!fd->id) break; |
2610 | if (!fd->refcount) continue; | 2627 | if (!fd->refcount) continue; |
2611 | 2628 | ||
2612 | key = _shared_string_get(fd->key); | 2629 | key = _shared_string_safe_get(fd->key); |
2613 | file = _shared_string_get(fd->path); | 2630 | file = _shared_string_safe_get(fd->path); |
2614 | if (!file) | 2631 | if (!file) |
2615 | { | 2632 | { |
2616 | ERR("Could not find filename for file %d: path id: %d", | 2633 | ERR("Could not find filename for file %d: path id: %d", |
@@ -2619,11 +2636,6 @@ _shared_image_entry_file_data_find(Image_Entry *ie) | |||
2619 | continue; | 2636 | continue; |
2620 | } | 2637 | } |
2621 | 2638 | ||
2622 | // Note: The strings base pointer may change if the index grows | ||
2623 | if ((key < _index.strings_entries.data) || | ||
2624 | (key > _index.strings_entries.data + _index.strings_entries.size)) | ||
2625 | key = _shared_string_get(fd->key); | ||
2626 | |||
2627 | lo.region.x = fd->lo.region.x; | 2639 | lo.region.x = fd->lo.region.x; |
2628 | lo.region.y = fd->lo.region.y; | 2640 | lo.region.y = fd->lo.region.y; |
2629 | lo.region.w = fd->lo.region.w; | 2641 | lo.region.w = fd->lo.region.w; |
@@ -2650,7 +2662,8 @@ _shared_image_entry_file_data_find(Image_Entry *ie) | |||
2650 | } | 2662 | } |
2651 | 2663 | ||
2652 | static const Shm_Object * | 2664 | static const Shm_Object * |
2653 | _shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id) | 2665 | _shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id, |
2666 | Eina_Bool safe) | ||
2654 | { | 2667 | { |
2655 | const Shm_Object *obj; | 2668 | const Shm_Object *obj; |
2656 | const char *base; | 2669 | const char *base; |
@@ -2665,7 +2678,7 @@ _shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id) | |||
2665 | 2678 | ||
2666 | if (high > si->count) | 2679 | if (high > si->count) |
2667 | { | 2680 | { |
2668 | if (eina_file_refresh(si->f)) | 2681 | if ((!safe) && eina_file_refresh(si->f)) |
2669 | { | 2682 | { |
2670 | WRN("Refreshing indexes."); | 2683 | WRN("Refreshing indexes."); |
2671 | _string_index_refresh(); | 2684 | _string_index_refresh(); |
@@ -2717,7 +2730,7 @@ static const File_Data * | |||
2717 | _shared_file_data_get_by_id(unsigned int id) | 2730 | _shared_file_data_get_by_id(unsigned int id) |
2718 | { | 2731 | { |
2719 | return (const File_Data *) | 2732 | return (const File_Data *) |
2720 | _shared_index_item_get_by_id(&_index.files, sizeof(File_Data), id); | 2733 | _shared_index_item_get_by_id(&_index.files, sizeof(File_Data), id, EINA_FALSE); |
2721 | } | 2734 | } |
2722 | 2735 | ||
2723 | static inline Eina_Bool | 2736 | static inline Eina_Bool |
@@ -2932,6 +2945,7 @@ _shared_image_entry_image_data_find(Image_Entry *ie) | |||
2932 | 2945 | ||
2933 | // Linear search in non-hashed entries. O(n) | 2946 | // Linear search in non-hashed entries. O(n) |
2934 | DBG("Looking for loaded image with file id %d", file_id); | 2947 | DBG("Looking for loaded image with file id %d", file_id); |
2948 | _string_index_refresh(); | ||
2935 | for (k = _index.images.last_entry_in_hash; k < _index.images.count; k++) | 2949 | for (k = _index.images.last_entry_in_hash; k < _index.images.count; k++) |
2936 | { | 2950 | { |
2937 | const char *file, *key; | 2951 | const char *file, *key; |
@@ -2953,8 +2967,8 @@ _shared_image_entry_image_data_find(Image_Entry *ie) | |||
2953 | continue; | 2967 | continue; |
2954 | } | 2968 | } |
2955 | 2969 | ||
2956 | key = _shared_string_get(fd->key); | 2970 | key = _shared_string_safe_get(fd->key); |
2957 | file = _shared_string_get(fd->path); | 2971 | file = _shared_string_safe_get(fd->path); |
2958 | if (!file) | 2972 | if (!file) |
2959 | { | 2973 | { |
2960 | ERR("No filename for file %d", fd->id); | 2974 | ERR("No filename for file %d", fd->id); |
@@ -2962,11 +2976,6 @@ _shared_image_entry_image_data_find(Image_Entry *ie) | |||
2962 | continue; | 2976 | continue; |
2963 | } | 2977 | } |
2964 | 2978 | ||
2965 | // Note: The strings base pointer may change if the index grows | ||
2966 | if ((key < _index.strings_entries.data) || | ||
2967 | (key > _index.strings_entries.data + _index.strings_entries.size)) | ||
2968 | key = _shared_string_get(fd->key); | ||
2969 | |||
2970 | keylen = key ? strlen(key) : 0; | 2979 | keylen = key ? strlen(key) : 0; |
2971 | filelen = strlen(file); | 2980 | filelen = strlen(file); |
2972 | 2981 | ||
@@ -2996,7 +3005,7 @@ found: | |||
2996 | return NULL; | 3005 | return NULL; |
2997 | } | 3006 | } |
2998 | 3007 | ||
2999 | shmpath = _shared_string_get(idata->shm_id); | 3008 | shmpath = _shared_string_safe_get(idata->shm_id); |
3000 | if (!shmpath) | 3009 | if (!shmpath) |
3001 | { | 3010 | { |
3002 | ERR("Found image but it is not loaded yet: %d (doload %d)", | 3011 | ERR("Found image but it is not loaded yet: %d (doload %d)", |
@@ -3012,7 +3021,7 @@ static const Font_Data * | |||
3012 | _shared_font_entry_data_get_by_id(int id) | 3021 | _shared_font_entry_data_get_by_id(int id) |
3013 | { | 3022 | { |
3014 | return (Font_Data *) | 3023 | return (Font_Data *) |
3015 | _shared_index_item_get_by_id(&_index.fonts, sizeof(Font_Data), id); | 3024 | _shared_index_item_get_by_id(&_index.fonts, sizeof(Font_Data), id, EINA_FALSE); |
3016 | } | 3025 | } |
3017 | 3026 | ||
3018 | static const Font_Data * | 3027 | static const Font_Data * |
@@ -3051,8 +3060,8 @@ _shared_font_entry_data_find(Font_Entry *fe) | |||
3051 | if (!cur->id) return NULL; | 3060 | if (!cur->id) return NULL; |
3052 | if (!cur->refcount) continue; | 3061 | if (!cur->refcount) continue; |
3053 | 3062 | ||
3054 | name = _shared_string_get(cur->name); | 3063 | name = _shared_string_safe_get(cur->name); |
3055 | source = _shared_string_get(cur->file); | 3064 | source = _shared_string_safe_get(cur->file); |
3056 | snprintf(hkey, PATH_MAX, "%s:%s/%u:%u:%u", source, name, | 3065 | snprintf(hkey, PATH_MAX, "%s:%s/%u:%u:%u", source, name, |
3057 | cur->size, cur->dpi, cur->rend_flags); | 3066 | cur->size, cur->dpi, cur->rend_flags); |
3058 | 3067 | ||