summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2020-09-06 21:04:08 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2020-09-06 21:04:08 +0200
commite07e4692d578783cc78c4ea52138930b8084a961 (patch)
tree19d3f30232e1f1f49c163e4bc45f2f5f288b9b2a
parent90cdd0bd88b4f690871017daa21e04a9bb3e99b2 (diff)
src/file_tiff*: better frama-c annotations, free memory in reverse order
of allocations
-rw-r--r--src/file_tiff.c6
-rw-r--r--src/file_tiff.h50
-rw-r--r--src/file_tiff_be.c17
-rw-r--r--src/file_tiff_le.c36
4 files changed, 72 insertions, 37 deletions
diff --git a/src/file_tiff.c b/src/file_tiff.c
index b30064f..00bc828 100644
--- a/src/file_tiff.c
+++ b/src/file_tiff.c
@@ -20,6 +20,7 @@
*/
+#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_tiff) || defined(SINGLE_FORMAT_jpg)
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -53,8 +54,6 @@ const file_hint_t file_hint_tiff= {
.register_header_check=&register_header_check_tiff
};
-/* @ ensures \result == 1 || \result == 2 || \result == 4 || \result == 8;
- */
unsigned int tiff_type2size(const unsigned int type)
{
switch(type)
@@ -185,10 +184,13 @@ static void register_header_check_tiff(file_stat_t *file_stat)
{
static const unsigned char tiff_header_be[4]= { 'M','M',0x00, 0x2a};
static const unsigned char tiff_header_le[4]= { 'I','I',0x2a, 0x00};
+#if !defined(SINGLE_FORMAT_jpg)
#if !defined(MAIN_tiff_le) && !defined(MAIN_jpg)
register_header_check(0, tiff_header_be, sizeof(tiff_header_be), &header_check_tiff_be, file_stat);
#endif
#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg)
register_header_check(0, tiff_header_le, sizeof(tiff_header_le), &header_check_tiff_le, file_stat);
#endif
+#endif
}
+#endif
diff --git a/src/file_tiff.h b/src/file_tiff.h
index fa9af03..7420461 100644
--- a/src/file_tiff.h
+++ b/src/file_tiff.h
@@ -71,6 +71,7 @@ struct ifd_header {
/*@
@ requires \valid_read(buffer+(0..buffer_size-1));
@ ensures \valid_read(buffer+(0..buffer_size-1));
+ @ assigns \nothing;
@*/
time_t get_date_from_tiff_header(const unsigned char*buffer, const unsigned int buffer_size);
@@ -93,7 +94,7 @@ unsigned int find_tag_from_tiff_header(const unsigned char *buffer, const unsign
unsigned int find_tag_from_tiff_header_le(const unsigned char *buffer, const unsigned int tiff_size, const unsigned int tag, const unsigned char**potential_error);
#endif
-#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg)
+#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg) && !defined(SINGLE_FORMAT_jpg)
/*@
@ requires \valid(fr);
@ requires \valid(fr->handle);
@@ -106,24 +107,33 @@ unsigned int find_tag_from_tiff_header_le(const unsigned char *buffer, const uns
void file_check_tiff_le(file_recovery_t *fr);
/*@
- @ requires buffer_size >= 15;
+ @ requires buffer_size > 0;
@ requires \valid_read(buffer+(0..buffer_size-1));
@ requires \valid_read(file_recovery);
@ requires file_recovery->file_stat==\null || valid_read_string((char*)file_recovery->filename);
@ requires \valid(file_recovery_new);
@ requires file_recovery_new->blocksize > 0;
+ @
+ @ requires buffer_size >= 15;
+ @
@ ensures \result == 0 || \result == 1;
@ ensures (\result == 1) ==> (file_recovery_new->file_stat == \null);
@ ensures (\result == 1) ==> (file_recovery_new->handle == \null);
- @ ensures \result == 1 ==> \initialized(&file_recovery_new->time);
- @ ensures (\result == 1) ==> (file_recovery_new->calculated_file_size == 0);
+ @ ensures (\result == 1) ==> \initialized(&file_recovery_new->time);
+ @ ensures (\result == 1) ==> \initialized(&file_recovery_new->calculated_file_size);
@ ensures (\result == 1) ==> (file_recovery_new->file_size == 0);
- @ ensures (\result == 1) ==> (file_recovery_new->data_check == \null);
- @ ensures (\result == 1) ==> (file_recovery_new->file_check == &file_check_tiff_le);
- @ ensures (\result == 1) ==> (file_recovery_new->file_rename== \null);
+ @ ensures (\result == 1) ==> \initialized(&file_recovery_new->min_filesize);
+ @ ensures (\result == 1) ==> (file_recovery_new->data_check == \null || \valid_function(file_recovery_new->data_check));
+ @ ensures (\result == 1) ==> (file_recovery_new->file_check == \null || \valid_function(file_recovery_new->file_check));
+ @ ensures (\result == 1) ==> (file_recovery_new->file_rename == \null || \valid_function(file_recovery_new->file_rename));
@ ensures (\result == 1) ==> (file_recovery_new->extension != \null);
@ ensures (\result == 1) ==> valid_read_string(file_recovery_new->extension);
@ ensures (\result == 1) ==> \separated(file_recovery_new, file_recovery_new->extension);
+ @
+ @ ensures (\result == 1) ==> (file_recovery_new->calculated_file_size == 0);
+ @ ensures (\result == 1) ==> (file_recovery_new->data_check == \null);
+ @ ensures (\result == 1) ==> (file_recovery_new->file_check == &file_check_tiff_le);
+ @ ensures (\result == 1) ==> (file_recovery_new->file_rename== \null);
@*/
int header_check_tiff_le(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new);
#endif
@@ -140,30 +150,44 @@ int header_check_tiff_le(const unsigned char *buffer, const unsigned int buffer_
unsigned int find_tag_from_tiff_header_be(const unsigned char*buffer, const unsigned int tiff_size, const unsigned int tag, const unsigned char**potential_error);
#endif
-#if !defined(MAIN_tiff_le) && !defined(MAIN_jpg)
+#if !defined(MAIN_tiff_le) && !defined(MAIN_jpg) && !defined(SINGLE_FORMAT_jpg)
/*@
- @ requires buffer_size >= 15;
+ @ requires buffer_size > 0;
@ requires \valid_read(buffer+(0..buffer_size-1));
@ requires \valid_read(file_recovery);
@ requires file_recovery->file_stat==\null || valid_read_string((char*)file_recovery->filename);
@ requires \valid(file_recovery_new);
@ requires file_recovery_new->blocksize > 0;
+ @
+ @ requires buffer_size >= 15;
+ @
@ ensures \result == 0 || \result == 1;
@ ensures (\result == 1) ==> (file_recovery_new->file_stat == \null);
@ ensures (\result == 1) ==> (file_recovery_new->handle == \null);
- @ ensures \result == 1 ==> \initialized(&file_recovery_new->time);
- @ ensures (\result == 1) ==> (file_recovery_new->calculated_file_size == 0);
+ @ ensures (\result == 1) ==> \initialized(&file_recovery_new->time);
+ @ ensures (\result == 1) ==> \initialized(&file_recovery_new->calculated_file_size);
@ ensures (\result == 1) ==> (file_recovery_new->file_size == 0);
- @ ensures (\result == 1) ==> (file_recovery_new->data_check == \null);
- @ ensures (\result == 1) ==> (file_recovery_new->file_rename== \null);
+ @ ensures (\result == 1) ==> \initialized(&file_recovery_new->min_filesize);
+ @ ensures (\result == 1) ==> (file_recovery_new->data_check == \null || \valid_function(file_recovery_new->data_check));
+ @ ensures (\result == 1) ==> (file_recovery_new->file_check == \null || \valid_function(file_recovery_new->file_check));
+ @ ensures (\result == 1) ==> (file_recovery_new->file_rename == \null || \valid_function(file_recovery_new->file_rename));
@ ensures (\result == 1) ==> (file_recovery_new->extension != \null);
@ ensures (\result == 1) ==> valid_read_string(file_recovery_new->extension);
@ ensures (\result == 1) ==> \separated(file_recovery_new, file_recovery_new->extension);
+ @
+ @ ensures (\result == 1) ==> (file_recovery_new->calculated_file_size == 0);
+ @ ensures (\result == 1) ==> (file_recovery_new->data_check == \null);
+ @ ensures (\result == 1) ==> (file_recovery_new->file_rename== \null);
@*/
int header_check_tiff_be(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new);
#endif
+/*@
+ @ ensures \result == 1 || \result == 2 || \result == 4 || \result == 8;
+ @ assigns \nothing;
+ @*/
unsigned int tiff_type2size(const unsigned int type);
+
#ifdef DEBUG_TIFF
const char *tag_name(unsigned int tag);
#endif
diff --git a/src/file_tiff_be.c b/src/file_tiff_be.c
index 74bc61e..4cfeb69 100644
--- a/src/file_tiff_be.c
+++ b/src/file_tiff_be.c
@@ -20,6 +20,7 @@
*/
+#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_tiff) || defined(SINGLE_FORMAT_jpg)
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -42,7 +43,7 @@
#include "__fc_builtin.h"
#endif
-#if (!defined(MAIN_tiff_be) && !defined(MAIN_tiff_le)) || defined(MAIN_jpg)
+#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_jpg)
extern const file_hint_t file_hint_jpg;
#endif
extern const file_hint_t file_hint_tiff;
@@ -149,7 +150,6 @@ unsigned int find_tag_from_tiff_header_be(const unsigned char *buffer, const uns
return 0;
/*@ assert \valid_read(buffer+(0..tiff_size-1)); */
/*@ assert offset_ifd0 + sizeof(struct ifd_header) <= tiff_size; */
- /*X assert \valid_read(buffer+(0..offset_ifd0 + sizeof(struct ifd_header)-1)); */
{
const unsigned int tmp=find_tag_from_tiff_header_be_aux(buffer, tiff_size, tag, potential_error, offset_ifd0);
/*@ assert \valid_read(buffer+(0..tiff_size-1)); */
@@ -196,6 +196,7 @@ unsigned int find_tag_from_tiff_header_be(const unsigned char *buffer, const uns
@ requires \valid(handle);
@ requires \valid_read(entry_strip_offsets);
@ requires \valid_read(entry_strip_bytecounts);
+ @ requires \separated(handle, &errno, &Frama_C_entropy_source, &__fc_heap_status, \union(entry_strip_offsets, entry_strip_bytecounts));
@*/
static uint64_t parse_strip_be(FILE *handle, const TIFFDirEntry *entry_strip_offsets, const TIFFDirEntry *entry_strip_bytecounts)
{
@@ -235,8 +236,8 @@ static uint64_t parse_strip_be(FILE *handle, const TIFFDirEntry *entry_strip_off
if(fseek(handle, be32(entry_strip_bytecounts->tdir_offset), SEEK_SET) < 0 ||
fread(sizep, sizeof(*sizep), nbr, handle) != nbr)
{
- free(offsetp);
free(sizep);
+ free(offsetp);
return TIFF_ERROR;
}
#if defined(__FRAMAC__)
@@ -249,8 +250,8 @@ static uint64_t parse_strip_be(FILE *handle, const TIFFDirEntry *entry_strip_off
if(max_offset < tmp)
max_offset=tmp;
}
- free(offsetp);
free(sizep);
+ free(offsetp);
return max_offset;
}
@@ -258,6 +259,7 @@ static uint64_t parse_strip_be(FILE *handle, const TIFFDirEntry *entry_strip_off
@ requires type != 1 || \valid_read((const char *)val);
@ requires type != 3 || \valid_read((const char *)val + ( 0 .. 2));
@ requires type != 4 || \valid_read((const char *)val + ( 0 .. 4));
+ @ assigns \nothing;
@*/
static unsigned int tiff_be_read(const void *val, const unsigned int type)
{
@@ -380,7 +382,7 @@ static uint64_t tiff_be_makernote(FILE *in, const uint32_t tiff_diroff)
#endif
#endif
-#if !defined(MAIN_tiff_le) && !defined(MAIN_jpg)
+#if !defined(MAIN_tiff_le) && !defined(MAIN_jpg) && !defined(SINGLE_FORMAT_jpg)
static uint64_t file_check_tiff_be_aux(file_recovery_t *fr, const uint32_t tiff_diroff, const unsigned int depth, const unsigned int count);
/*@
@@ -743,9 +745,7 @@ static void file_check_tiff_be(file_recovery_t *fr)
strcmp(fr->extension,"wdp")==0)
fr->file_size=calculated_file_size;
}
-#endif
-#if !defined(MAIN_tiff_le) && !defined(MAIN_jpg)
/*@
@ requires separation: \separated(&file_hint_tiff, buffer+(..), file_recovery, file_recovery_new);
@ ensures (\result == 1) ==> (file_recovery_new->file_check == &file_check_tiff_be);
@@ -761,7 +761,7 @@ int header_check_tiff_be(const unsigned char *buffer, const unsigned int buffer_
const TIFFHeader *header=(const TIFFHeader *)buffer;
if((uint32_t)be32(header->tiff_diroff) < sizeof(TIFFHeader))
return 0;
-#if (!defined(MAIN_tiff_be) && !defined(MAIN_tiff_le)) || defined(MAIN_jpg)
+#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_jpg)
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_jpg)
{
@@ -795,6 +795,7 @@ int header_check_tiff_be(const unsigned char *buffer, const unsigned int buffer_
return 1;
}
#endif
+#endif
#if defined(MAIN_tiff_be)
#define BLOCKSIZE 65536u
diff --git a/src/file_tiff_le.c b/src/file_tiff_le.c
index 196e4c3..034e075 100644
--- a/src/file_tiff_le.c
+++ b/src/file_tiff_le.c
@@ -20,6 +20,7 @@
*/
+#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_tiff) || defined(SINGLE_FORMAT_jpg)
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -42,10 +43,10 @@
#include "__fc_builtin.h"
#endif
-#if !defined(MAIN_tiff_be) && !defined(MAIN_tiff_le) && !defined(MAIN_jpg)
+#if !defined(SINGLE_FORMAT)
extern const file_hint_t file_hint_raf;
#endif
-#if (!defined(MAIN_tiff_be) && !defined(MAIN_tiff_le)) || defined(MAIN_jpg)
+#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_jpg)
extern const file_hint_t file_hint_jpg;
#endif
extern const file_hint_t file_hint_tiff;
@@ -173,6 +174,7 @@ unsigned int find_tag_from_tiff_header_le(const unsigned char *buffer, const uns
const unsigned int nbr_fields=get_nbr_fields_le(buffer, tiff_size, offset_ifd0);
unsigned int offset_tiff_next_diroff;
offset_tiff_next_diroff=offset_ifd0 + 2 + nbr_fields * sizeof(TIFFDirEntry);
+ /*@ assert tiff_size >= 4; */
if(offset_tiff_next_diroff < tiff_size - 4)
{
const unsigned char *ptr_hdr;
@@ -198,6 +200,7 @@ unsigned int find_tag_from_tiff_header_le(const unsigned char *buffer, const uns
@ requires \valid(handle);
@ requires \valid_read(entry_strip_offsets);
@ requires \valid_read(entry_strip_bytecounts);
+ @ requires \separated(handle, &errno, &Frama_C_entropy_source, &__fc_heap_status, \union(entry_strip_offsets, entry_strip_bytecounts));
@*/
static uint64_t parse_strip_le(FILE *handle, const TIFFDirEntry *entry_strip_offsets, const TIFFDirEntry *entry_strip_bytecounts)
{
@@ -237,22 +240,25 @@ static uint64_t parse_strip_le(FILE *handle, const TIFFDirEntry *entry_strip_off
if(fseek(handle, le32(entry_strip_bytecounts->tdir_offset), SEEK_SET) < 0 ||
fread(sizep, sizeof(*sizep), nbr, handle) != nbr)
{
- free(offsetp);
free(sizep);
+ free(offsetp);
return TIFF_ERROR;
}
#if defined(__FRAMAC__)
Frama_C_make_unknown((char *)offsetp, nbr*sizeof(*offsetp));
Frama_C_make_unknown((char *)sizep, nbr*sizeof(*sizep));
#endif
+ /*@
+ @ loop assigns i, max_offset;
+ @*/
for(i=0; i<nbr; i++)
{
const uint64_t tmp=(uint64_t)le32(offsetp[i]) + le32(sizep[i]);
if(max_offset < tmp)
max_offset=tmp;
}
- free(offsetp);
free(sizep);
+ free(offsetp);
return max_offset;
}
@@ -260,6 +266,7 @@ static uint64_t parse_strip_le(FILE *handle, const TIFFDirEntry *entry_strip_off
@ requires type != 1 || \valid_read((const char *)val);
@ requires type != 3 || \valid_read((const char *)val + ( 0 .. 2));
@ requires type != 4 || \valid_read((const char *)val + ( 0 .. 4));
+ @ assigns \nothing;
@*/
static unsigned int tiff_le_read(const void *val, const unsigned int type)
{
@@ -382,7 +389,7 @@ static uint64_t tiff_le_makernote(FILE *in, const uint32_t tiff_diroff)
#endif
#endif
-#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg)
+#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg) && !defined(SINGLE_FORMAT_jpg)
static uint64_t file_check_tiff_le_aux(file_recovery_t *fr, const uint32_t tiff_diroff, const unsigned int depth, const unsigned int count);
/*@
@@ -437,17 +444,17 @@ static uint64_t file_check_tiff_le_aux(file_recovery_t *fr, const uint32_t tiff_
unsigned char buffer[8192];
unsigned int i,n;
int data_read;
- uint64_t max_offset=0;
- uint64_t alphaoffset=0;
uint64_t alphabytecount=0;
- uint64_t imageoffset=0;
+ uint64_t alphaoffset=0;
uint64_t imagebytecount=0;
- uint64_t jpegifoffset=0;
+ uint64_t imageoffset=0;
uint64_t jpegifbytecount=0;
- uint64_t strip_offsets=0;
+ uint64_t jpegifoffset=0;
+ uint64_t max_offset=0;
uint64_t strip_bytecounts=0;
- uint64_t tile_offsets=0;
+ uint64_t strip_offsets=0;
uint64_t tile_bytecounts=0;
+ uint64_t tile_offsets=0;
unsigned int tdir_tag_old=0;
unsigned int sorted_tag_error=0;
const TIFFDirEntry *entries=(const TIFFDirEntry *)&buffer[2];
@@ -748,7 +755,7 @@ void file_check_tiff_le(file_recovery_t *fr)
}
#endif
-#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg)
+#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg) && !defined(SINGLE_FORMAT_jpg)
/*@
@ requires separation: \separated(&file_hint_tiff, buffer+(..), file_recovery, file_recovery_new);
@ ensures (\result == 1) ==> (file_recovery_new->extension == file_hint_tiff.extension ||
@@ -767,7 +774,7 @@ int header_check_tiff_le(const unsigned char *buffer, const unsigned int buffer_
return 0;
/* Avoid a false positiv with some RAF files */
if(file_recovery->file_stat!=NULL &&
-#if !defined(MAIN_tiff_be) && !defined(MAIN_tiff_le) && !defined(MAIN_jpg)
+#if !defined(SINGLE_FORMAT)
file_recovery->file_stat->file_hint==&file_hint_raf &&
#endif
memcmp(buffer, raf_fp, 15)==0)
@@ -775,7 +782,7 @@ int header_check_tiff_le(const unsigned char *buffer, const unsigned int buffer_
header_ignored(file_recovery_new);
return 0;
}
-#if (!defined(MAIN_tiff_be) && !defined(MAIN_tiff_le)) || defined(MAIN_jpg)
+#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_jpg)
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_jpg)
{
@@ -814,6 +821,7 @@ int header_check_tiff_le(const unsigned char *buffer, const unsigned int buffer_
return 1;
}
#endif
+#endif
#if defined(MAIN_tiff_le)
#define BLOCKSIZE 65536u