git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] imap-send: increase command size limit

From
René Scharfe <l.s.r@web.de>
Date
Apr 14, 2024, 16:47 UTC
Message-ID
<7026075c-db4e-4d43-bbd1-d2edb52da9b7@web.de>

nfvasprintf() has a 8KB limit, but it's not relevant, as its result is combined with other strings and added to a 1KB buffer by its caller. That 1KB limit is not mentioned in RFC 9051, which specifies IMAP.

While 1KB is plenty for user names, passwords and mailbox names, there's no point in limiting our commands like that. Call xstrvfmt() instead of open-coding it and use strbuf to format the command to send, as we need its length. Fail hard if it exceeds INT_MAX, because socket_write() can't take more than that.

Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: René Scharfe <l.s.r@web.de>
---
This time I compiled with NO_CURL=1 and NO_APPLE_COMMON_CRYPTO=1 and
verified with a silly printf that the changed code was actually used
and wrote the present message to an IMAP folder whose name is 1006
characters log, which required a 1026 bytes long APPEND command.  Yay,
freedom!
Ran into a build issue, will send a separate patch for that.
 imap-send.c | 35 ++++++++++++-----------------------
 1 file changed, 12 insertions(+), 23 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 4caa8668e6..0afd088d8a 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -68,20 +68,6 @@ static void imap_warn(const char *, ...);

 static char *next_arg(char **);

-static int nfvasprintf(char **strp, const char *fmt, va_list ap)
-{
-	int len;
-	char tmp[8192];
-
-	len = vsnprintf(tmp, sizeof(tmp), fmt, ap);
-	if (len < 0)
-		die("Fatal: Out of memory");
-	if (len >= sizeof(tmp))
-		die("imap command overflow!");
-	*strp = xmemdupz(tmp, len);
-	return len;
-}
-
 struct imap_server_conf {
 	const char *name;
 	const char *tunnel;
@@ -503,11 +489,11 @@ static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
 {
 	struct imap *imap = ctx->imap;
 	struct imap_cmd *cmd;
-	int n, bufl;
-	char buf[1024];
+	int n;
+	struct strbuf buf = STRBUF_INIT;

 	cmd = xmalloc(sizeof(struct imap_cmd));
-	nfvasprintf(&cmd->cmd, fmt, ap);
+	cmd->cmd = xstrvfmt(fmt, ap);
 	cmd->tag = ++imap->nexttag;

 	if (cb)
@@ -519,27 +505,30 @@ static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
 		get_cmd_result(ctx, NULL);

 	if (!cmd->cb.data)
-		bufl = xsnprintf(buf, sizeof(buf), "%d %s\r\n", cmd->tag, cmd->cmd);
+		strbuf_addf(&buf, "%d %s\r\n", cmd->tag, cmd->cmd);
 	else
-		bufl = xsnprintf(buf, sizeof(buf), "%d %s{%d%s}\r\n",
-				 cmd->tag, cmd->cmd, cmd->cb.dlen,
-				 CAP(LITERALPLUS) ? "+" : "");
+		strbuf_addf(&buf, "%d %s{%d%s}\r\n", cmd->tag, cmd->cmd,
+			    cmd->cb.dlen, CAP(LITERALPLUS) ? "+" : "");
+	if (buf.len > INT_MAX)
+		die("imap command overflow!");

 	if (0 < verbosity) {
 		if (imap->num_in_progress)
 			printf("(%d in progress) ", imap->num_in_progress);
 		if (!starts_with(cmd->cmd, "LOGIN"))
-			printf(">>> %s", buf);
+			printf(">>> %s", buf.buf);
 		else
 			printf(">>> %d LOGIN <user> <pass>\n", cmd->tag);
 	}
-	if (socket_write(&imap->buf.sock, buf, bufl) != bufl) {
+	if (socket_write(&imap->buf.sock, buf.buf, buf.len) != buf.len) {
 		free(cmd->cmd);
 		free(cmd);
 		if (cb)
 			free(cb->data);
+		strbuf_release(&buf);
 		return NULL;
 	}
+	strbuf_release(&buf);
 	if (cmd->cb.data) {
 		if (CAP(LITERALPLUS)) {
 			n = socket_write(&imap->buf.sock, cmd->cb.data, cmd->cb.dlen);
--
2.44.0
Next: brian m. carlson
Message 1 of 8 in “imap-send: increase command size limit”
  1. imap-send: increase command size limitRené Scharfe, Apr 14, 2024
  2. brian m. carlsonApr 14, 2024
  3. Junio C HamanoApr 15, 2024
  4. Jeff KingApr 15, 2024
  5. René ScharfeApr 16, 2024
  6. Jeff KingApr 15, 2024
  7. René ScharfeApr 16, 2024
  8. Jeff KingApr 17, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.