daemon: detect and reject too-long paths
When we are checking the path via path_ok(), we use some fixed PATH_MAX buffers. We write into them via snprintf(), so there's no possibility of overflow, but it does mean we may silently truncate the path, leading to potentially confusing errors when the partial path does not exist. We're better off to reject the path explicitly. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Oct 22, 2016 at 00:59 UTC
6bdb0083be3b42aab5dfa6bf18b447623704f7f5
1 file changed
+21
-4
daemon.c
+21
-4
@@ -161,6 +161,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
161
{
162
static char rpath[PATH_MAX];
163
static char interp_path[PATH_MAX];
164
+ size_t rlen;
165
const char *path;
166
const char *dir;
167
@@ -188,8 +189,12 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
189
namlen = slash - dir;
190
restlen -= namlen;
191
loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash);
191
- snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
192
- namlen, dir, user_path, restlen, slash);
192
+ rlen = snprintf(rpath, sizeof(rpath), "%.*s/%s%.*s",
193
+ namlen, dir, user_path, restlen, slash);
194
+ if (rlen >= sizeof(rpath)) {
195
+ logerror("user-path too large: %s", rpath);
196
+ return NULL;
197
+ }
198
dir = rpath;
199
}
200
}
@@ -208,7 +213,15 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
213
214
strbuf_expand(&expanded_path, interpolated_path,
215
expand_path, &context);
211
- strlcpy(interp_path, expanded_path.buf, PATH_MAX);
216
+
217
+ rlen = strlcpy(interp_path, expanded_path.buf,
218
+ sizeof(interp_path));
219
+ if (rlen >= sizeof(interp_path)) {
220
+ logerror("interpolated path too large: %s",
221
+ interp_path);
222
+ return NULL;
223
+ }
224
+
225
strbuf_release(&expanded_path);
226
loginfo("Interpolated dir '%s'", interp_path);
227
@@ -220,7 +233,11 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
233
logerror("'%s': Non-absolute path denied (base-path active)", dir);
234
return NULL;
235
}
223
- snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
236
+ rlen = snprintf(rpath, sizeof(rpath), "%s%s", base_path, dir);
237
+ if (rlen >= sizeof(rpath)) {
238
+ logerror("base-path too large: %s", rpath);
239
+ return NULL;
240
+ }
241
dir = rpath;
242
}
243