/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_ */ |