Coverage Report

Created: 2025-07-01 06:59

/src/sleuthkit/tsk/fs/fs_inode.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The Sleuth Kit
3
 *
4
 * Copyright (c) 2006-2011 Brian Carrier, Basis Technology.  All Rights reserved
5
 *
6
 * LICENSE
7
 *  This software is distributed under the IBM Public License.
8
 * AUTHOR(S)
9
 *  Wietse Venema
10
 *  IBM T.J. Watson Research
11
 *  P.O. Box 704
12
 *  Yorktown Heights, NY 10598, USA
13
--*/
14
15
/**
16
 * \file fs_inode.c
17
 * Contains functions to allocate, free, and process the generic inode
18
 * structures
19
 */
20
#include "tsk_fs_i.h"
21
22
/**
23
 * Contains the short (1 character) name of the file type
24
 */
25
char tsk_fs_meta_type_str[TSK_FS_META_TYPE_STR_MAX][2] =
26
    { "-", "r", "d", "p", "c", "b", "l", "s", "h", "w", "v", "V"
27
};
28
29
/**
30
 * \internal
31
 * Allocates a generic inode / metadata structure.
32
 *
33
 * @param a_buf_len Number of bytes needed to store fs-specific data regarding where content is stored.
34
 * @returns NULL on error
35
 */
36
TSK_FS_META *
37
tsk_fs_meta_alloc(size_t a_buf_len)
38
3.77M
{
39
3.77M
    TSK_FS_META *fs_meta;
40
41
3.77M
    if ((fs_meta =
42
3.77M
            (TSK_FS_META *) tsk_malloc(sizeof(TSK_FS_META))) == NULL)
43
0
        return NULL;
44
45
3.77M
    fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY;
46
47
3.77M
    if (a_buf_len > 0) {
48
3.77M
        if ((fs_meta->content_ptr = tsk_malloc(a_buf_len)) == NULL) {
49
0
            free(fs_meta);
50
0
            return NULL;
51
0
        }
52
3.77M
        fs_meta->content_len = a_buf_len;
53
3.77M
        fs_meta->reset_content = NULL;
54
3.77M
    }
55
56
    // assign the id so we know the structure is still alloc
57
3.77M
    fs_meta->tag = TSK_FS_META_TAG;
58
59
3.77M
    return fs_meta;
60
3.77M
}
61
62
63
/**
64
 * \internal
65
 * Resize an existing TSK_FS_META structure -- changes the number of
66
 * block pointers.
67
 *
68
 * @param fs_meta Structure to resize
69
 * @param a_buf_len Size of file system specific data that is used to store references to file content
70
 * @return NULL on error
71
 */
72
TSK_FS_META *
73
tsk_fs_meta_realloc(TSK_FS_META * a_fs_meta, size_t a_buf_len)
74
0
{
75
0
    if (a_fs_meta->reset_content != NULL) {
76
0
        a_fs_meta->reset_content(a_fs_meta->content_ptr);
77
0
    }
78
79
0
    if (a_fs_meta->content_len != a_buf_len) {
80
0
        a_fs_meta->content_len = a_buf_len;
81
0
        a_fs_meta->content_ptr =
82
0
            tsk_realloc((char *) a_fs_meta->content_ptr, a_buf_len);
83
0
        if (a_fs_meta->content_ptr == NULL) {
84
0
            return NULL;
85
0
        }
86
0
    }
87
0
    return a_fs_meta;
88
0
}
89
90
91
/**
92
 * \internal
93
 * Free the memory allocated to the TSK_FS_META structure.
94
 *
95
 * @param fs_meta Structure to free
96
 */
