Bug Summary

File:obj-scan-build/libshouldbeinlibc/../../libshouldbeinlibc/idvec-impgids.c
Location:line 82, column 8
Description:Memory is never released; potential leak of memory pointed to by 'gids'

Annotated Source Code

1/* Add gids implied by a user
2
3 Copyright (C) 1997, 2001, 2014 Free Software Foundation, Inc.
4
5 Written by Miles Bader <miles@gnu.ai.mit.edu>
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include <stdlib.h>
22#include <errno(*__errno_location ()).h>
23#include <idvec.h>
24#include <pwd.h>
25#include <grp.h>
26
27#define NUM_STATIC_GIDS100 100 /* Initial size of static gid array. */
28
29/* The set of gids implied by a uid. */
30struct uid_implies
31{
32 uid_t uid; /* this uid... */
33 struct idvec *implies; /* implies these gids. */
34 struct uid_implies *next;
35};
36
37/* Cache of previously calculated results for add_implied_gids. */
38static struct uid_implies *uid_implies_cache = 0;
39
40/* Add to IMPLIED_GIDS those group ids implied by the user UID. */
41static error_t
42_merge_implied_gids (struct idvec *implied_gids, uid_t uid)
43{
44 struct uid_implies *ui;
45
46 for (ui = uid_implies_cache; ui; ui = ui->next)
3
Loop condition is false. Execution continues on line 51
47 if (ui->uid == uid)
48 return idvec_merge (implied_gids, ui->implies);
49
50 {
51 error_t err = 0;
52 struct passwd *pw = getpwuid (uid);
53
54 if (! pw)
4
Assuming 'pw' is non-null
5
Taking false branch
55 err = EINVAL((0x10 << 26) | ((22) & 0x3fff));
56 else
57 {
58 struct idvec *cache = make_idvec ();
59 gid_t _gids[NUM_STATIC_GIDS100], *gids = _gids;
60 int maxgids = NUM_STATIC_GIDS100;
61 int ngids = getgrouplist (pw->pw_name, pw->pw_gid, gids, &maxgids);
62
63 if (ngids == -1)
6
Taking true branch
64 {
65 gids = malloc (maxgids * sizeof (gid_t));
7
Memory is allocated
66 if (! gids)
8
Assuming 'gids' is non-null
9
Taking false branch
67 err = ENOMEM((0x10 << 26) | ((12) & 0x3fff));
68 else
69 ngids = getgrouplist (pw->pw_name, pw->pw_gid, gids, &maxgids);
70 }
71
72 if (! cache)
10
Assuming 'cache' is null
11
Taking true branch
73 err = ENOMEM((0x10 << 26) | ((12) & 0x3fff));
74
75 if (! err)
12
Taking false branch
76 {
77 err = idvec_merge_ids (cache, gids, ngids);
78 if (gids != _gids)
79 free (gids);
80 }
81
82 if (! err)
13
Memory is never released; potential leak of memory pointed to by 'gids'
83 {
84 idvec_merge (implied_gids, cache);
85 ui = malloc (sizeof (struct uid_implies));
86 if (ui)
87 {
88 ui->uid = uid;
89 ui->implies = cache;
90 ui->next = uid_implies_cache;
91 uid_implies_cache = ui;
92 }
93 else
94 idvec_free (cache);
95 }
96 }
97
98 return err;
99 }
100}
101
102/* Add to GIDS those group ids implied by the users in UIDS. */
103error_t
104idvec_merge_implied_gids (struct idvec *gids, const struct idvec *uids)
105{
106 unsigned int i;
107 error_t err = 0;
108 for (i = 0; i < uids->num; i++)
1
Loop condition is true. Entering loop body
109 {
110 error_t this_err = _merge_implied_gids (gids, uids->ids[i]);
2
Calling '_merge_implied_gids'
111 if (this_err && !err)
112 err = this_err;
113 }
114 return err;
115}