[PATCH] SSL: improved validation of ssl_session_cache and ssl_ocsp_cache
Maxim Dounin
mdounin at mdounin.ru
Fri Oct 14 16:30:43 UTC 2022
Hello!
On Fri, Oct 14, 2022 at 04:33:00PM +0400, Sergey Kandaurov wrote:
> > On 14 Oct 2022, at 00:30, Maxim Dounin <mdounin at mdounin.ru> wrote:
> >
> > Hello!
> >
> > On Thu, Oct 13, 2022 at 05:02:42PM +0400, Sergey Kandaurov wrote:
> >
> >> # HG changeset patch
> >> # User Sergey Kandaurov <pluknet at nginx.com>
> >> # Date 1665665717 -14400
> >> # Thu Oct 13 16:55:17 2022 +0400
> >> # Node ID b2eba2994ddcbf9084075f9ae32c3332a628ca7a
> >> # Parent 81b4326daac70d6de70abbc3fe36d4f6e3da54a2
> >> SSL: improved validation of ssl_session_cache and ssl_ocsp_cache.
> >>
> >> Now it properly detects invalid shared zone configuration with omitted size.
> >> Previously it used to read outside of the buffer boundary.
> >>
> >> Found with AddressSanitizer.
> >>
> >> diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
> >> --- a/src/http/modules/ngx_http_ssl_module.c
> >> +++ b/src/http/modules/ngx_http_ssl_module.c
> >> @@ -1039,10 +1039,10 @@ ngx_http_ssl_session_cache(ngx_conf_t *c
> >> {
> >> ngx_http_ssl_srv_conf_t *sscf = conf;
> >>
> >> - size_t len;
> >> + u_char *p;
> >> ngx_str_t *value, name, size;
> >> ngx_int_t n;
> >> - ngx_uint_t i, j;
> >> + ngx_uint_t i;
> >>
> >> value = cf->args->elts;
> >>
> >> @@ -1083,25 +1083,20 @@ ngx_http_ssl_session_cache(ngx_conf_t *c
> >> && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
> >> == 0)
> >> {
> >> - len = 0;
> >> + name.data = value[i].data + sizeof("shared:") - 1;
> >> +
> >> + p = (u_char *) ngx_strchr(name.data, ':');
> >>
> >> - for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
> >> - if (value[i].data[j] == ':') {
> >> - break;
> >> - }
> >> -
> >> - len++;
> >> + if (p == NULL) {
> >> + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
> >> + "invalid zone size \"%V\"", &value[i]);
> >> + return NGX_CONF_ERROR;
> >
> > goto invalid?
> >
> > This seems to be more in line with both previous handling of the
> > "len == 0" case, and the remaining handling of the "n ==
> > NGX_ERROR" case.
>
> Agree.
>
> >
> >> }
> >>
> >> - if (len == 0) {
> >> - goto invalid;
> >> - }
> >> + name.len = p - name.data;
> >
> > This makes it possible to create a shared memory zone with an
> > empty name, which was previously forbidden.
> >
>
> Thanks, that's certainly an omission.
>
> diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
> --- a/src/http/modules/ngx_http_ssl_module.c
> +++ b/src/http/modules/ngx_http_ssl_module.c
> @@ -1088,13 +1088,15 @@ ngx_http_ssl_session_cache(ngx_conf_t *c
> p = (u_char *) ngx_strchr(name.data, ':');
>
> if (p == NULL) {
> - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
> - "invalid zone size \"%V\"", &value[i]);
> - return NGX_CONF_ERROR;
> + goto invalid;
> }
>
> name.len = p - name.data;
>
> + if (name.len == 0) {
> + goto invalid;
> + }
> +
> size.data = p + 1;
> size.len = value[i].data + value[i].len - size.data;
>
>
> (with intention to update other places.)
Looks good.
> > Note that limit_req_zone / limit_conn_zone parsing you've copied
> > does not allow shared memory zones with empty names due to the
> > additional name.len check after parsing of all arguments.
>
> Indeed, this is to bring similarity in parsing,
> that's why it comes with such a huge diff.
>
> Alternatively (my initial version), is to add a simple check.
> Given that the resulting code has subtle differences comparing to
> limit_req/limit_conn, I tend to think it has little sense to unify.
> That said, below is a different approach:
I generally tend to think that ngx_strchr() approach as used in
limit_req_zone / limit_conn_zone is more readable compared to the
explicit for loop in ssl_session_cache. But the idea of changing
the existing code is indeed questionable.
>
> # HG changeset patch
> # User Sergey Kandaurov <pluknet at nginx.com>
> # Date 1665749669 -14400
> # Fri Oct 14 16:14:29 2022 +0400
> # Node ID 68bc1f8b35a9709a2b8bef6c2d60b33ac7c2712b
> # Parent 81b4326daac70d6de70abbc3fe36d4f6e3da54a2
> SSL: improved validation of ssl_session_cache and ssl_ocsp_cache.
>
> Now it properly detects invalid shared zone configuration with omitted size.
> Previously it used to read outside of the buffer boundary.
>
> Found with AddressSanitizer.
>
> diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
> --- a/src/http/modules/ngx_http_ssl_module.c
> +++ b/src/http/modules/ngx_http_ssl_module.c
> @@ -1097,6 +1097,10 @@ ngx_http_ssl_session_cache(ngx_conf_t *c
> goto invalid;
> }
>
> + if (j == value[i].len) {
> + goto invalid;
> + }
> +
> name.len = len;
> name.data = value[i].data + sizeof("shared:") - 1;
>
May be just
@@ -1093,7 +1093,7 @@ ngx_http_ssl_session_cache(ngx_conf_t *c
len++;
}
- if (len == 0) {
+ if (len == 0 || j == value[i].len) {
goto invalid;
}
?
Either way, looks good.
Feel free to commit the variant you prefer.
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx-devel
mailing list