[FL-3643] Fix crash when reading files > 64B (#3166)
* Increase MF DESFire result buffer * Ignore chunks that do not fit into the result buffer and show warning * Display information about partial files Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									3d872cf37a
								
							
						
					
					
						commit
						cfaf745523
					
				@ -190,6 +190,8 @@ void nfc_render_mf_desfire_file_settings_data(
 | 
				
			|||||||
    uint32_t record_count = 1;
 | 
					    uint32_t record_count = 1;
 | 
				
			||||||
    uint32_t record_size = 0;
 | 
					    uint32_t record_size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const uint32_t total_size = simple_array_get_count(data->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch(settings->type) {
 | 
					    switch(settings->type) {
 | 
				
			||||||
    case MfDesfireFileTypeStandard:
 | 
					    case MfDesfireFileTypeStandard:
 | 
				
			||||||
    case MfDesfireFileTypeBackup:
 | 
					    case MfDesfireFileTypeBackup:
 | 
				
			||||||
@ -220,9 +222,20 @@ void nfc_render_mf_desfire_file_settings_data(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(uint32_t rec = 0; rec < record_count; rec++) {
 | 
					    for(uint32_t rec = 0; rec < record_count; rec++) {
 | 
				
			||||||
 | 
					        const uint32_t size_offset = rec * record_size;
 | 
				
			||||||
 | 
					        const uint32_t size_remaining = total_size > size_offset ? total_size - size_offset : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(size_remaining < record_size) {
 | 
				
			||||||
 | 
					            furi_string_cat_printf(
 | 
				
			||||||
 | 
					                str, "record %lu (partial %lu of %lu)\n", rec, size_remaining, record_size);
 | 
				
			||||||
 | 
					            record_size = size_remaining;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
            furi_string_cat_printf(str, "record %lu\n", rec);
 | 
					            furi_string_cat_printf(str, "record %lu\n", rec);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(uint32_t ch = 0; ch < record_size; ch += 4) {
 | 
					        for(uint32_t ch = 0; ch < record_size; ch += 4) {
 | 
				
			||||||
            furi_string_cat_printf(str, "%03lx|", ch);
 | 
					            furi_string_cat_printf(str, "%03lx|", ch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for(uint32_t i = 0; i < 4; i++) {
 | 
					            for(uint32_t i = 0; i < 4; i++) {
 | 
				
			||||||
                if(ch + i < record_size) {
 | 
					                if(ch + i < record_size) {
 | 
				
			||||||
                    const uint32_t data_index = rec * record_size + ch + i;
 | 
					                    const uint32_t data_index = rec * record_size + ch + i;
 | 
				
			||||||
@ -233,6 +246,7 @@ void nfc_render_mf_desfire_file_settings_data(
 | 
				
			|||||||
                    furi_string_cat_printf(str, "   ");
 | 
					                    furi_string_cat_printf(str, "   ");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for(uint32_t i = 0; i < 4 && ch + i < record_size; i++) {
 | 
					            for(uint32_t i = 0; i < 4 && ch + i < record_size; i++) {
 | 
				
			||||||
                const uint32_t data_index = rec * record_size + ch + i;
 | 
					                const uint32_t data_index = rec * record_size + ch + i;
 | 
				
			||||||
                const uint8_t data_byte =
 | 
					                const uint8_t data_byte =
 | 
				
			||||||
@ -243,8 +257,10 @@ void nfc_render_mf_desfire_file_settings_data(
 | 
				
			|||||||
                    furi_string_cat_printf(str, ".");
 | 
					                    furi_string_cat_printf(str, ".");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            furi_string_push_back(str, '\n');
 | 
					            furi_string_push_back(str, '\n');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        furi_string_push_back(str, '\n');
 | 
					        furi_string_push_back(str, '\n');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define TAG "MfDesfirePoller"
 | 
					#define TAG "MfDesfirePoller"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MF_DESFIRE_BUF_SIZE_MAX (64U)
 | 
					#define MF_DESFIRE_BUF_SIZE (64U)
 | 
				
			||||||
 | 
					#define MF_DESFIRE_RESULT_BUF_SIZE (512U)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef NfcCommand (*MfDesfirePollerReadHandler)(MfDesfirePoller* instance);
 | 
					typedef NfcCommand (*MfDesfirePollerReadHandler)(MfDesfirePoller* instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -20,10 +21,10 @@ static MfDesfirePoller* mf_desfire_poller_alloc(Iso14443_4aPoller* iso14443_4a_p
 | 
				
			|||||||
    MfDesfirePoller* instance = malloc(sizeof(MfDesfirePoller));
 | 
					    MfDesfirePoller* instance = malloc(sizeof(MfDesfirePoller));
 | 
				
			||||||
    instance->iso14443_4a_poller = iso14443_4a_poller;
 | 
					    instance->iso14443_4a_poller = iso14443_4a_poller;
 | 
				
			||||||
    instance->data = mf_desfire_alloc();
 | 
					    instance->data = mf_desfire_alloc();
 | 
				
			||||||
    instance->tx_buffer = bit_buffer_alloc(MF_DESFIRE_BUF_SIZE_MAX);
 | 
					    instance->tx_buffer = bit_buffer_alloc(MF_DESFIRE_BUF_SIZE);
 | 
				
			||||||
    instance->rx_buffer = bit_buffer_alloc(MF_DESFIRE_BUF_SIZE_MAX);
 | 
					    instance->rx_buffer = bit_buffer_alloc(MF_DESFIRE_BUF_SIZE);
 | 
				
			||||||
    instance->input_buffer = bit_buffer_alloc(MF_DESFIRE_BUF_SIZE_MAX);
 | 
					    instance->input_buffer = bit_buffer_alloc(MF_DESFIRE_BUF_SIZE);
 | 
				
			||||||
    instance->result_buffer = bit_buffer_alloc(MF_DESFIRE_BUF_SIZE_MAX);
 | 
					    instance->result_buffer = bit_buffer_alloc(MF_DESFIRE_RESULT_BUF_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    instance->mf_desfire_event.data = &instance->mf_desfire_event_data;
 | 
					    instance->mf_desfire_event.data = &instance->mf_desfire_event_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,15 @@ MfDesfireError mf_desfire_send_chunks(
 | 
				
			|||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const size_t rx_size = bit_buffer_get_size_bytes(instance->rx_buffer);
 | 
				
			||||||
 | 
					            const size_t rx_capacity_remaining =
 | 
				
			||||||
 | 
					                bit_buffer_get_capacity_bytes(rx_buffer) - bit_buffer_get_size_bytes(rx_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(rx_size <= rx_capacity_remaining) {
 | 
				
			||||||
                bit_buffer_append_right(rx_buffer, instance->rx_buffer, sizeof(uint8_t));
 | 
					                bit_buffer_append_right(rx_buffer, instance->rx_buffer, sizeof(uint8_t));
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                FURI_LOG_W(TAG, "RX buffer overflow: ignoring %zu bytes", rx_size);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } while(false);
 | 
					    } while(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user