On 2022/08/15 08:53:05 +0200, Theo Buehler <[email protected]> wrote:
> On Sun, Aug 14, 2022 at 11:15:16PM +0200, Omar Polo wrote:
> > I was looking for something different when I stumbled upon this.
> >
> > - in server_file_index `escapedpath' is leaked if evbuffer_add_printf
> > fails, similarly the directory entries in the loop. `escapeduri'
> > is also leaked if escape_html fails.
> >
> > - read_errdoc leaks a file descriptor if fstat fails or if the file
> > is empty.
> >
> > both very unlikely but worth fixing IMHO.
> >
> > For server_file_index I decided to just drop the `skip' variable and
> > just goto fail on errors. There shouldn't be any visible change from
> > it, except that we don't try to serve half page if we somehow exhaust
> > memory halfway through.
> >
> > ok?
>
> I have no opinion on whether keeping or dropping skip is better. There
> are a bunch of new problems with your diff, though.
Agree on all the points. I don't know how I haven't spotted them
re-reading the diff before sending it, apologize!
I tried to do too much in a single diff. Instead of a refactoring +
memleak, here's a diff that only covers the leaks. I still don't like
how it still tries to server_response_http when skip = 1, but that can
be address later.
Index: server_http.c
===================================================================
RCS file: /home/cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.150
diff -u -p -u -r1.150 server_http.c
--- server_http.c 2 Mar 2022 11:10:43 -0000 1.150
+++ server_http.c 15 Aug 2022 07:26:56 -0000
@@ -1777,13 +1777,16 @@ read_errdoc(const char *root, const char
free(path);
if (fstat(fd, &sb) < 0) {
log_warn("%s: stat", __func__);
+ close(fd);
return (NULL);
}
if ((ret = calloc(1, sb.st_size + 1)) == NULL)
fatal("calloc");
- if (sb.st_size == 0)
+ if (sb.st_size == 0) {
+ close(fd);
return (ret);
+ }
if (read(fd, ret, sb.st_size) != sb.st_size) {
log_warn("%s: read", __func__);
close(fd);
Index: server_file.c
===================================================================
RCS file: /home/cvs/src/usr.sbin/httpd/server_file.c,v
retrieving revision 1.74
diff -u -p -u -r1.74 server_file.c
--- server_file.c 4 Mar 2022 01:46:07 -0000 1.74
+++ server_file.c 15 Aug 2022 07:24:29 -0000
@@ -535,8 +535,10 @@ server_file_index(struct httpd *env, str
"<body>\n"
"<h1>Index of %s</h1>\n"
"<hr>\n<pre>\n",
- escapedpath, style, escapedpath) == -1)
- skip = 1;
+ escapedpath, style, escapedpath) == -1) {
+ free(escapedpath);
+ goto fail;
+ }
free(escapedpath);
@@ -556,10 +558,17 @@ server_file_index(struct httpd *env, str
strftime(tmstr, sizeof(tmstr), "%d-%h-%Y %R", &tm);
namewidth = 51 - strlen(dp->d_name);
- if ((escapeduri = url_encode(dp->d_name)) == NULL)
- goto fail;
- if ((escapedhtml = escape_html(dp->d_name)) == NULL)
- goto fail;
+ if ((escapeduri = url_encode(dp->d_name)) == NULL) {
+ skip = 1;
+ free(dp);
+ continue;
+ }
+ if ((escapedhtml = escape_html(dp->d_name)) == NULL) {
+ skip = 1;
+ free(escapeduri);
+ free(dp);
+ continue;
+ }
if (dp->d_name[0] == '.' &&
!(dp->d_name[1] == '.' && dp->d_name[2] == '\0')) {