Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

apache 2.4 modules: writing new cookie on the response cause seg fault

Tags:

c

apache

I'm writing apache module and I'm having difficulties writing a new cookie to be sent to the browser with the response.

I'm trying to use ap_cookie_write as stated in the documentation.

First question - I don't think setting cookie on the request_rec will result with sending the cookie back to the client, so how can I really add cookies?

Second question - This code:

if (ap_cookie_write(ctx->r, "_mycookie", "", NULL,  0L) != APR_SUCCESS) {
     ERROR(ctx->r->server, "Could not write _mycookie empty value");
}

causes this crash:

[Wed Aug 03 10:09:51.712610 2016] [core:debug] [pid 17272:tid 140219016423168] util_cookies.c(59): [client 10.20.1.35:52967] AH00007: ap_cookie: user '(null)' set cookie: '_mycookie=;HttpOnly;Secure;Version=1', referer: http://10.20.1.203/
[Wed Aug 03 10:09:52.389575 2016] [core:notice] [pid 32421:tid 140219219822464] AH00051: child pid 17272 exit signal Segmentation fault (11), possible coredump in /etc/apache2

What am I doing wrong? by looking at the source code I see that there it no need to allocate the strings I'm sending there.

Update

As for the second question - I figured out that the varargs list must end with NULL so that fixed the seg fault:

if (ap_cookie_write(ctx->r, "_mycookie", "", NULL,  0L, NULL) != APR_SUCCESS) {
     ERROR(ctx->r->server, "Could not write _mycookie empty value");
}

But now the cookie does not return on the response.

like image 203
Shikloshi Avatar asked Aug 03 '16 07:08

Shikloshi


1 Answers

You need to provide ap_cookie_write the header table(s) to add the cookie to. As the documentation says:

A varargs array of zero or more (apr_table_t *) tables followed by NULL to which the cookies should be added.

What do cookies have to do with headers?

Cookies are added/removed via the Set-Cookie (or Set-Cookie2) header.

Why does the header table need to be provided?

request_rec instances have two header tables, headers_out and err_headers_out.

The difference between headers_out and err_headers_out, is that the latter are printed even on error, and persist across internal redirects (so the headers printed for ErrorDocument handlers will have them).

For example, if a handler wants to return a 404 response, but nevertheless to set a cookie, it has to be:

$r->err_headers_out->add('Set-Cookie' => $cookie); return Apache2::Const::NOT_FOUND; If the handler does:

$r->headers_out->add('Set-Cookie' => $cookie); return Apache2::Const::NOT_FOUND; the Set-Cookie header won't be sent.

(Source)

As such, ap_cookie_write cannot know which header table(s), if any, to use. You could provide other unrelated tables if you wanted.

In your case, you likely want to do:

request_rec *r = ctx->r;
ap_cookie_write(r, "_mycookie", "", NULL,  0L, r->headers_out, r->err_headers_out, NULL);
like image 112
Avi Avatar answered Oct 20 '22 12:10

Avi