Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Any and all contributions are welcome. Included is also a `cadius.pro` file you

## Changelog

#### 1.4.5
- Fix `os_GetFolderFiles` calloc too small.
- AppleSingle check for OOB accesses (thanks [@peterferrie](https://github.com/peterferrie)). [#34](https://github.com/mach-kernel/cadius/pull/34)

#### 1.4.4
- Fix 140KiB volume size assertion (thanks [@inexorabletash](https://github.com/inexorabletash)): [#30](https://github.com/mach-kernel/cadius/pull/27)

Expand Down
39 changes: 24 additions & 15 deletions Src/File_AppleSingle.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ static uint16_t as_field16(uint16_t num)
* @param buf
* @return
*/
bool ASIsAppleSingle(unsigned char *buf)
bool ASIsAppleSingle(unsigned char *buf, size_t buflen)
{
if (buflen < sizeof(AS_MAGIC)) return false;
int buf_magic;
memcpy(&buf_magic, buf, sizeof(AS_MAGIC));
buf_magic = as_field32(buf_magic);
Expand All @@ -35,9 +36,11 @@ bool ASIsAppleSingle(unsigned char *buf)
* @param buf The buffer
* @return
*/
struct as_file_header *ASParseHeader(unsigned char *buf)
struct as_file_header *ASParseHeader(unsigned char *buf, size_t buflen)
{
if (buflen < sizeof(as_file_header)) return NULL;
struct as_file_header *header = malloc(sizeof(as_file_header));
if (!header) return NULL;
struct as_file_header *buf_header = (as_file_header *) buf;

header->magic = as_field32(buf_header->magic);
Expand All @@ -52,9 +55,11 @@ struct as_file_header *ASParseHeader(unsigned char *buf)
* @param entry_buf The entry buffer
* @return
*/
struct as_prodos_info *ASParseProdosEntry(unsigned char *entry_buf)
struct as_prodos_info *ASParseProdosEntry(unsigned char *entry_buf, size_t buflen)
{
if (buflen < sizeof(as_prodos_info)) return NULL;
struct as_prodos_info *prodos_entry = malloc(sizeof(as_prodos_info));
if (!prodos_entry) return NULL;
struct as_prodos_info *buf_prodos_entry = (as_prodos_info *) entry_buf;

prodos_entry->access = as_field16(buf_prodos_entry->access);
Expand All @@ -70,19 +75,20 @@ struct as_prodos_info *ASParseProdosEntry(unsigned char *entry_buf)
* @param buf
* @return
*/
struct as_file_entry *ASGetEntries(struct as_file_header *header, unsigned char *buf)
struct as_file_entry *ASGetEntries(struct as_file_header *header, unsigned char *buf, size_t buflen)
{
if (!header)
{
logf_error(" Error: Invalid AppleSingle file!\n");
return NULL;
}

struct as_file_entry *entries = malloc(
header->num_entries * sizeof(as_file_entry)
);
size_t entries_length = header->num_entries * sizeof(as_file_entry);
if (buflen < sizeof(as_file_header) + entries_length) return NULL;

struct as_file_entry *entries = malloc(entries_length);
struct as_file_entry *buf_entries = (as_file_entry *) (buf + sizeof(as_file_header));

memcpy(entries, buf_entries, header->num_entries * sizeof(as_file_entry));

if (IS_LITTLE_ENDIAN)
Expand All @@ -103,9 +109,10 @@ struct as_file_entry *ASGetEntries(struct as_file_header *header, unsigned char
* @param data The data
* @param data_fork_entry The data fork entry
*/
void ASDecorateDataFork(struct prodos_file *current_file, unsigned char *data, as_file_entry *data_fork_entry)
void ASDecorateDataFork(struct prodos_file *current_file, unsigned char *data, size_t datalen, as_file_entry *data_fork_entry)
{
if (data_fork_entry->entry_id != data_fork) return;
if (datalen < data_fork_entry->offset + data_fork_entry->length) return;

unsigned char *data_entry = malloc(data_fork_entry->length);
memcpy(data_entry, data + data_fork_entry->offset, data_fork_entry->length);
Expand All @@ -123,12 +130,14 @@ void ASDecorateDataFork(struct prodos_file *current_file, unsigned char *data, a
* @param data The data
* @param prodos_entry The prodos entry
*/
void ASDecorateProdosFileInfo(struct prodos_file *current_file, unsigned char *data, as_file_entry *prodos_entry)
void ASDecorateProdosFileInfo(struct prodos_file *current_file, unsigned char *data, size_t datalen, as_file_entry *prodos_entry)
{
if (prodos_entry->entry_id != prodos_file_info) return;
if (datalen < prodos_entry->offset + prodos_entry->length) return;

struct as_prodos_info *info_meta = ASParseProdosEntry(
data + prodos_entry->offset
data + prodos_entry->offset,
prodos_entry->length
);

if (!info_meta) return;
Expand All @@ -147,19 +156,19 @@ void ASDecorateProdosFileInfo(struct prodos_file *current_file, unsigned char *d
* @param current_file
* @param data
*/
void ASDecorateProdosFile(struct prodos_file *current_file, unsigned char *data)
void ASDecorateProdosFile(struct prodos_file *current_file, unsigned char *data, size_t datalen)
{
struct as_file_header *header = ASParseHeader(data);
struct as_file_entry *entries = ASGetEntries(header, data);
struct as_file_header *header = ASParseHeader(data, datalen);
struct as_file_entry *entries = ASGetEntries(header, data, datalen);

for (int i = 0; i < header->num_entries; ++i)
switch(entries[i].entry_id)
{
case data_fork:
ASDecorateDataFork(current_file, data, &entries[i]);
ASDecorateDataFork(current_file, data, datalen, &entries[i]);
break;
case prodos_file_info:
ASDecorateProdosFileInfo(current_file, data, &entries[i]);
ASDecorateProdosFileInfo(current_file, data, datalen, &entries[i]);
break;
default:
logf_info(" Entry ID %d unsupported, ignoring!\n", entries[i].entry_id);
Expand Down
14 changes: 7 additions & 7 deletions Src/File_AppleSingle.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ typedef struct as_from_prodos

#pragma pack(pop)

bool ASIsAppleSingle(unsigned char *buf);
bool ASIsAppleSingle(unsigned char *buf, size_t buflen);

struct as_file_header *ASParseHeader(unsigned char *buf);
struct as_prodos_info *ASParseProdosEntry(unsigned char *entry_buf);
struct as_file_entry *ASGetEntries(struct as_file_header *header, unsigned char *buf);
struct as_file_header *ASParseHeader(unsigned char *buf, size_t buflen);
struct as_prodos_info *ASParseProdosEntry(unsigned char *entry_buf, size_t buflen);
struct as_file_entry *ASGetEntries(struct as_file_header *header, unsigned char *buf, size_t buflen);

void ASDecorateDataFork(struct prodos_file *current_file, unsigned char *data, as_file_entry *data_fork_entry);
void ASDeocrateProdosFileInfo(struct prodos_file *current_file, unsigned char *data, as_file_entry *prodos_entry);
void ASDecorateProdosFile(struct prodos_file *current_file, unsigned char *data);
void ASDecorateDataFork(struct prodos_file *current_file, unsigned char *data, size_t datalen, as_file_entry *data_fork_entry);
void ASDeocrateProdosFileInfo(struct prodos_file *current_file, unsigned char *data, size_t datalen, as_file_entry *prodos_entry);
void ASDecorateProdosFile(struct prodos_file *current_file, unsigned char *data, size_t datalen);

struct as_from_prodos ASFromProdosFile(struct prodos_file *file);
2 changes: 1 addition & 1 deletion Src/Main.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ int main(int argc, char *argv[])
struct file_descriptive_entry *folder_entry;

/* Message Information */
logf("%s v 1.4.4 (c) Brutal Deluxe 2011-2013.\n",argv[0]);
logf("%s v 1.4.5 (c) Brutal Deluxe 2011-2013.\n",argv[0]);

/* Vérification des paramètres */
if(argc < 3)
Expand Down
4 changes: 2 additions & 2 deletions Src/Prodos_Add.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,12 @@ static struct prodos_file *LoadFile(char *file_path_data, bool zero_case_bits)
return NULL;
}

bool is_apple_single = ASIsAppleSingle(data);
bool is_apple_single = ASIsAppleSingle(data, &current_file->data_length);

if (is_apple_single)
{
logf_info(" AppleSingle format detected!\n");
ASDecorateProdosFile(current_file, data);
ASDecorateProdosFile(current_file, data, &current_file->data_length);
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion Src/os/posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ int os_GetFolderFiles(char *folder_path, char *hierarchy)
if (entry == NULL) break;

// +2 for \0 and a possible slash
char *heap_path = calloc(1, strlen(folder_path) + 2);
char *heap_path = calloc(1, strlen(folder_path) + strlen(entry->d_name) + 2);
strcpy(heap_path, folder_path);

// If there's no trailing dir slash, we append it
Expand Down