Coverage Report

Created: 2023-06-07 06:53

/src/libvshadow/libvshadow/libvshadow_block_descriptor.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Block descriptor functions
3
 *
4
 * Copyright (C) 2011-2023, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libvshadow_block_descriptor.h"
27
#include "libvshadow_debug.h"
28
#include "libvshadow_definitions.h"
29
#include "libvshadow_libcerror.h"
30
#include "libvshadow_libcnotify.h"
31
#include "libvshadow_unused.h"
32
33
#include "vshadow_store.h"
34
35
const uint8_t vshadow_empty_store_block_list_entry[ 32 ] = {
36
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
38
39
/* Creates a block descriptor
40
 * Make sure the value block_descriptor is referencing, is set to NULL
41
 * Returns 1 if successful or -1 on error
42
 */
43
int libvshadow_block_descriptor_initialize(
44
     libvshadow_block_descriptor_t **block_descriptor,
45
     libcerror_error_t **error )
46
859
{
47
859
  static char *function = "libvshadow_block_descriptor_initialize";
48
49
859
  if( block_descriptor == NULL )
50
0
  {
51
0
    libcerror_error_set(
52
0
     error,
53
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
54
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
55
0
     "%s: invalid block descriptor.",
56
0
     function );
57
58
0
    return( -1 );
59
0
  }
60
859
  if( *block_descriptor != NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
65
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
66
0
     "%s: invalid block descriptor value already set.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
859
  *block_descriptor = memory_allocate_structure(
72
859
                       libvshadow_block_descriptor_t );
73
74
859
  if( *block_descriptor == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
79
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
80
0
     "%s: unable to create block descriptor.",
81
0
     function );
82
83
0
    goto on_error;
84
0
  }
85
859
  if( memory_set(
86
859
       *block_descriptor,
87
859
       0,
88
859
       sizeof( libvshadow_block_descriptor_t ) ) == NULL )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
93
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
94
0
     "%s: unable to clear block descriptor.",
95
0
     function );
96
97
0
    goto on_error;
98
0
  }
99
859
  ( *block_descriptor )->index         = -1;
100
859
  ( *block_descriptor )->reverse_index = -1;
101
102
859
  return( 1 );
103
104
0
on_error:
105
0
  if( *block_descriptor != NULL )
106
0
  {
107
0
    memory_free(
108
0
     *block_descriptor );
109
110
0
    *block_descriptor = NULL;
111
0
  }
112
0
  return( -1 );
113
859
}
114
115
/* Frees a block descriptor
116
 * Returns 1 if successful or -1 on error
117
 */
118
int libvshadow_block_descriptor_free(
119
     libvshadow_block_descriptor_t **block_descriptor,
120
     libcerror_error_t **error )
121
859
{
122
859
  static char *function = "libvshadow_block_descriptor_free";
123
859
  int result            = 1;
124
125
859
  if( block_descriptor == NULL )
126
0
  {
127
0
    libcerror_error_set(
128
0
     error,
129
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
130
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
131
0
     "%s: invalid block descriptor.",
132
0
     function );
133
134
0
    return( -1 );
135
0
  }
136
859
  if( *block_descriptor != NULL )
137
859
  {
138
859
    if( ( *block_descriptor )->overlay != NULL )
139
0
    {
140
0
      if( libvshadow_block_descriptor_free(
141
0
           &( ( *block_descriptor )->overlay ),
142
0
           error ) != 1 )
143
0
      {
144
0
        libcerror_error_set(
145
0
         error,
146
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
147
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
148
0
         "%s: unable to free overlay block descriptor.",
149
0
         function );
150
151
0
        result = -1;
152
0
      }
153
0
    }
154
859
    memory_free(
155
859
     *block_descriptor );
156
157
859
    *block_descriptor = NULL;
158
859
  }
159
859
  return( result );
160
859
}
161
162
/* Frees a block descriptor if stored in the reverse block tree only
163
 * Returns 1 if successful or -1 on error
164
 */
165
int libvshadow_block_descriptor_free_reverse(
166
     libvshadow_block_descriptor_t **block_descriptor,
167
     libcerror_error_t **error )
