Coverage Report

Created: 2023-12-08 06:48

/src/clamav/libclamav/udf.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  Copyright (C) 2023 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
3
 *
4
 *  Authors: Cisco
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License version 2 as
8
 *  published by the Free Software Foundation.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 *  MA 02110-1301, USA.
19
 */
20
21
#ifndef _UDF_H_
22
#define _UDF_H_
23
24
#include "others.h"
25
26
#define UDF_EMPTY_LEN 32768
27
28
0
#define VOLUME_DESCRIPTOR_SIZE 0x800
29
30
#ifndef HAVE_ATTRIB_PACKED
31
#define __attribute__(x)
32
#endif
33
34
#ifdef HAVE_PRAGMA_PACK
35
#pragma pack(1)
36
#endif
37
38
#ifdef HAVE_PRAGMA_PACK_HPPA
39
#pragma pack 1
40
#endif
41
42
typedef struct __attribute__((packed)) {
43
    uint16_t typeTimeZone; /*
44
                              0     Coordinated UTC
45
                              1     Local Time
46
                              2     Up to agreement between originator and recipient
47
                              3 - 15    Reserved
48
                              */
49
    uint16_t year;
50
    uint8_t month;
51
    uint8_t day;
52
    uint8_t hour;
53
    uint8_t minute;
54
    uint8_t second;
55
    uint8_t centiseconds;
56
    uint8_t hundredsMicroSeconds;
57
    uint8_t microseconds;
58
} timestamp;
59
60
typedef struct __attribute__((packed)) {
61
62
    uint32_t blockNumber;
63
64
    uint16_t partitionReferenceNumber;
65
66
} lb_addr;
67
68
typedef struct __attribute__((packed)) {
69
    uint32_t length; //4/14.14.1.1
70
    /*30 least significant bits are length in bytes.
71
     *
72
     * 2 most significant bits are described in figure 4/42
73
     *
74
     * 0 extent recorded and allocated
75
     * 1 extent NOT recorded but allocated
76
     * 2 extent NOT recorded and NOT allocated
77
     * 3 the extent is the next extent of allocation descriptors.
78
     * */
79
80
    lb_addr extentLocation; //logical block number.  (CAN be zero)
81
82
    uint8_t implementationUse[6];
83
84
} long_ad;
85
86
/*
87
 * https://www.ecma-international.org/wp-content/uploads/ECMA-167_3rd_edition_june_1997.pdf
88
 * section 3/7.2 */