97
void
98
tsk_fs_meta_close(TSK_FS_META * fs_meta)
99
3.77M
{
100
3.77M
    TSK_FS_META_NAME_LIST *fs_name, *fs_name2;
101
102
3.77M
    if ((!fs_meta) || (fs_meta->tag != TSK_FS_META_TAG))
103
0
        return;
104
105
    // clear the tag so we know the structure isn't alloc
106
3.77M
    fs_meta->tag = 0;
107
108
3.77M
    if (fs_meta->content_ptr) {
109
3.77M
        if (fs_meta->reset_content) {
110
1
            fs_meta->reset_content(fs_meta->content_ptr);
111
1
        }
112
113
3.77M
        free((char *) fs_meta->content_ptr);
114
3.77M
    }
115
116
3.77M
    fs_meta->content_ptr = NULL;
117
3.77M
    fs_meta->content_len = 0;
118
119
3.77M
    if (fs_meta->attr)
120
608k
        tsk_fs_attrlist_free(fs_meta->attr);
121
3.77M
    fs_meta->attr = NULL;
122
123
3.77M
    free(fs_meta->link);
124
3.77M
    fs_meta->link = NULL;
125
126
3.77M
    fs_name = fs_meta->name2;
127
3.86M
    while (fs_name) {
128
91.2k
        fs_name2 = fs_name->next;
129
91.2k
        fs_name->next = NULL;
130
91.2k
        free(fs_name);
131
91.2k
        fs_name = fs_name2;
132
91.2k
    }
133
134
3.77M
    free(fs_meta);
135
3.77M
}
136
137
/** \internal
138
 * Reset the contents of a TSK_FS_META structure.
139
 * @param a_fs_meta Structure to reset
140
 */
141
void
142
tsk_fs_meta_reset(TSK_FS_META * a_fs_meta)
143
0
{
144
0
    void *content_ptr_tmp;
145
0
    size_t content_len_tmp;
146
0
    TSK_FS_ATTRLIST *attr_tmp;
147
0
    TSK_FS_META_NAME_LIST *name2_tmp;
148
0
    char *link_tmp;
149
150
    // Clear content
151
0
    if (a_fs_meta->reset_content) {
152
0
        a_fs_meta->reset_content(a_fs_meta->content_ptr);
153
0
    }
154
155
    // backup pointers
156
0
    content_ptr_tmp = a_fs_meta->content_ptr;
157
0
    content_len_tmp = a_fs_meta->content_len;
158
0
    attr_tmp = a_fs_meta->attr;
159
0
    name2_tmp = a_fs_meta->name2;
160
0
    link_tmp = a_fs_meta->link;
161
162
    // clear all data
163
0
    memset(a_fs_meta, 0, sizeof(TSK_FS_META));
164
0
    a_fs_meta->tag = TSK_FS_META_TAG;
165
166
    // restore and clear the pointers
167
0
    a_fs_meta->content_ptr = content_ptr_tmp;
168
0
    a_fs_meta->content_len = content_len_tmp;
169
170
0
    a_fs_meta->attr = attr_tmp;
171
0
    a_fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY;
172
173
0
    a_fs_meta->name2 = name2_tmp;
174
175
0
    a_fs_meta->link = link_tmp;
176
0
    if (a_fs_meta->link)
177
0
        a_fs_meta->link[0] = '\0';
178
179
180
0
    if (a_fs_meta->name2) {
181
0
        name2_tmp = a_fs_meta->name2;
182
0
        while (name2_tmp) {
183
0
            name2_tmp->name[0] = '\0';
184
0
            name2_tmp->par_inode = 0;
185
0
            name2_tmp->par_seq = 0;
186
0
            name2_tmp = name2_tmp->next;
187
0
        }
188
189
0
    }
190
0
}
191
192
/**
193
 * \ingroup fslib
194
 * Walk a range of metadata structures and call a callback for each
195
 * structure that matches the flags supplied.   For example, it can
196
 * call the callback on only allocated or unallocated entries.
197
 *
198
 * @param a_fs File system to process
199
 * @param a_start Metadata address to start walking from
200
 * @param a_end Metadata address to walk to
201
 * @param a_flags Flags that specify the desired metadata features
202
 * @param a_cb Callback function to call
203
 * @param a_ptr Pointer to pass to the callback
204
 * @returns 1 on error and 0 on success
205
 */
206
uint8_t
207
tsk_fs_meta_walk(TSK_FS_INFO * a_fs, TSK_INUM_T a_start,
208
    TSK_INUM_T a_end, TSK_FS_META_FLAG_ENUM a_flags,
209
    TSK_FS_META_WALK_CB a_cb, void *a_ptr)
210
12.4k
{
211
12.4k
    if ((a_fs == NULL) || (a_fs->tag != TSK_FS_INFO_TAG))
212
0
        return 1;
213
214
12.4k
    return a_fs->inode_walk(a_fs, a_start, a_end, a_flags, a_cb, a_ptr);
215
12.4k
}