Bug Summary

File:obj-scan-build/libdiskfs/../../libdiskfs/fsys-getroot.c
Location:line 113, column 7
Description:Array subscript is undefined

Annotated Source Code

1/*
2 Copyright (C) 1993,94,95,96,97,98,2002 Free Software Foundation
3
4This file is part of the GNU Hurd.
5
6The GNU Hurd is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11The GNU Hurd is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with the GNU Hurd; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/* Written by Michael I. Bushnell. */
21
22#include "priv.h"
23#include "fsys_S.h"
24#include <hurd/fsys.h>
25#include <fcntl.h>
26
27/* Implement fsys_getroot as described in <hurd/fsys.defs>. */
28kern_return_t
29diskfs_S_fsys_getroot (fsys_t controlport,
30 mach_port_t reply,
31 mach_msg_type_name_t replytype,
32 mach_port_t dotdot,
33 uid_t *uids,
34 size_t nuids,
35 uid_t *gids,
36 size_t ngids,
37 int flags,
38 retry_type *retry,
39 char *retryname,
40 file_t *returned_port,
41 mach_msg_type_name_t *returned_port_poly)
42{
43 struct port_info *pt = ports_lookup_port (diskfs_port_bucket, controlport,
44 diskfs_control_class);
45 error_t err = 0;
46 mode_t type;
47 struct protid *newpi;
48 struct peropen *newpo;
49 struct iouser user;
50 struct peropen peropen_context =
51 {
52 root_parent: dotdot,
53 shadow_root_parent: MACH_PORT_NULL((mach_port_t) 0),
54 shadow_root: _diskfs_chroot_directory ? diskfs_root_node : NULL((void*)0), /* XXX */
1
Assuming '_diskfs_chroot_directory' is null
2
'?' condition is false
55 path: NULL((void*)0),
56 };
57
58 if (!pt)
3
Assuming 'pt' is non-null
4
Taking false branch
59 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
60
61 flags &= O_HURD(0xffff | 0x00040000 | 0x00020000);
62
63 user.uids = make_idvec ();
64 user.gids = make_idvec ();
65 idvec_set_ids (user.uids, uids, nuids);
66 idvec_set_ids (user.gids, gids, ngids);
67#define drop_idvec()idvec_free (user.gids); idvec_free (user.uids) idvec_free (user.gids); idvec_free (user.uids)
68
69 pthread_rwlock_rdlock (&diskfs_fsys_lock);
70 pthread_mutex_lock (&diskfs_root_node->lock);
71
72 /* This code is similar (but not the same as) the code in
73 dir-lookup.c that does the same thing. Perhaps a way should
74 be found to share the logic. */
75
76 type = diskfs_root_node->dn_stat.st_mode & S_IFMT0170000;
77
78 if (((diskfs_root_node->dn_stat.st_mode & S_IPTRANS000010000000)
6
Taking false branch
79 || fshelp_translated (&diskfs_root_node->transbox))
80 && !(flags & O_NOTRANS0x0080))
5
Assuming 'flags' is & 128
81 {
82 err = fshelp_fetch_root (&diskfs_root_node->transbox,
83 &peropen_context, dotdot, &user, flags,
84 _diskfs_translator_callback1,
85 _diskfs_translator_callback2,
86 retry, retryname, returned_port);
87 if (err != ENOENT((0x10 << 26) | ((2) & 0x3fff)))
88 {
89 pthread_mutex_unlock (&diskfs_root_node->lock);
90 pthread_rwlock_unlock (&diskfs_fsys_lock);
91 drop_idvec ()idvec_free (user.gids); idvec_free (user.uids);
92 if (!err)
93 *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND17;
94 return err;
95 }
96
97 /* ENOENT means the translator was removed in the interim. */
98 err = 0;
99 }
100
101 if (type == S_IFLNK0120000 && !(flags & (O_NOLINK0x0040 | O_NOTRANS0x0080)))
7
Assuming 'type' is equal to 40960
8
Taking true branch
102 {
103 /* Handle symlink interpretation */
104 char pathbuf[diskfs_root_node->dn_stat.st_size + 1];
105 size_t amt;
9
Variable 'amt' declared without an initial value
106
107 if (diskfs_read_symlink_hook)
10
Assuming 'diskfs_read_symlink_hook' is non-null
11
Taking true branch
108 err = (*diskfs_read_symlink_hook) (diskfs_root_node, pathbuf);
109 if (!diskfs_read_symlink_hook || err == EINVAL((0x10 << 26) | ((22) & 0x3fff)))
12
Assuming 'diskfs_read_symlink_hook' is non-null
13
Taking false branch
110 err = diskfs_node_rdwr (diskfs_root_node, pathbuf, 0,
111 diskfs_root_node->dn_stat.st_size, 0,
112 0, &amt);
113 pathbuf[amt] = '\0';
14
Array subscript is undefined
114
115 pthread_mutex_unlock (&diskfs_root_node->lock);
116 pthread_rwlock_unlock (&diskfs_fsys_lock);
117 if (err)
118 {
119 drop_idvec ()idvec_free (user.gids); idvec_free (user.uids);
120 return err;
121 }
122
123 if (pathbuf[0] == '/')
124 {
125 *retry = FS_RETRY_MAGICAL;
126 *returned_port = MACH_PORT_NULL((mach_port_t) 0);
127 *returned_port_poly = MACH_MSG_TYPE_COPY_SEND19;
128 strcpy (retryname, pathbuf);
129 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), dotdot);
130 drop_idvec ()idvec_free (user.gids); idvec_free (user.uids);
131 return 0;
132 }
133 else
134 {
135 *retry = FS_RETRY_REAUTH;
136 *returned_port = dotdot;
137 *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND17;
138 strcpy (retryname, pathbuf);
139 drop_idvec ()idvec_free (user.gids); idvec_free (user.uids);
140 return 0;
141 }
142 }
143
144 if ((type == S_IFSOCK0140000 || type == S_IFBLK0060000
145 || type == S_IFCHR0020000 || type == S_IFIFO0010000)
146 && (flags & (O_READ0x0001|O_WRITE0x0002|O_EXEC0x0004)))
147 err = EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
148
149 if (!err && (flags & O_READ0x0001))
150 err = fshelp_access (&diskfs_root_node->dn_stat, S_IREAD00400, &user);
151
152 if (!err && (flags & O_EXEC0x0004))
153 err = fshelp_access (&diskfs_root_node->dn_stat, S_IEXEC00100, &user);
154
155 if (!err && (flags & (O_WRITE0x0002)))
156 {
157 if (type == S_IFDIR0040000)
158 err = EISDIR((0x10 << 26) | ((21) & 0x3fff));
159 else if (diskfs_check_readonly ())
160 err = EROFS((0x10 << 26) | ((30) & 0x3fff));
161 else
162 err = fshelp_access (&diskfs_root_node->dn_stat,
163 S_IWRITE00200, &user);
164 }
165
166 if (err)
167 {
168 pthread_mutex_unlock (&diskfs_root_node->lock);
169 pthread_rwlock_unlock (&diskfs_fsys_lock);
170 drop_idvec ()idvec_free (user.gids); idvec_free (user.uids);
171 return err;
172 }
173
174 if ((flags & O_NOATIME0x0800)
175 && (fshelp_isowner (&diskfs_root_node->dn_stat, &user)
176 == EPERM((0x10 << 26) | ((1) & 0x3fff))))
177 flags &= ~O_NOATIME0x0800;
178
179 flags &= ~OPENONLY_STATE_MODES(0x0010|0x0020|0x0040|0x0080|0x0008|0x00040000|0x00020000);
180
181 err = diskfs_make_peropen (diskfs_root_node, flags,
182 &peropen_context, &newpo);
183 if (! err)
184 {
185 err = diskfs_create_protid (newpo, &user, &newpi);
186 if (err)
187 diskfs_release_peropen (newpo);
188 }
189
190 if (! err)
191 {
192 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), dotdot);
193 *retry = FS_RETRY_NORMAL;
194 *retryname = '\0';
195 *returned_port = ports_get_right (newpi);
196 *returned_port_poly = MACH_MSG_TYPE_MAKE_SEND20;
197 ports_port_deref (newpi);
198 }
199
200 pthread_mutex_unlock (&diskfs_root_node->lock);
201 pthread_rwlock_unlock (&diskfs_fsys_lock);
202
203 ports_port_deref (pt);
204
205 drop_idvec ()idvec_free (user.gids); idvec_free (user.uids);
206
207 return err;
208}