Re: [dev] [ii] snprintf using NULL pointer with %s

From: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
Date: Mon, 6 Apr 2026 11:10:20 +0200

On Sun, Apr 05, 2026 at 02:22:34PM -0400, Aaron Burrow wrote:
> Hello,
>
> I am working from commit b6b5be5ebba548dfc0c61cd54704980d2fc50916 of
> the ii codebase. Below I describe the issue, give inputs that trigger
> the behavior, and give a patch.
>
> proc_server_cmd will call snprintf with NULL as the argument for %s
> given the right sort of input. C99 says that the argument for %s
> "shall be a pointer to the initial element of an array of character
> type." But NULL pointers are not to the initial element of any array.
>
> Here are the examples with the line numbers of where they cause the issue.
> "PONG" (line 619 with argv[TOK_TEXT])
> "PING" (line 624 with argv[TOK_TEXT])
> ":a!b " (line 619 with argv[TOK_CMD])
> ":a!b CARROT" (line 682 with argv[TOK_TEXT])
>
> All of the cases besides PING are easy to fix. For them, my patch
> just checks for NULL the same way that other parts of this function
> already do. PING is trickier because the RFC wants us to send back a
> parameter with our PONG. ii tries to handle this by just mirroring
> PING, but what should happen when PING doesn't come with a parameter?
> My patch just sends back a PONG with no parameter.
>
> diff --git a/ii.c b/ii.c
> index 98c7c09..bc2fa8a 100644
> --- a/ii.c
> +++ b/ii.c
> _AT_@ -616,12 +616,17 @@ proc_server_cmd(int fd, char *buf)
> tokenize(&argv[TOK_CMD], TOK_LAST - TOK_CMD, cmd, ' ');
>
> if (!argv[TOK_CMD] || !strcmp("PONG", argv[TOK_CMD])) {
> - snprintf(msg, sizeof(msg), "-!- %s %s", argv[TOK_CMD],
> argv[TOK_TEXT]);
> + snprintf(msg, sizeof(msg), "-!- %s %s",
> + argv[TOK_CMD] ? argv[TOK_CMD] : "",
> + argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
> channel_print(channelmaster, msg);
> return;
> } else if (!strcmp("PING", argv[TOK_CMD])) {
> channel_print(channelmaster, "-!- sending PONG to PING
> request");
> - snprintf(msg, sizeof(msg), "PONG %s\r\n", argv[TOK_TEXT]);
> + if (!argv[TOK_TEXT])
> + snprintf(msg, sizeof(msg), "PONG\r\n");
> + else
> + snprintf(msg, sizeof(msg), "PONG %s\r\n",
> argv[TOK_TEXT]);
> channel_print(channelmaster, msg);
> ewritestr(fd, msg);
> return;
> _AT_@ -679,7 +684,8 @@ proc_server_cmd(int fd, char *buf)
> snprintf(msg, sizeof(msg), "<%s> %s", argv[TOK_NICKSRV],
> argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
> } else {
> - snprintf(msg, sizeof(msg), "-!- unknown cmd %s",
> argv[TOK_TEXT]);
> + snprintf(msg, sizeof(msg), "-!- unknown cmd %s",
> + argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
> channel_print(channelmaster, msg);
> return; /* can't read this message */
> }
>
> Thanks,
> Aaron Burrow
>
> PS: I should mention that I became aware of this issue by prompting
> ChatGPT to look for correctness issues in ii's source. I wrote and
> tested the patch.
>

Hi Aaron,

Thanks for the patch. I have pushed it.

The patch white-space was garbled I think and I made some changes: I think PONG
should have a mandatory argument, so now it is not sent.

        https://www.rfc-editor.org/rfc/rfc1459#section-4.6.3

-- 
Kind regards,
Hiltjo
Received on Mon Apr 06 2026 - 11:10:20 CEST

This archive was generated by hypermail 2.3.0 : Mon Apr 06 2026 - 11:24:08 CEST