Bug Summary

File:obj-scan-build/libshouldbeinlibc/../../libshouldbeinlibc/idvec-impgids.c
Location:line 94, 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 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#ifdef HAVE_GETGROUPLIST1
60 gid_t _gids[NUM_STATIC_GIDS100], *gids = _gids;
61 int maxgids = NUM_STATIC_GIDS100;
62 int ngids = getgrouplist (pw->pw_name, pw->pw_gid, gids, &maxgids);
63
64 if (ngids == -1)
6
Taking true branch
65 {
66 gids = malloc (maxgids * sizeof (gid_t));
7
Memory is allocated
67 if (! gids)
8
Assuming 'gids' is non-null
9
Taking false branch
68 err = ENOMEM((0x10 << 26) | ((12) & 0x3fff));
69 else
70 ngids = getgrouplist (pw->pw_name, pw->pw_gid, gids, &maxgids);
71 }
72
73 if (! cache)
10
Assuming 'cache' is null
11
Taking true branch
74 err = ENOMEM((0x10 << 26) | ((12) & 0x3fff));
75
76 if (! err)
12
Taking false branch
77 {
78 err = idvec_merge_ids (cache, gids, ngids);
79 if (gids != _gids)
80 free (gids);
81 }
82#else
83#warning "getgrouplist() not available; supplementary group IDs unsupported."
84 if (! cache)
85 err = ENOMEM((0x10 << 26) | ((12) & 0x3fff));
86 else
87 {
88 err = idvec_add_new (cache, pw->pw_gid);
89 if (err)
90 idvec_free (cache);
91 }
92#endif
93
94 if (! err)
13
Memory is never released; potential leak of memory pointed to by 'gids'
95 {
96 idvec_merge (implied_gids, cache);
97 ui = malloc (sizeof (struct uid_implies));
98 if (ui)
99 {
100 ui->uid = uid;
101 ui->implies = cache;
102 ui->next = uid_implies_cache;
103 uid_implies_cache = ui;
104 }
105 else
106 idvec_free (cache);
107 }
108 }
109
110 return err;
111 }
112}
113
114/* Add to GIDS those group ids implied by the users in UIDS. */
115error_t
116idvec_merge_implied_gids (struct idvec *gids, const struct idvec *uids)
117{
118 unsigned int i;
119 error_t err = 0;
120 for (i = 0; i < uids->num; i++)
1
Loop condition is true. Entering loop body
121 {
122 error_t this_err = _merge_implied_gids (gids, uids->ids[i]);
2
Calling '_merge_implied_gids'
123 if (this_err && !err)
124 err = this_err;
125 }
126 return err;
127}