168
0
{
169
0
  static char *function = "libvshadow_block_descriptor_free_reverse";
170
0
  int result            = 1;
171
172
0
  if( block_descriptor == NULL )
173
0
  {
174
0
    libcerror_error_set(
175
0
     error,
176
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
177
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
178
0
     "%s: invalid block descriptor.",
179
0
     function );
180
181
0
    return( -1 );
182
0
  }
183
0
  if( ( *block_descriptor != NULL )
184
0
   && ( ( *block_descriptor )->index == -1 ) )
185
0
  {
186
0
    if( ( *block_descriptor )->overlay != NULL )
187
0
    {
188
0
      if( libvshadow_block_descriptor_free(
189
0
           &( ( *block_descriptor )->overlay ),
190
0
           error ) != 1 )
191
0
      {
192
0
        libcerror_error_set(
193
0
         error,
194
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
195
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
196
0
         "%s: unable to free overlay block descriptor.",
197
0
         function );
198
199
0
        result = -1;
200
0
      }
201
0
    }
202
0
    memory_free(
203
0
     *block_descriptor );
204
205
0
    *block_descriptor = NULL;
206
0
  }
207
0
  return( result );
208
0
}
209
210
/* Clones a block descriptor
211
 * Make sure the value destination_block_descriptor is pointing to is set to NULL
212
 * Returns 1 if successful or -1 on error
213
 */
214
int libvshadow_block_descriptor_clone(
215
     libvshadow_block_descriptor_t **destination_block_descriptor,
216
     libvshadow_block_descriptor_t *source_block_descriptor,
217
     libcerror_error_t **error )
218
0
{
219
0
  static char *function = "libvshadow_block_descriptor_clone";
220
221
0
  if( destination_block_descriptor == NULL )
222
0
  {
223
0
    libcerror_error_set(
224
0
     error,
225
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
226
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
227
0
     "%s: invalid destination block descriptor.",
228
0
     function );
229
230
0
    return( -1 );
231
0
  }
232
0
  if( *destination_block_descriptor != NULL )
233
0
  {
234
0
    libcerror_error_set(
235
0
     error,
236
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
237
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
238
0
     "%s: invalid destination block descriptor value already set.",
239
0
     function );
240
241
0
    return( -1 );
242
0
  }
243
0
  if( source_block_descriptor == NULL )
244
0
  {
245
0
    *destination_block_descriptor = NULL;
246
247
0
    return( 1 );
248
0
  }
249
0
  *destination_block_descriptor = memory_allocate_structure(
250
0
                                   libvshadow_block_descriptor_t );
251
252
0
  if( *destination_block_descriptor == NULL )
253
0
  {
254
0
    libcerror_error_set(
255
0
     error,
256
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
257
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
258
0
     "%s: unable to create destination block descriptor.",
259
0
     function );
260
261
0
    goto on_error;
262
0
  }
263
0
  if( memory_copy(
264
0
       *destination_block_descriptor,
265
0
       source_block_descriptor,
266
0
       sizeof( libvshadow_block_descriptor_t ) ) == NULL )
267
0
  {
268
0
    libcerror_error_set(
269
0
     error,
270
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
271
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
272
0
     "%s: unable to copy block descriptor.",
273
0
     function );
274
275
0
    goto on_error;
276
0
  }
277
0
  if( source_block_descriptor->overlay != NULL )
278
0
  {
279
0
    if( libvshadow_block_descriptor_clone(
280
0
         &( ( *destination_block_descriptor )->overlay ),
281
0
         source_block_descriptor->overlay,
282
0
         error ) != 1 )
283
0
    {
284
0
      libcerror_error_set(
285
0
       error,
286
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
287
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
288
0
       "%s: unable to create destination overlay block descriptor.",
289
0
       function );
290
291
0
      goto on_error;
292
0
    }
293
0
  }
294
0
  ( *destination_block_descriptor )->index         = -1;
295
0
  ( *destination_block_descriptor )->reverse_index = -1;
296
297
0
  return( 1 );
298
299
0
on_error:
300
0
  if( *destination_block_descriptor != NULL )
301
0
  {
302
0
    memory_free(
303
0
     *destination_block_descriptor );
304
305
0
    *destination_block_descriptor = NULL;
306
0
  }
307
0
  return( -1 );
308
0
}
309
310
/* Reads the block descriptor
311
 * Returns 1 if successful, 0 if block list entry is empty or -1 on error
312
 */
313
int libvshadow_block_descriptor_read_data(
314
     libvshadow_block_descriptor_t *block_descriptor,
315
     const uint8_t *data,
316
     size_t data_size,
317
     int store_index LIBVSHADOW_ATTRIBUTE_UNUSED,
318
     libcerror_error_t **error )
