Fw:[PATCH] inet: add boundary check to prevent bof and inet/tst-ruserpass [BZ #33881]
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Thu Mar 12 14:12:37 GMT 2026
Hi,
This specific error could be reproduced with a default 'make check', since
this is independent of ABI. So I would recommend you to always trigger a
full make check before sending a new version.
Also, we have a .clang-format so I also recommend you running it on new files
to format it properly (it might require some minor adjustments).
Running glibc-cicd is not strictly required, and I only saw issues for some
specific tests that require kernel iteration (like newer syscalls or container
support). It should be ok to rely on make/make check locally, just keep in
mind that glibc-cicd run on i686 with DJ bots and armhf/aarch64 on Linaro ones.
On 12/03/26 08:10, c.colonna wrote:
> As an update,
>
>
> following the indication received in the irssi chat, pointing me to this repo https://gitlab.com/djdelorie/glibc-cicd.
>
>
> I managed to replicate the cicd locally and reproduce the exact same error.
>
>
> As a next step I try to make some cli script to automate running the ci in glibc-cicd locally on a patch and try to isolate exactly the failing test.
>
>
> This could speed up the troubleshooting problem and moreover ensure that the code is reproduced exactly in the same environment
>
>
>
> From"c.colonna" c.colonna@itdoctor.it
> Toarjun@redhat.com
> Cc
> DateWed, 11 Mar 2026 14:55:11 +0100
> SubjectFw:[PATCH] inet: add boundary check to prevent bof and inet/tst-ruserpass [BZ #33881]
>
> Good morning,
>
>
> I submitted this patch for glibc.
>
> I encountered some errors during CI:
>
>
> https://patchwork.sourceware.org/project/glibc/patch/20260306135229.2082046-1-c.colonna@itdoctor.it/
>
> one of them is a simple lint failure on the Makefile:
>
> https://www.delorie.com/trybots/32bit/58484/lint-makefiles.out
>
>
> FAIL: lint-makefiles
> original exit status 1
> --- /home/tcwg-build/workspace/tcwg_gnu_4/glibc/inet/Makefile.expected
> +++ /home/tcwg-build/workspace/tcwg_gnu_4/glibc/inet/Makefile 2026-03-06 17:27:16.587191199 +0000
> @@ -97,8 +97,8 @@
> tst-inet6_rth \
> tst-network \
> tst-ntoa \
> - tst-ruserpass \
> tst-sockaddr \
> + tst-ruserpass \
> # tests
>
> I can fix this easily.
>
>
> The other one is a problem in the test itself:
>
> https://www.delorie.com/trybots/32bit/58484/inet-tst-ruserpass.out
>
> Didn't expect signal from child: got `Aborted'
>
>
> I saw this message is produced by the test harness. I can suppose that something or someone aborted the test.
>
> One of my hypothesis is that maybe the failure on the other test (the lint), stopped the CI and cause this test being aborted. This is only a supposition I've no complete view of what ci do.
>
>
> In my local environment the test pass.
>
>
> Another problem might be that the test code tweaks with test files (e.g. .netrc) and env to trigger the logic the fix was written for. E.g. $HOME env var is set to point to the temporary file. Not knowing how much are isolated these tests, I cannot exclude that what pass in local environment fails in the CI maybe due to concurrent test execution in same environment.
>
>
> *I wonder if, can I fix the Makefile lint error and submit the patch again to check if the other error disappear?*
>
> This would at least exclude the correlation between those two regressions.
>
>
> Meanwhile, i'm also playing with ci code https://gitlab.com/djdelorie/glibc-cicd
>
> trying to reproduce locally the exact same env and code that lead to the regression.
>
>
> In that case I could debug the abortion in a local env.
>
>
>
> Thanks
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> From"Christian Colonna" c.colonna@itdoctor.it
> Tolibc-alpha@sourceware.org
> Cc"Christian Colonna" c.colonna@itdoctor.it
> DateFri, 6 Mar 2026 14:52:29 +0100
> Subject[PATCH] inet: add boundary check to prevent bof and inet/tst-ruserpass [BZ #33881]
>
> Add boundary checks in the token function parsing .netrc config file.
> If token was too long, the buffer storing token could overflow.
>
> Add test creating .netrc file with a long token and verify that ruserpass doesn't cause SEGFAULT.
> Add additional test to verify that when permission of .netrc are not 0600 ruserpass returns -1.
>
> Signed-off-by: Christian Colonna <c.colonna@itdoctor.it>
> ---
> inet/Makefile | 1 +
> inet/ruserpass.c | 12 ++++--
> inet/tst-ruserpass.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 96 insertions(+), 4 deletions(-)
> create mode 100644 inet/tst-ruserpass.c
>
> diff --git a/inet/Makefile b/inet/Makefile
> index 613f61d290..caeb1b0801 100644
> --- a/inet/Makefile
> +++ b/inet/Makefile
> @@ -98,6 +98,7 @@ tests := \
> tst-network \
> tst-ntoa \
> tst-sockaddr \
> + tst-ruserpass \
> # tests
> # tst-deadline must be linked statically so that we can access
> diff --git a/inet/ruserpass.c b/inet/ruserpass.c
> index be4e024203..22d835a0c1 100644
> --- a/inet/ruserpass.c
> +++ b/inet/ruserpass.c
> @@ -54,7 +54,9 @@ static FILE *cfile;
> #define ID 10
> #define MACHINE 11
> -static char tokval[100];
> +#define TOKVAL_SIZE 100
> +
> +static char tokval[TOKVAL_SIZE];
> static const char tokstr[] =
> {
> @@ -229,7 +231,8 @@ token (void)
> while ((c = getc_unlocked(cfile)) != EOF && c != '"') {
> if (c == '\\')
> c = getc_unlocked(cfile);
> - *cp++ = c;
> + if (cp-tokval < TOKVAL_SIZE)
> + *cp++ = c;
> }
> } else {
> *cp++ = c;
> @@ -237,7 +240,8 @@ token (void)
> && c != '\n' && c != '\t' && c != ' ' && c != ',') {
> if (c == '\\')
> c = getc_unlocked(cfile);
> - *cp++ = c;
> + if (cp-tokval < TOKVAL_SIZE)
> + *cp++ = c;
> }
> }
> *cp = 0;
> @@ -247,4 +251,4 @@ token (void)
> if (!strcmp(&tokstr[toktab[i].tokstr_off], tokval))
> return toktab[i].tval;
> return (ID);
> -}
> +}
> \ No newline at end of file
> diff --git a/inet/tst-ruserpass.c b/inet/tst-ruserpass.c
> new file mode 100644
> index 0000000000..7edcf56434
> --- /dev/null
> +++ b/inet/tst-ruserpass.c
> @@ -0,0 +1,87 @@
> +/* Test for ruserpass.
> + Copyright (C) 2026-2026 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +
> +
> +static char *temp_home_dir;
> +static char *temp_netrc;
> +
> +extern int ruserpass (const char *host, const char **aname, const char **apass);
> +
> +static void
> +generate_string_a (char * str, size_t len)
> +{
> + memset (str, 'a', len);
> + str[len] = '\0';
> +}
> +
> +static void
> +do_prepare (int argc, char **argv)
> +{
> + char temp_password[200];
> +
> + // creating a .netrc file for testing. In ruserpass the file is accessed relative to $HOME env, we will tweak $HOME to use our test file
> + temp_home_dir = support_create_temp_directory ("tst-ruserpass-");
> + temp_netrc = xasprintf ("%s/.netrc", temp_home_dir);
> + add_temp_file (temp_netrc);
> +
> + generate_string_a(temp_password, sizeof(temp_password) - 1);
> +
> + char * netrc_content = xasprintf ("machine foo.gnu login foo password %s\n", temp_password);
> +
> + support_write_file_string (temp_netrc, netrc_content);
> +
> + free (netrc_content);
> +}
> +
> +#define PREPARE do_prepare
> +
> +static int
> +do_test (void)
> +{
> + const char *orig_name = NULL;
> + const char *orig_pass = NULL;
> +
> + if (access (temp_netrc, R_OK) != 0)
> + FAIL_EXIT1 ("File .netrc is not readable");
> + setenv ("HOME", temp_home_dir, 1);
> +
> + // function should returns -1 if .netrc file permission is readable by others
> + TEST_COMPARE (ruserpass ("foo.gnu", &orig_name, &orig_pass), -1);
> +
> +
> + if (chmod (temp_netrc, S_IRUSR | S_IWUSR) != 0)
> + FAIL_EXIT1 ("Impossible to set .netrc permissions. We need it to be 0600 else ruserpass will exit -1.");
> +
> + // ruserpass should not segfault if password is longer than password tokval buffer
> + TEST_COMPARE (ruserpass ("foo.gnu", &orig_name, &orig_pass), EXIT_SUCCESS);
> +
> + free (temp_home_dir);
> + free (temp_netrc);
> +
> + return EXIT_SUCCESS;
> +}
> +
> +#include <support/test-driver.c>
> \ No newline at end of file
> --
> 2.39.5
>
More information about the Libc-alpha
mailing list