Skip to content

Commit 607d6ff

Browse files
committed
adf_dir / adfGetRDirEnt: prevent OOM error in case of invalid linking.
The recent corrections (4cfa5f3, 1327704) allowing to read volumes containing invalid (looping) linking might not address all the cases (hard to predict what other tricks could have been used...). To prevent any OOM crashes in other cases like this, an additional mechanism is added. It limits the number of levels when traversing directories. The AmigaOS has the limit of 256 characters for the path, but the limit is set somewhat higher, to 512 levels (what, on valid volumes, should never be reached). Anyway, this will prevent any OOM crashes related to such cases.
1 parent c9cdc61 commit 607d6ff

1 file changed

Lines changed: 28 additions & 6 deletions

File tree

src/adf_dir.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include <string.h>
4040

4141

42+
#define ADF_DIR_MAX_LEVELS 512u
43+
4244
static void adfStrToUpper( uint8_t * const nstr,
4345
const uint8_t * const ostr,
4446
const unsigned nlen,
@@ -145,13 +147,22 @@ struct AdfList * adfGetDirEnt( const struct AdfVolume * const vol,
145147
}
146148

147149
/*
148-
* adfGetRDirEnt
150+
* adfGetRDirEntLimited
149151
*
150152
*/
151-
struct AdfList * adfGetRDirEnt( const struct AdfVolume * const vol,
152-
const ADF_SECTNUM nSect,
153-
const bool recurs )
153+
static struct AdfList * adfGetRDirEntLimited( const struct AdfVolume * const vol,
154+
const ADF_SECTNUM nSect,
155+
const bool recurs,
156+
const unsigned level )
154157
{
158+
if ( level > ADF_DIR_MAX_LEVELS ) {
159+
adfEnv.eFct( "%s: Too many levels (>%u), check the volume's filesystem for "
160+
"errors (possible invalid linking between internal data structures). "
161+
"This also means 'path too long' on AmigaOS (max. 256 characters!).",
162+
__func__, ADF_DIR_MAX_LEVELS );
163+
return NULL;
164+
}
165+
155166
struct AdfList *cell, *head;
156167
struct AdfEntry * entry;
157168
struct AdfEntryBlock parent, entryBlk;
@@ -192,8 +203,8 @@ struct AdfList * adfGetRDirEnt( const struct AdfVolume * const vol,
192203
}
193204

194205
if ( recurs && entry->type == ADF_ST_DIR )
195-
cell->subdir = adfGetRDirEnt( vol, entry->sector, recurs );
196-
206+
cell->subdir = adfGetRDirEntLimited( vol, entry->sector, recurs,
207+
level + 1 );
197208
if ( entryBlk.nextSameHash == 0 )
198209
break;
199210

@@ -258,6 +269,17 @@ struct AdfList * adfGetRDirEnt( const struct AdfVolume * const vol,
258269
return head;
259270
}
260271

272+
/*
273+
* adfGetRDirEnt
274+
*
275+
*/
276+
struct AdfList * adfGetRDirEnt( const struct AdfVolume * const vol,
277+
const ADF_SECTNUM nSect,
278+
const bool recurs )
279+
{
280+
return adfGetRDirEntLimited( vol, nSect, recurs, 0 );
281+
}
282+
261283
/*
262284
* adfFreeDirList
263285
*

0 commit comments

Comments
 (0)