319
0
{
320
0
  static char *function = "libvshadow_block_descriptor_read_data";
321
322
0
  LIBVSHADOW_UNREFERENCED_PARAMETER( store_index )
323
324
0
  if( block_descriptor == NULL )
325
0
  {
326
0
    libcerror_error_set(
327
0
     error,
328
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
329
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
330
0
     "%s: invalid block descriptor.",
331
0
     function );
332
333
0
    return( -1 );
334
0
  }
335
0
  if( data == NULL )
336
0
  {
337
0
    libcerror_error_set(
338
0
     error,
339
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
340
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
341
0
     "%s: invalid data.",
342
0
     function );
343
344
0
    return( -1 );
345
0
  }
346
0
  if( ( data_size < sizeof( vshadow_store_block_list_entry_t ) )
347
0
   || ( data_size > (size_t) SSIZE_MAX ) )
348
0
  {
349
0
    libcerror_error_set(
350
0
     error,
351
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
352
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
353
0
     "%s: invalid data size value out of bounds.",
354
0
     function );
355
356
0
    return( -1 );
357
0
  }
358
0
  if( memory_compare(
359
0
       data,
360
0
             vshadow_empty_store_block_list_entry,
361
0
             sizeof( vshadow_store_block_list_entry_t ) ) == 0 )
362
0
  {
363
0
    return( 0 );
364
0
  }
365
#if defined( HAVE_DEBUG_OUTPUT )
366
  if( libcnotify_verbose != 0 )
367
  {
368
    libcnotify_printf(
369
     "%s: store: %02d data:\n",
370
     function,
371
     store_index );
372
    libcnotify_print_data(
373
     data,
374
     sizeof( vshadow_store_block_list_entry_t ),
375
     0 );
376
  }
377
#endif
378
0
  byte_stream_copy_to_uint64_little_endian(
379
0
   ( (vshadow_store_block_list_entry_t *) data )->original_offset,
380
0
   block_descriptor->original_offset );
381
382
0
  byte_stream_copy_to_uint64_little_endian(
383
0
   ( (vshadow_store_block_list_entry_t *) data )->relative_offset,
384
0
   block_descriptor->relative_offset );
385
386
0
  byte_stream_copy_to_uint64_little_endian(
387
0
   ( (vshadow_store_block_list_entry_t *) data )->offset,
388
0
   block_descriptor->offset );
389
390
0
  byte_stream_copy_to_uint32_little_endian(
391
0
   ( (vshadow_store_block_list_entry_t *) data )->flags,
392
0
   block_descriptor->flags );
393
394
0
  byte_stream_copy_to_uint32_little_endian(
395
0
   ( (vshadow_store_block_list_entry_t *) data )->allocation_bitmap,
396
0
   block_descriptor->bitmap );
397
398
#if defined( HAVE_DEBUG_OUTPUT )
399
  if( libcnotify_verbose != 0 )
400
  {
401
    libcnotify_printf(
402
     "%s: store: %02d original offset\t: 0x%08" PRIx64 "\n",
403
     function,
404
     store_index,
405
     block_descriptor->original_offset );
406
407
    libcnotify_printf(
408
     "%s: store: %02d relative offset\t: 0x%08" PRIx64 "\n",
409
     function,
410
     store_index,
411
     block_descriptor->relative_offset );
412
413
    libcnotify_printf(
414
     "%s: store: %02d offset\t\t\t: 0x%08" PRIx64 "\n",
415
     function,
416
     store_index,
417
     block_descriptor->offset );
418
419
    libcnotify_printf(
420
     "%s: store: %02d flags\t\t\t: 0x%08" PRIx32 "\n",
421
     function,
422
     store_index,
423
     block_descriptor->flags );
424
425
    libcnotify_printf(
426
     "%s: store: %02d allocation bitmap\t: 0x%08" PRIx32 "\n",
427
     function,
428
     store_index,
429
     block_descriptor->bitmap );
430
431
    libcnotify_printf(
432
     "\n" );
433
  }
434
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
435
436
0
  if( ( block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_FORWARDER ) != 0 )
437
0
  {
438
0
    if( block_descriptor->offset != 0 )
439
0
    {
440
0
      libcerror_error_set(
441
0
       error,
442
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
443
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
444
0
       "%s: unsupported offset - value not zero.",
445
0
       function );
446
447
0
      return( -1 );
448
0
    }
449
0
  }
450
0
  return( 1 );
451
0
}
452