Bug Summary

File:api/src/glfs-resolve.c
Location:line 179, column 26
Description:Access to field 'table' results in a dereference of a null pointer (loaded from variable 'parent')

Annotated Source Code

1/*
2 Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10
11
12#include <unistd.h>
13#include <string.h>
14#include <stdlib.h>
15#include <stdio.h>
16#include <inttypes.h>
17#include <limits.h>
18
19#ifndef _CONFIG_H
20#define _CONFIG_H
21#include "config.h"
22#endif
23
24#include "glusterfs.h"
25#include "logging.h"
26#include "stack.h"
27#include "event.h"
28#include "glfs-mem-types.h"
29#include "common-utils.h"
30#include "syncop.h"
31#include "call-stub.h"
32
33#include "glfs-internal.h"
34
35
36void
37glfs_first_lookup (xlator_t *subvol)
38{
39 loc_t loc = {0, };
40 int ret = -1;
41
42 loc.inode = subvol->itable->root;
43 memset (loc.gfid, 0, 16);
44 loc.gfid[15] = 1;
45 loc.path = "/";
46 loc.name = "";
47
48 ret = syncop_lookup (subvol, &loc, 0, 0, 0, 0);
49
50 gf_log (subvol->name, GF_LOG_DEBUG, "first lookup complete %d", ret)do { do { if (0) printf ("first lookup complete %d", ret); } while
(0); _gf_log (subvol->name, "glfs-resolve.c", __FUNCTION__
, 50, GF_LOG_DEBUG, "first lookup complete %d", ret); } while
(0)
;
51
52 return;
53}
54
55
56int
57glfs_loc_touchup (loc_t *loc)
58{
59 char *path = NULL((void*)0);
60 int ret = -1;
61 char *bn = NULL((void*)0);
62
63 if (loc->parent)
64 ret = inode_path (loc->parent, loc->name, &path);
65 else
66 ret = inode_path (loc->inode, 0, &path);
67
68 loc->path = path;
69
70 if (ret < 0 || !path) {
71 ret = -1;
72 errno(*__errno_location ()) = ENOMEM12;
73 goto out;
74 }
75
76 bn = strrchr (path, '/');
77 if (bn)
78 bn++;
79 loc->name = bn;
80 ret = 0;
81out:
82 return ret;
83}
84
85
86int
87glfs_resolve_symlink (struct glfs *fs, xlator_t *subvol, inode_t *inode,
88 char **lpath)
89{
90 loc_t loc = {0, };
91 char *path = NULL((void*)0);
92 char *rpath = NULL((void*)0);
93 int ret = -1;
94
95 loc.inode = inode_ref (inode);
96 uuid_copy (loc.gfid, inode->gfid);
97 ret = inode_path (inode, NULL((void*)0), &rpath);
98 if (ret < 0)
99 goto out;
100 loc.path = rpath;
101
102 ret = syncop_readlink (subvol, &loc, &path, 4096);
103
104 if (ret < 0)
105 goto out;
106
107 if (lpath)
108 *lpath = path;
109out:
110 loc_wipe (&loc);
111 return ret;
112}
113
114
115void
116glfs_resolve_base (struct glfs *fs, xlator_t *subvol, inode_t *inode,
117 struct iatt *iatt)
118{
119 loc_t loc = {0, };
120 int ret = -1;
121 char *path = NULL((void*)0);
122
123 loc.inode = inode_ref (inode);
124 uuid_copy (loc.gfid, inode->gfid);
125
126 ret = inode_path (loc.inode, NULL((void*)0), &path);
127 loc.path = path;
128 if (ret < 0)
129 goto out;
130
131 ret = syncop_lookup (subvol, &loc, NULL((void*)0), iatt, NULL((void*)0), NULL((void*)0));
132out:
133 loc_wipe (&loc);
134}
135
136
137inode_t *
138glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
139 const char *component, struct iatt *iatt)
140{
141 loc_t loc = {0, };
142 inode_t *inode = NULL((void*)0);
143 int reval = 0;
144 int ret = -1;
145 int glret = -1;
146 struct iatt ciatt = {0, };
147 uuid_t gfid;
148 dict_t *xattr_req = NULL((void*)0);
149
150 loc.name = component;
151
152 loc.parent = inode_ref (parent);
153 uuid_copy (loc.pargfid, parent->gfid);
154
155 xattr_req = dict_new ();
156 if (!xattr_req) {
31
Assuming 'xattr_req' is non-null
32
Taking false branch
157 errno(*__errno_location ()) = ENOMEM12;
158 goto out;
159 }
160
161 ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
162 if (ret) {
33
Assuming 'ret' is 0
34
Taking false branch
163 errno(*__errno_location ()) = ENOMEM12;
164 goto out;
165 }
166
167 if (strcmp (component, ".") == 0)
35
Taking true branch
168 loc.inode = inode_ref (parent);
169 else if (strcmp (component, "..") == 0)
170 loc.inode = inode_parent (parent, 0, 0);
171 else
172 loc.inode = inode_grep (parent->table, parent, component);
173
174 if (loc.inode) {
36
Taking false branch
175 uuid_copy (loc.gfid, loc.inode->gfid);
176 reval = 1;
177 } else {
178 uuid_generate (gfid);
179 loc.inode = inode_new (parent->table);
37
Access to field 'table' results in a dereference of a null pointer (loaded from variable 'parent')
180 }
181
182 if (!loc.inode)
183 goto out;
184
185
186 glret = glfs_loc_touchup (&loc);
187 if (glret < 0) {
188 ret = -1;
189 goto out;
190 }
191
192 ret = syncop_lookup (subvol, &loc, xattr_req, &ciatt, NULL((void*)0), NULL((void*)0));
193 if (ret && reval) {
194 inode_unref (loc.inode);
195 loc.inode = inode_new (parent->table);
196 if (!loc.inode)
197 goto out;
198 uuid_generate (gfid);
199 ret = syncop_lookup (subvol, &loc, xattr_req, &ciatt,
200 NULL((void*)0), NULL((void*)0));
201 }
202 if (ret)
203 goto out;
204
205 inode = inode_link (loc.inode, loc.parent, component, &ciatt);
206 if (inode)
207 inode_lookup (inode);
208 if (iatt)
209 *iatt = ciatt;
210out:
211 if (xattr_req)
212 dict_unref (xattr_req);
213
214 loc_wipe (&loc);
215
216 return inode;
217}
218
219
220int
221glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
222 const char *origpath, loc_t *loc, struct iatt *iatt,
223 int follow)
224{
225 inode_t *inode = NULL((void*)0);
226 inode_t *parent = NULL((void*)0);
227 char *saveptr = NULL((void*)0);
228 char *path = NULL((void*)0);
229 char *component = NULL((void*)0);
230 char *next_component = NULL((void*)0);
231 int ret = -1;
232 struct iatt ciatt = {0, };
233
234 path = gf_strdup (origpath);
235 if (!path) {
4
Taking false branch
236 errno(*__errno_location ()) = ENOMEM12;
237 return -1;
238 }
239
240 parent = NULL((void*)0);
241 if (at && path[0] != '/') {
242 /* A relative resolution of a path which starts with '/'
243 is equal to an absolute path resolution.
244 */
245 inode = inode_ref (at);
246 } else {
247 inode = inode_ref (subvol->itable->root);
248
249 glfs_resolve_base (fs, subvol, inode, &ciatt);
250 }
251
252 for (component = strtok_r (path, "/", &saveptr);
5
Loop condition is true. Entering loop body
11
Loop condition is true. Entering loop body
17
Loop condition is true. Entering loop body
26
Loop condition is true. Entering loop body
253 component; component = next_component) {
254
255 next_component = strtok_r (NULL((void*)0), "/", &saveptr);
256
257 if (parent)
6
Taking false branch
12
Taking true branch
18
Taking true branch
27
Taking true branch
258 inode_unref (parent);
259
260 parent = inode;
28
Null pointer value stored to 'parent'
261
262 inode = glfs_resolve_component (fs, subvol, parent,
29
Passing null pointer value via 3rd parameter 'parent'
30
Calling 'glfs_resolve_component'
263 component, &ciatt);
264 if (!inode)
7
Taking false branch
13
Taking false branch
19
Taking false branch
265 break;
266
267 if (IA_ISLNK (ciatt.ia_type)(ciatt.ia_type == IA_IFLNK) && (next_component || follow)) {
268 /* If the component is not the last piece,
269 then following it is necessary even if
270 not requested by the caller
271 */
272 char *lpath = NULL((void*)0);
273 loc_t sym_loc = {0,};
274
275 ret = glfs_resolve_symlink (fs, subvol, inode, &lpath);
276 inode_unref (inode);
277 inode = NULL((void*)0);
20
Null pointer value stored to 'inode'
278 if (ret < 0)
21
Taking false branch
279 break;
280
281 ret = glfs_resolve_at (fs, subvol, parent, lpath,
282 &sym_loc,
283 /* followed iatt becomes the
284 component iatt
285 */
286 &ciatt,
287 /* always recurisvely follow while
288 following symlink
289 */
290 1);
291 if (ret == 0)
22
Assuming 'ret' is not equal to 0
23
Taking false branch
292 inode = inode_ref (sym_loc.inode);
293 loc_wipe (&sym_loc);
294 GF_FREE (lpath)__gf_free (lpath);
295 }
296
297 if (!next_component)
8
Assuming 'next_component' is non-null
9
Taking false branch
14
Assuming 'next_component' is non-null
15
Taking false branch
24
Taking false branch
298 break;
299
300 if (!IA_ISDIR (ciatt.ia_type)(ciatt.ia_type == IA_IFDIR)) {
10
Taking false branch
16
Taking false branch
25
Taking false branch
301 /* next_component exists and this component is
302 not a directory
303 */
304 inode_unref (inode);
305 inode = NULL((void*)0);
306 ret = -1;
307 errno(*__errno_location ()) = ENOTDIR20;
308 break;
309 }
310 }
311
312 if (parent && next_component)
313 /* resolution failed mid-way */
314 goto out;
315
316 /* At this point, all components up to the last parent directory
317 have been resolved successfully (@parent). Resolution of basename
318 might have failed (@inode) if at all.
319 */
320
321 loc->parent = parent;
322 if (parent) {
323 uuid_copy (loc->pargfid, parent->gfid);
324 loc->name = component;
325 }
326
327 loc->inode = inode;
328 if (inode) {
329 uuid_copy (loc->gfid, inode->gfid);
330 if (iatt)
331 *iatt = ciatt;
332 ret = 0;
333 }
334
335 glfs_loc_touchup (loc);
336out:
337 GF_FREE (path)__gf_free (path);
338
339 /* do NOT loc_wipe here as only last component might be missing */
340
341 return ret;
342}
343
344
345int
346glfs_resolve_path (struct glfs *fs, xlator_t *subvol, const char *origpath,
347 loc_t *loc, struct iatt *iatt, int follow)
348{
349 int ret = -1;
350
351 if (origpath[0] == '/')
2
Taking false branch
352 ret = glfs_resolve_at (fs, subvol, NULL((void*)0), origpath, loc, iatt,
353 follow);
354 else
355 ret = glfs_resolve_at (fs, subvol, fs->cwd, origpath, loc, iatt,
3
Calling 'glfs_resolve_at'
356 follow);
357
358 return ret;
359}
360
361
362int
363glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
364 loc_t *loc, struct iatt *iatt)
365{
366 int ret = -1;
367
368 ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 1);
369
370 return ret;
371}
372
373
374int
375glfs_lresolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
376 loc_t *loc, struct iatt *iatt)
377{
378 int ret = -1;
379
380 ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 0);
1
Calling 'glfs_resolve_path'
381
382 return ret;
383}
384