89
typedef struct __attribute__((packed)) {
90
    uint16_t tagId;
91
    uint16_t descriptorVersion;
92
    uint8_t checksum;
93
    uint8_t reserved;
94
    uint16_t serialNumber;
95
    uint16_t descriptorCRC;
96
    uint16_t descriptorCRCLength;
97
    uint32_t tagLocation;
98
} DescriptorTag;
99
100
typedef struct __attribute__((packed)) {
101
    uint8_t flags;
102
    /*
103
     * 1/7.4
104
     * characteristics
105
     * bit 0    dirty: If regid has been modified and might not be valid, set to * 1.  Otherwise, 0
106
     * bit 1    protected: If 1, this regid cannot be modified
107
     * bit 2-7  reserved
108
     */
109
    uint8_t identifier[23];
110
    /*
111
     * If first byte is 0x2b, then this is covered by ECMA-168 (this spec)
112
     * If first byte is 0x2d, then this is not registered
113
     */
114
    uint8_t identifierSuffix[8];
115
} regid;
116
117
typedef struct __attribute__((packed)) {
118
    DescriptorTag tag;
119
    uint32_t volumeDescriptorSequenceNumber;
120
    uint32_t primaryVolumeDescriptorNumber;
121
    uint8_t volumeIdentifier[32];
122
    uint16_t volumeSequenceNumber;
123
    uint16_t interchangeLevel;
124
    uint16_t maxInterchangeLevel;
125
    uint32_t charSetList;
126
    uint8_t volumeSetIdentifier[128];
127
    uint8_t descriptorCharSet[64];
128
    uint8_t explanatoryCharSet[64];
129
    uint64_t volumeAbstract;
130
    uint64_t volumeCopyrightNotice;
131
    uint8_t applicationIdentifier[32];
132
    uint8_t recordingDateTime[12];
133
    uint8_t implementationIdentifier[32];
134
    uint8_t implementationUse[64];
135
    uint32_t predVolumeDescSequenceLocation;
136
    uint16_t flags;
137
    uint8_t reserved[22];
138
139
} PrimaryVolumeDescriptor;
140
141
typedef struct __attribute__((packed)) {
142
    DescriptorTag tag;
143
    uint32_t volumeDescriptorSequenceNumber;
144
145
    regid implementationIdentifier;
146
    uint8_t implementationUse[460];
147
148
} ImplementationUseVolumeDescriptor;
149
150
/* https://www.ecma-international.org/wp-content/uploads/ECMA-167_3rd_edition_june_1997.pdf */
151
/* 4/3 */
152
typedef struct __attribute__((packed)) {
153
    uint32_t logicalBlockNumber;
154
155
    uint16_t partitionReferenceNumber;
156
} LBAddr;
157
158
//https://www.ecma-international.org/wp-content/uploads/ECMA-167_3rd_edition_june_1997.pdf
159
//section 4/23
160
typedef struct __attribute__((packed)) {
161
    uint32_t priorRecordedNumberOfDirectEntries;
162
    uint16_t strategyType;
163
    uint8_t strategyParameter[2]; /*described as 'bytes' in docs, so don't want to worry about byte order.*/
164
    uint16_t maxEntries;
165
    uint8_t reserved_must_be_zero;
166
167
    uint8_t fileType;
168
169
    LBAddr parentICBLocation;
170
171
    uint16_t flags;
172
} ICBTag;
173
174
typedef struct __attribute__((packed)) {
175
176
    DescriptorTag tag;
177
178
    uint16_t versionNumber;
179
180
    uint8_t characteristics;
181
182
    uint8_t fileIdentifierLength;
183
184
    long_ad icb;
185
186
    uint16_t implementationLength;
187
188
    uint8_t rest[1];
189
190
} FileIdentifierDescriptor;
191
192
0
#define FILE_IDENTIFIER_DESCRIPTOR_SIZE_KNOWN (sizeof(FileIdentifierDescriptor) - 1)
193
194
/*Section 14.4.9 of https:... */
195
static uint32_t getFileIdentifierDescriptorPaddingLength(const FileIdentifierDescriptor* const fid)
196
0
{
197
0
    uint32_t ret = 0;
198
0
    uint32_t tmp = fid->implementationLength + fid->fileIdentifierLength + 38;
199
0
    ret          = tmp + 3;
200
0
    ret          = ret / 4;
201
202
0
    ret = ret * 4;
203
0
    ret = ret - tmp;
204
205
0
    return ret;
206
0
}
Unexecuted instantiation: scanners.c:getFileIdentifierDescriptorPaddingLength
Unexecuted instantiation: udf.c:getFileIdentifierDescriptorPaddingLength
207
208
static inline size_t getFileIdentifierDescriptorSize(const FileIdentifierDescriptor* fid)
209
0
{
210
211
0
    return FILE_IDENTIFIER_DESCRIPTOR_SIZE_KNOWN + fid->implementationLength + fid->fileIdentifierLength + getFileIdentifierDescriptorPaddingLength(fid);
212
0
}
Unexecuted instantiation: scanners.c:getFileIdentifierDescriptorSize
Unexecuted instantiation: udf.c:getFileIdentifierDescriptorSize
213
214
typedef struct __attribute__((packed)) {
215
    DescriptorTag tag;
216
217
    ICBTag icbTag;
218
219
    uint32_t uid;
220
221
    uint32_t gid;
222
223
    uint32_t permissions;
224
225
    uint16_t fileLinkCnt;
226
227
    uint8_t recordFormat;
228
    uint8_t recordDisplayAttributes;
229
230
    uint32_t recordLength;
231
232
    uint64_t infoLength;
233
234
    uint64_t logicalBlocksRecorded;
235
236
    timestamp accessDateTime;
237
238
    timestamp modificationDateTime;
239
240
    timestamp attributeDateTime;
241
242
    uint32_t checkpoint;
243
244
    long_ad extendedAttrICB;
245
246
    regid implementationId;
247
248
    uint64_t uniqueId;
249
250
    uint32_t extendedAttrLen;
251
252
    uint32_t allocationDescLen;
253
254
    /* Variable length stuff here, need to handle;
255
    */
256
    uint8_t rest[1];
257
258
} FileEntryDescriptor;
259
260
0
#define FILE_ENTRY_DESCRIPTOR_SIZE_KNOWN (sizeof(FileEntryDescriptor) - 1)
261
static inline size_t getFileEntryDescriptorSize(const FileEntryDescriptor* fed)
262
0
{
263
0
    return FILE_ENTRY_DESCRIPTOR_SIZE_KNOWN + fed->extendedAttrLen + fed->allocationDescLen;
264
0
}
Unexecuted instantiation: scanners.c:getFileEntryDescriptorSize
Unexecuted instantiation: udf.c:getFileEntryDescriptorSize
265
266
typedef struct __attribute__((packed)) {
267
    DescriptorTag tag;
268
269
    ICBTag icbTag;
270
271
    uint32_t uid;
272
273
    uint32_t gid;
274
275
    uint32_t permissions;
276
277
    uint16_t fileLinkCnt;
278
279
    uint8_t recordFormat;
280
281
    uint8_t recordDisplayAttributes;
282
283
    uint32_t recordLength;
284
285
    uint64_t infoLength;
286
287
    uint64_t objectSize; //different
288
289
    uint64_t logicalBlocksRecorded;
290
291
    timestamp accessDateTime;
292
293
    timestamp modificationDateTime;
294
295
    timestamp creationDateTime; //different
296
297
    timestamp attributeDateTime;
298
299
    uint32_t checkpoint;
300
301
    uint32_t reserved; //different
302
303
    long_ad extendedAttrICB;
304
305
    long_ad streamDirectoryICB; //different
306
307
    regid implementationId;
308
309
    uint64_t uniqueId;
310
311
    uint32_t extendedAttrLen;
312
313
    uint32_t allocationDescLen;
314
315
    /* Variable length stuff here, need to handle;
316
    */
317
318
} ExtendedFileEntryDescriptor;
319
320
typedef struct __attribute__((packed)) {
321
322
    uint32_t length;
323
324
    uint32_t position;
325
326
} short_ad;
327
328
typedef struct __attribute__((packed)) {
329
    uint32_t extentLen;
330
    uint32_t recordedLen;
331
332
    uint32_t infoLen;
333
334
    lb_addr extentLocation;
335
336
    uint8_t implementationUse[2];
337
} ext_ad;
338
339
typedef struct __attribute__((packed)) {
340
    uint32_t extentLength;
341
342
    uint32_t extentLocation;
343
344
} extent_ad;
345
346
typedef struct __attribute__((packed)) {
347
348
    DescriptorTag tag;
349
350
    uint32_t volumeDescriptorSequenceNumber;
351
352
    uint16_t partitionFlags;
353
354
    uint16_t partitionNumber;
355
356
    regid partitionContents;
357
358
    uint8_t partitionContentsUse[128];
359
360
    uint32_t accessType;
361
362
    uint32_t partitionStartingLocation;
363
364
    uint32_t partitionLength;
365
366
    regid implementationIdentifier;
367
368
    uint8_t implementationUse[128];
369
370
    uint8_t reserved[156];
371
372
} PartitionDescriptor;
373
374
typedef struct __attribute__((packed)) {
375
    DescriptorTag tag;
376
377
    uint32_t volumeDescriptorSequenceNumber;
378
379
    uint32_t numAllocationDescriptors;
380
381
    uint8_t rest[1]; /*reset is 'numAllocationDescriptors' * sizeof (extent_ad),
382
    and padded out to VOLUME_DESCRIPTOR_SIZE with zeros. */
383
384
} UnallocatedSpaceDescriptor;
385
386
typedef struct __attribute__((packed)) {
387
    DescriptorTag tag;
388
389
    uint8_t padding[496];
390
} TerminatingDescriptor;
391
392
typedef struct __attribute__((packed)) {
393
    DescriptorTag tag;
394
395
    timestamp recordingDateTime;
396
397
    uint32_t integrityType;
398
399
    extent_ad nextIntegrityExtent;
400
401
    uint8_t logicalVolumeContents[32];
402
403
    uint32_t numPartitions;
404
405
    uint32_t lenImplementationUse;
406
407
    uint32_t freeSpaceTable;
408
409
    uint32_t sizeTable;
410
411
    uint8_t rest[1];
412
413
} LogicalVolumeIntegrityDescriptor;
414
415
typedef struct __attribute__((packed)) {
416
    DescriptorTag tag;
417
418
    extent_ad mainVolumeDescriptorSequence;
419
420
    extent_ad reserveVolumeDescriptorSequence;
421
422
    uint8_t reserved[480];
423
424
} AnchorVolumeDescriptorPointer;
425
426
typedef struct __attribute__((packed)) {
427
    DescriptorTag tag;
428
429
    uint32_t volumeDescriptorSequenceNumber;
430
431
    extent_ad nextVolumeDescriptorSequence;
432
433
    uint8_t reserved[484];
434
435
} VolumeDescriptorPointer;
436
437
/*
438
 * charsetType can be
439
 0 The CS0 coded character set (1/7.2.2).
440
 1 The CS1 coded character set (1/7.2.3).
441
 2 The CS2 coded character set (1/7.2.4).
442
 3 The CS3 coded character set (1/7.2.5).
443
 4 The CS4 coded character set (1/7.2.6).
444
 5 The CS5 coded character set (1/7.2.7).
445
 6 The CS6 coded character set (1/7.2.8).
446
 7 The CS7 coded character set (1/7.2.9).
447
 8 The CS8 coded character set (1/7.2.10).
448
 9-255 Reserved for future standardisation.
449
 *
450
 */
