Skip to content

Conversation

mholt
Copy link
Contributor

@mholt mholt commented Jan 14, 2017

I noticed that the response body is not closed in the error case of waiting for a certificate to be issued: https://sourcegraph.com/github.com/xenolf/lego@ce8fb060cb8361a9ff8b5fb7c2347fa907b6fcac/-/blob/acme/client.go#L673-674

AFAIK the response body needs to be closed even if there isn't one or it is not read. We close it above if the response code is 201 or 202, but not 200 or anything else. I think this will fix that problem.

@mholt mholt requested a review from xenolf January 14, 2017 07:34
@mholt
Copy link
Contributor Author

mholt commented Jan 14, 2017

Incidentally, I think there may be one more subtle leak, but I want someone else to verify.

On this line we initially get an *http.Response, which has a body that must be closed. I think the body for that very first response gets closed if and only if it comes back with a 201 or 202 status code. If it doesn't, we replace resp with a new one here but we never closed the body of the first one.

I actually caught this thanks to Sourcegraph's code browser; when I clicked the resp variable, it took me up to that first line where I saw that we were re-using an earlier variable, not creating a new one.

Am I missing something or is that also a bug?

@mholt
Copy link
Contributor Author

mholt commented Jan 14, 2017

Actually, I'm not sure if my initial PR was entirely correct. There are some places where handleHTTPError is called after a defer resp.Body.Close(), meaning in those cases, the body will be closed twice. I just pushed an amendment that should defer the Close() in the right place without duplicating/overlapping Close() calls.

acme/client.go Outdated

break
default:
defer resp.Body.Close()
Copy link

@miekg miekg Jan 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not put this defer directly after the post, i.e. line 612? Then the Close in the other switch can be removed as well.

But yeah, def. a leak here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miekg Because it might be read in line 621. If that's never the case, then sure, but I don't want to break things. I need feedback from @xenolf.

Also make a new const of maxBodySize, and cap the number of polls
to a maximum of 1000.
@mholt
Copy link
Contributor Author

mholt commented Jan 15, 2017

@xenolf @miekg I've pushed a commit that ensures the body for both responses is closed. I had to pull the select out into its own function in order for it to be reasonably readable.

I also took 1024*1024 into a constant, and set a cap for the number of iterations (polling) we're allowed to do in checking for a certificate. There's no reason it should take 1000 polls to get a single cert, and it will be one extra layer of protection against some buggy protocol implementation, perhaps.

Tested and it works :) Please review ASAP. (Will go forward including this in new Caddy releases either way, though.)

Copy link
Member

@xenolf xenolf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mholt thanks for catching that. The latest revision of the changes is looking good.

acme/client.go Outdated
}

// maxBodySize is the maximum size of body that we will read.
const maxBodySize = 1024 * 1024
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we move that up to the top? :)

Copy link
Contributor Author

@mholt mholt Jan 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! Will do in a little bit. (Edit: Done!)

@mholt mholt changed the title Close response body in error case Close response body in error case and close first one Jan 15, 2017
@xenolf xenolf merged commit f5d538c into master Jan 15, 2017
@mholt mholt deleted the fdleak branch January 15, 2017 15:59
@ldez ldez added this to the v0.4 milestone Dec 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants