Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wBnrf-001ODn-0K for pgsql-hackers@arkaria.postgresql.org; Sun, 12 Apr 2026 06:00:11 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wBnrc-001GQZ-1b for pgsql-hackers@arkaria.postgresql.org; Sun, 12 Apr 2026 06:00:09 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wBnrc-001GQR-0N for pgsql-hackers@lists.postgresql.org; Sun, 12 Apr 2026 06:00:09 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wBnra-00000000cqZ-1EWO for pgsql-hackers@lists.postgresql.org; Sun, 12 Apr 2026 06:00:08 +0000 Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-488ba840146so31644765e9.1 for ; Sat, 11 Apr 2026 23:00:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775973605; x=1776578405; darn=lists.postgresql.org; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=8LcCAnthjJfu0rgH1qiFBq5YG5OJPoMPu8N7rrWN0FY=; b=a+f9yzrsgC6QqiTNEXXRUQz2uIaq9HxRZA0qTPqgewarv9RfPwCpQr1TQN9N0MxWQ5 Q5FMnj3qMBlQfuHs4Rcvw/lqft/qFFplvN2RD40yrlqfyQ25Pv+J4JJwNTmCRq8hJQt9 txcVrPpl2k6Bj/vKBGcmcvoRD69JcP8LFR1mtZ4U62aj04PR5DHE9DbGcZ4JVDWexFJR D8qbjJ7dGBersAUr0RTOfuP/oJqii3BmBfbCWxDFUfk9juQaGblgXRufXanX+xP1RDlm a/ZMqWZQM0xXj4s88WX2xIi6IuSSZJg7g6Z1pQk53D+mp6VhTRUF6z3YNuLrVuieQbmj ftyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775973605; x=1776578405; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=8LcCAnthjJfu0rgH1qiFBq5YG5OJPoMPu8N7rrWN0FY=; b=EQICG/cY2WYZnPVUWR9D8x0q7NrhIp8dtqTT9TlVq9Hkomkgt/WIed13s8genJqylx 5URGFPYpDEkUlheZeS89CUbd9qaoL+FIrTh8pGkKUhtxxIcLXHcz2ls20yfGjD6RBkPv gOkpl1xElh82OBjo0qkWkPO0liHcZqB6k+gdI/RGLePszPRISUE73NrTXWvlek/0amcU ROUb9Z2jNSumnuiR2jNBS7sE5sYtDu2QaudtTQ+HDxA1gGh61XL1LXD1KVG42YiFmxHD M3Tl9ZvLfYoFCJ07YHJQKJqwVNszg3O1wzIhfU6K182sL6tXHtlmqaYv4ShJKPVDmY3s QaVg== X-Gm-Message-State: AOJu0Yx0p/WoqK4+vNnlqOQ8gsQBQty4JVShrMECPrTmzkI81jCmx5cP umwLFnay1gUJuEUDeKr/dIZ/svVR+BOcRW5rDwFhKj16MBt879Ovv9ag3k0efg== X-Gm-Gg: AeBDiesT+Isg0b/BAi5a7Wflt7qpsoonJTefgyt3+9zwW7zvXbLOh/rw9hF8Y/YX12F Htb6LnZn3UpRcpj+tZpi9MHCnLFlZ2UG95vuaUbpXbeJ+XJdA5xMeYPKjmbGcTlMo3WzLyyat0R flY7yMuzwjYIoaJyR3yp+a6NWXyWvX757NPYIEN/C5KAg9G55AhzCHZrWJvb2LLzqgmz97f5Jrx 6jn944G0ID0Ny8d3jwwml8g/S4hBAmNU2QJ4A3YNpgeGKOkgsRnhb0jweLJdg8+nhzA2Z/KAuQy 3528ADt7oOdXzg6gx/jaBh7TWeUYd/HvNCcceHOK8zgqugdsbuWZWI5hCuaqVpMBVYnod2XjWUt YmomuyAq2lNEY/I2++7VTTYnPhlaLPdx2WB0e4ntSr4xwAcXCvEAcmaYoO4NVm6ULLTO8Rbmc6D hG1wTdPR9GHPD6kTMwgek4v8W1 X-Received: by 2002:a05:600c:3f19:b0:485:3ff1:d5ed with SMTP id 5b1f17b1804b1-488d67bbc2amr105844215e9.1.1775973604546; Sat, 11 Apr 2026 23:00:04 -0700 (PDT) Received: from [192.168.0.50] ([89.149.68.143]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-488d68603f4sm61779405e9.27.2026.04.11.23.00.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 11 Apr 2026 23:00:01 -0700 (PDT) Content-Type: multipart/alternative; boundary="------------Iw9dQkqxJQ69S0uRf0eC7JYL" Message-ID: <09df9d75-13e7-45fe-89af-33fe118e797b@gmail.com> Date: Sun, 12 Apr 2026 09:00:00 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Non-compliant SASLprep implementation for ASCII characters To: Michael Paquier , John Naylor Cc: Postgres hackers References: Content-Language: en-US From: Alexander Lakhin In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------Iw9dQkqxJQ69S0uRf0eC7JYL Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello Michael, 19.03.2026 06:25, Michael Paquier wrote: > Applied the result for the module, to have at least the coverage part. > The last piece is refreshed, and attached for now. > -- When running make check for src/test/modules/test_saslprep under Valgrind, I've discovered: # --- /pgtest/postgresql.git/src/test/modules/test_saslprep/expected/test_saslprep.out 2026-04-12 07:44:47.090517505 +0300 # +++ /pgtest/postgresql.git/src/test/modules/test_saslprep/results/test_saslprep.out 2026-04-12 08:03:29.353348951 +0300 # @@ -2,151 +2,7 @@ #  CREATE EXTENSION test_saslprep; #  -- Incomplete UTF-8 sequence. #  SELECT test_saslprep('\xef'); # -  test_saslprep # ------------------ # - (,INVALID_UTF8) # -(1 row) # - ... - -DROP EXTENSION test_saslprep; +server closed the connection unexpectedly +   This probably means the server terminated abnormally +   before or while processing the request. +connection to server was lost src/test/modules/test_saslprep/log/postmaster.log 2026-04-12 08:03:26.064 EEST postmaster[1043298] LOG:  database system is ready to accept connections 2026-04-12 08:03:26.078 EEST dead-end client backend[1043325] [unknown] FATAL:  the database system is starting up ==00:00:00:04.413 1043360== Invalid read of size 1 ==00:00:00:04.413 1043360==    at 0x484F234: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==00:00:00:04.413 1043360==    by 0x5277C6F: strlcpy (strlcpy.c:24) ==00:00:00:04.413 1043360==    by 0x48648CF: test_saslprep (test_saslprep.c:87) ==00:00:00:04.413 1043360==    by 0x541A45: ExecInterpExpr (execExprInterp.c:979) ==00:00:00:04.413 1043360==    by 0x5446A1: ExecInterpExprStillValid (execExprInterp.c:2301) ==00:00:00:04.413 1043360==    by 0x5AD1FD: ExecEvalExprNoReturn (executor.h:433) ==00:00:00:04.413 1043360==    by 0x5AD2BB: ExecEvalExprNoReturnSwitchContext (executor.h:474) ==00:00:00:04.413 1043360==    by 0x5AD31C: ExecProject (executor.h:506) ==00:00:00:04.413 1043360==    by 0x5AD53F: ExecResult (nodeResult.c:135) ==00:00:00:04.413 1043360==    by 0x55F5E4: ExecProcNodeFirst (execProcnode.c:469) ==00:00:00:04.413 1043360==    by 0x55108F: ExecProcNode (executor.h:327) ==00:00:00:04.413 1043360==    by 0x554149: ExecutePlan (execMain.c:1736) ==00:00:00:04.413 1043360==  Address 0x7439295 is 6,917 bytes inside a block of size 8,192 alloc'd ==00:00:00:04.413 1043360==    at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==00:00:00:04.413 1043360==    by 0xADBE27: AllocSetContextCreateInternal (aset.c:444) ==00:00:00:04.413 1043360==    by 0x762E31: PostmasterMain (postmaster.c:534) ==00:00:00:04.413 1043360==    by 0x5E9543: main (main.c:231) ==00:00:00:04.413 1043360== ... ==00:00:00:04.413 1043360== ==00:00:00:04.414 1043360== Exit program on first error (--exit-on-first-error=yes) 2026-04-12 08:03:29.349 EEST postmaster[1043298] LOG:  client backend (PID 1043360) exited with exit code 1 2026-04-12 08:03:29.349 EEST postmaster[1043298] DETAIL:  Failed process was running: SELECT test_saslprep('\xef'); The corresponding code:     src_len = VARSIZE_ANY_EXHDR(string);     src = VARDATA_ANY(string);     /*      * Copy the input given, to make SASLprep() act on a sanitized string.      */     input_data = palloc0(src_len + 1);     strlcpy(input_data, src, src_len + 1); That is, strlcpy() tries to evaluate strlen() for src, which contains only one byte without null terminator. skink tests this module successfully [1] by some reason: ================================== 151/394 =================================== test:         test_saslprep - postgresql:test_saslprep/regress start time:   13:26:00 duration:     8.04s result:       exit status 0 command:      ... ----------------------------------- stdout ----------------------------------- # executing test in /home/bf/bf-build/skink-master/HEAD/pgsql.build/testrun/test_saslprep/regress group test_saslprep test regress # initializing database system by copying initdb template # using temp instance on port 40096 with PID 3982971 ok 1         - test_saslprep                            1971 ms 1..1 # All 1 tests passed. # test succeeded [1] https://buildfarm.postgresql.org/cgi-bin/show_stage_log.pl?nm=skink&dt=2026-04-11%2011%3A31%3A01&stg=misc-check Best regards, Alexander --------------Iw9dQkqxJQ69S0uRf0eC7JYL Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
Hello Michael,

19.03.2026 06:25, Michael Paquier wrote:
Applied the result for the module, to have at least the coverage part.
The last piece is refreshed, and attached for now.
--

When running make check for src/test/modules/test_saslprep under Valgrind,
I've discovered:
# --- /pgtest/postgresql.git/src/test/modules/test_saslprep/expected/test_saslprep.out  2026-04-12 07:44:47.090517505 +0300
# +++ /pgtest/postgresql.git/src/test/modules/test_saslprep/results/test_saslprep.out   2026-04-12 08:03:29.353348951 +0300
# @@ -2,151 +2,7 @@
#  CREATE EXTENSION test_saslprep;
#  -- Incomplete UTF-8 sequence.
#  SELECT test_saslprep('\xef');
# -  test_saslprep  
# ------------------
# - (,INVALID_UTF8)
# -(1 row)
# -
...
-
-DROP EXTENSION test_saslprep;
+server closed the connection unexpectedly
+   This probably means the server terminated abnormally
+   before or while processing the request.
+connection to server was lost

src/test/modules/test_saslprep/log/postmaster.log
2026-04-12 08:03:26.064 EEST postmaster[1043298] LOG:  database system is ready to accept connections
2026-04-12 08:03:26.078 EEST dead-end client backend[1043325] [unknown] FATAL:  the database system is starting up
==00:00:00:04.413 1043360== Invalid read of size 1
==00:00:00:04.413 1043360==    at 0x484F234: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:00:04.413 1043360==    by 0x5277C6F: strlcpy (strlcpy.c:24)
==00:00:00:04.413 1043360==    by 0x48648CF: test_saslprep (test_saslprep.c:87)
==00:00:00:04.413 1043360==    by 0x541A45: ExecInterpExpr (execExprInterp.c:979)
==00:00:00:04.413 1043360==    by 0x5446A1: ExecInterpExprStillValid (execExprInterp.c:2301)
==00:00:00:04.413 1043360==    by 0x5AD1FD: ExecEvalExprNoReturn (executor.h:433)
==00:00:00:04.413 1043360==    by 0x5AD2BB: ExecEvalExprNoReturnSwitchContext (executor.h:474)
==00:00:00:04.413 1043360==    by 0x5AD31C: ExecProject (executor.h:506)
==00:00:00:04.413 1043360==    by 0x5AD53F: ExecResult (nodeResult.c:135)
==00:00:00:04.413 1043360==    by 0x55F5E4: ExecProcNodeFirst (execProcnode.c:469)
==00:00:00:04.413 1043360==    by 0x55108F: ExecProcNode (executor.h:327)
==00:00:00:04.413 1043360==    by 0x554149: ExecutePlan (execMain.c:1736)
==00:00:00:04.413 1043360==  Address 0x7439295 is 6,917 bytes inside a block of size 8,192 alloc'd
==00:00:00:04.413 1043360==    at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:00:04.413 1043360==    by 0xADBE27: AllocSetContextCreateInternal (aset.c:444)
==00:00:00:04.413 1043360==    by 0x762E31: PostmasterMain (postmaster.c:534)
==00:00:00:04.413 1043360==    by 0x5E9543: main (main.c:231)
==00:00:00:04.413 1043360==
...
==00:00:00:04.413 1043360==
==00:00:00:04.414 1043360== Exit program on first error (--exit-on-first-error=yes)
2026-04-12 08:03:29.349 EEST postmaster[1043298] LOG:  client backend (PID 1043360) exited with exit code 1
2026-04-12 08:03:29.349 EEST postmaster[1043298] DETAIL:  Failed process was running: SELECT test_saslprep('\xef');

The corresponding code:
    src_len = VARSIZE_ANY_EXHDR(string);
    src = VARDATA_ANY(string);

    /*
     * Copy the input given, to make SASLprep() act on a sanitized string.
     */
    input_data = palloc0(src_len + 1);
    strlcpy(input_data, src, src_len + 1);

That is, strlcpy() tries to evaluate strlen() for src, which contains only
one byte without null terminator.

skink tests this module successfully [1] by some reason:
================================== 151/394 ===================================
test:         test_saslprep - postgresql:test_saslprep/regress
start time:   13:26:00
duration:     8.04s
result:       exit status 0
command:      ...
----------------------------------- stdout -----------------------------------
# executing test in /home/bf/bf-build/skink-master/HEAD/pgsql.build/testrun/test_saslprep/regress group test_saslprep test regress
# initializing database system by copying initdb template
# using temp instance on port 40096 with PID 3982971
ok 1         - test_saslprep                            1971 ms
1..1
# All 1 tests passed.
# test succeeded

[1] https://buildfarm.postgresql.org/cgi-bin/show_stage_log.pl?nm=skink&dt=2026-04-11%2011%3A31%3A01&stg=misc-check

Best regards,
Alexander
--------------Iw9dQkqxJQ69S0uRf0eC7JYL--