451
typedef struct __attribute__((packed)) {
452
    uint8_t charSetType;
453
454
    uint8_t charSetInfo[63];
455
} charspec;
456
457
typedef struct __attribute__((packed)) {
458
459
    DescriptorTag tag;
460
461
    uint32_t volumeDescriptorSequenceNumber;
462
463
    charspec descriptorCharSet;
464
465
    uint8_t logicalVolumeIdentifier[128]; //TODO: handle dstring
466
467
    uint32_t logicalBlockSize;
468
469
    regid domainIdentifier;
470
471
    uint8_t logicalVolumeContentsUse[16];
472
473
    uint32_t mapTableLength;
474
475
    uint32_t numPartitionMaps;
476
477
    regid implementationIdentifier;
478
479
    uint8_t implementationUse[128];
480
481
    ext_ad integritySequenceExtent;
482
483
    uint8_t partitionMaps[1]; //actual length of mapTableLength above;
484
485
} LogicalVolumeDescriptor;
486
487
typedef struct __attribute__((packed)) {
488
    DescriptorTag tag;
489
    timestamp recordingDateTime;
490
491
    uint16_t interchangeLevel;
492
493
    uint16_t maxInterchangeLevel;
494
    uint32_t characterSetList;
495
    uint32_t maxCharacterSetList;
496
497
    uint32_t fileSetNumber;
498
    uint32_t fileSetDescriptorNumber;
499
500
    charspec logicalVolumeIdentifierCharSet;
501
    uint8_t logicalVolumeIdentifier[128];
502
    charspec fileSetCharSet;
503
    uint8_t fileSetIdentifier[32];
504
505
    uint8_t copyrightIdentifier[32];
506
    uint8_t abstractIdentifier[32];
507
    long_ad rootDirectoryICB;
508
509
    regid domainIdentifier;
510
511
    long_ad nextExtent;
512
    long_ad systemStreamDirectoryICB;
513
    uint8_t reserved[32];
514
515
} FileSetDescriptor;
516
517
#ifdef HAVE_PRAGMA_PACK
518
#pragma pack()
519
#endif
520
521
#ifdef HAVE_PRAGMA_PACK_HPPA
522
#pragma pack
523
#endif
524
525
cl_error_t cli_scanudf(cli_ctx* ctx, size_t offset);
526
527
#endif /* _UDF_H_ */