BUG/MEDIUM: dumpstats: undefined behavior in stats_tlskeys_list()
The function stats_tlskeys_list() can meet an undefined behavior when called with appctx->st2 == STAT_ST_LIST, indeed the ref pointer is used uninitialized. However this function was using NULL in appctx->ctx.tlskeys.ref as a flag to dump every tickets from every references. A real flag appctx->ctx.tlskeys.dump_all is now used for this behavior. This patch delete the 'ref' variable and use appctx->ctx.tlskeys.ref directly.
This commit is contained in:
parent
e984a0e4fb
commit
cf9e788790
|
@ -106,6 +106,7 @@ struct appctx {
|
||||||
} map;
|
} map;
|
||||||
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
||||||
struct {
|
struct {
|
||||||
|
int dump_all;
|
||||||
struct tls_keys_ref *ref;
|
struct tls_keys_ref *ref;
|
||||||
} tlskeys;
|
} tlskeys;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1446,8 +1446,10 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
||||||
}
|
}
|
||||||
else if (strcmp(args[1], "tls-keys") == 0) {
|
else if (strcmp(args[1], "tls-keys") == 0) {
|
||||||
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
||||||
|
appctx->ctx.tlskeys.dump_all = 0;
|
||||||
/* no parameter, shows only file list */
|
/* no parameter, shows only file list */
|
||||||
if (!*args[2]) {
|
if (!*args[2]) {
|
||||||
|
appctx->ctx.tlskeys.dump_all = 1;
|
||||||
appctx->st2 = STAT_ST_INIT;
|
appctx->st2 = STAT_ST_INIT;
|
||||||
appctx->st0 = STAT_CLI_O_TLSK;
|
appctx->st0 = STAT_CLI_O_TLSK;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1456,6 +1458,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
||||||
if (args[2][0] == '*') {
|
if (args[2][0] == '*') {
|
||||||
/* list every TLS ticket keys */
|
/* list every TLS ticket keys */
|
||||||
appctx->ctx.tlskeys.ref = NULL;
|
appctx->ctx.tlskeys.ref = NULL;
|
||||||
|
appctx->ctx.tlskeys.dump_all = 1;
|
||||||
} else {
|
} else {
|
||||||
appctx->ctx.tlskeys.ref = tlskeys_ref_lookup_ref(args[2]);
|
appctx->ctx.tlskeys.ref = tlskeys_ref_lookup_ref(args[2]);
|
||||||
if(!appctx->ctx.tlskeys.ref) {
|
if(!appctx->ctx.tlskeys.ref) {
|
||||||
|
@ -6131,7 +6134,6 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si, struct st
|
||||||
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
||||||
static int stats_tlskeys_list(struct stream_interface *si) {
|
static int stats_tlskeys_list(struct stream_interface *si) {
|
||||||
struct appctx *appctx = __objt_appctx(si->end);
|
struct appctx *appctx = __objt_appctx(si->end);
|
||||||
struct tls_keys_ref *ref;
|
|
||||||
|
|
||||||
switch (appctx->st2) {
|
switch (appctx->st2) {
|
||||||
case STAT_ST_INIT:
|
case STAT_ST_INIT:
|
||||||
|
@ -6151,44 +6153,42 @@ static int stats_tlskeys_list(struct stream_interface *si) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref = appctx->ctx.tlskeys.ref;
|
|
||||||
|
|
||||||
/* Now, we start the browsing of the references lists.
|
/* Now, we start the browsing of the references lists.
|
||||||
* Note that the following call to LIST_ELEM return bad pointer. The only
|
* Note that the following call to LIST_ELEM return bad pointer. The only
|
||||||
* available field of this pointer is <list>. It is used with the function
|
* available field of this pointer is <list>. It is used with the function
|
||||||
* tlskeys_list_get_next() for retruning the first available entry
|
* tlskeys_list_get_next() for retruning the first available entry
|
||||||
*/
|
*/
|
||||||
if (ref == NULL) {
|
if (appctx->ctx.tlskeys.ref == NULL) {
|
||||||
ref = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
|
appctx->ctx.tlskeys.ref = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
|
||||||
ref = tlskeys_list_get_next(ref, &tlskeys_reference);
|
appctx->ctx.tlskeys.ref = tlskeys_list_get_next(appctx->ctx.tlskeys.ref, &tlskeys_reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
appctx->st2 = STAT_ST_LIST;
|
appctx->st2 = STAT_ST_LIST;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case STAT_ST_LIST:
|
case STAT_ST_LIST:
|
||||||
while (ref) {
|
while (appctx->ctx.tlskeys.ref) {
|
||||||
int i;
|
int i;
|
||||||
int head = ref->tls_ticket_enc_index;
|
int head = appctx->ctx.tlskeys.ref->tls_ticket_enc_index;
|
||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
if (appctx->st0 == STAT_CLI_O_TLSK_ENT)
|
if (appctx->st0 == STAT_CLI_O_TLSK_ENT)
|
||||||
chunk_appendf(&trash, "# ");
|
chunk_appendf(&trash, "# ");
|
||||||
chunk_appendf(&trash, "%d (%s)\n", ref->unique_id,
|
chunk_appendf(&trash, "%d (%s)\n", appctx->ctx.tlskeys.ref->unique_id,
|
||||||
ref->filename);
|
appctx->ctx.tlskeys.ref->filename);
|
||||||
|
|
||||||
if (appctx->st0 == STAT_CLI_O_TLSK_ENT) {
|
if (appctx->st0 == STAT_CLI_O_TLSK_ENT) {
|
||||||
for (i = 0; i < TLS_TICKETS_NO; i++) {
|
for (i = 0; i < TLS_TICKETS_NO; i++) {
|
||||||
struct chunk *t2 = get_trash_chunk();
|
struct chunk *t2 = get_trash_chunk();
|
||||||
int b64_len;
|
int b64_len;
|
||||||
|
|
||||||
chunk_reset(t2);
|
chunk_reset(t2);
|
||||||
b64_len = a2base64((char *)(ref->tlskeys + (head + 2 + i) % TLS_TICKETS_NO),
|
b64_len = a2base64((char *)(appctx->ctx.tlskeys.ref->tlskeys + (head + 2 + i) % TLS_TICKETS_NO),
|
||||||
sizeof(struct tls_sess_key), t2->str, t2->size);
|
sizeof(struct tls_sess_key), t2->str, t2->size);
|
||||||
if (b64_len < 0)
|
if (b64_len < 0)
|
||||||
return 0;
|
return 0;
|
||||||
t2->len = b64_len;
|
t2->len = b64_len;
|
||||||
chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, i, t2->str);
|
chunk_appendf(&trash, "%d.%d %s\n", appctx->ctx.tlskeys.ref->unique_id, i, t2->str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bi_putchk(si_ic(si), &trash) == -1) {
|
if (bi_putchk(si_ic(si), &trash) == -1) {
|
||||||
|
@ -6199,11 +6199,11 @@ static int stats_tlskeys_list(struct stream_interface *si) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appctx->ctx.tlskeys.ref) /* don't display everything if don't null */
|
if (appctx->ctx.tlskeys.dump_all == 0) /* don't display everything if not necessary */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* get next list entry and check the end of the list */
|
/* get next list entry and check the end of the list */
|
||||||
ref = tlskeys_list_get_next(ref, &tlskeys_reference);
|
appctx->ctx.tlskeys.ref = tlskeys_list_get_next(appctx->ctx.tlskeys.ref, &tlskeys_reference);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue