Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frr: fix compilation with GCC14 #24242

Merged
merged 1 commit into from
Jun 5, 2024

Conversation

httpstorm
Copy link
Contributor

Fixes:

zebra/zebra_netns_notify.c: In function 'zebra_ns_ready_read': zebra/zebra_netns_notify.c:265:40: error: implicit declaration of function 'basename' [-Wimplicit-function-declaration]
  265 |         if (strmatch(VRF_DEFAULT_NAME, basename(netnspath))) {
      |                                        ^~~~~~~~

Maintainer: @lucize
Compile tested: WRT3200ACM

Another pending PR: #24083

@neheb @robimarko @PolynomialDivision @1715173329 @trippleflux

@httpstorm httpstorm force-pushed the frr.gcc-14-compatibility branch from 38b6496 to 270c077 Compare May 27, 2024 15:01
@neheb
Copy link
Contributor

neheb commented May 27, 2024

I would check if netnspath is writable.

@httpstorm
Copy link
Contributor Author

httpstorm commented May 28, 2024

@neheb
Good catch. According to the macOS man page for basename

basename() returns a pointer to internal static storage space that will be overwritten by subsequent calls.
Other vendor implementations of basename() may modify the contents of the string passed to basename(); this should be taken into account when writing code which calls this function if portability is desired.

Edit: according to https://man7.org/linux/man-pages/man3/basename.3.html

There are two different versions of basename() - the POSIX
       version described above, and the GNU version, which one gets
       after

               #define _GNU_SOURCE         /* See feature_test_macros(7) */
               #include <string.h>

       The GNU version never modifies its argument, and returns the
       empty string when path has a trailing slash, and in particular
       also when it is "/".  There is no GNU version of dirname().

       With glibc, one gets the POSIX version of basename() when
       <libgen.h> is included, and the GNU version otherwise.

So if we include libgen.h, we switch from the GNU version that does not modify the argument to the POSIX version which does. And we are likely to break frr. I will change the PR to draft, until we decide what to do. Any suggestions?

I analysed a part of the code path: we start with void *arg which is assigned to struct zebra_netns_info *, where const char *netnspath; is not writable. This is assigned to const char *netnspath; and passed to basename. So if basename tries to update netnspath, bad things may happen. I think it's worth reporting upstream. Edit: the same applies to branch master.

struct event {
	…
	void *arg;		      /* event argument */
	…
};
…
struct zebra_netns_info {
	const char *netnspath;
	unsigned int retries;
};
…
int strcmp(const char *s1, const char *s2);
…
#define strmatch(a,b) (!strcmp((a), (b)))
…
#define EVENT_ARG(X) ((X)->arg)
…
struct zebra_netns_info *zns_info = EVENT_ARG(t);
const char *netnspath;
…
netnspath = zns_info->netnspath;
…
if (strmatch(VRF_DEFAULT_NAME, basename(netnspath))) {

https://github.com/FRRouting/frr/blob/9852228d1e87bdbad13e0fed8313203f00bf26af/zebra/zebra_netns_notify.c#L235
https://github.com/FRRouting/frr/blob/9852228d1e87bdbad13e0fed8313203f00bf26af/lib/frrevent.h#L114

@httpstorm httpstorm marked this pull request as draft May 28, 2024 11:28
@httpstorm httpstorm force-pushed the frr.gcc-14-compatibility branch from 3d1f77b to fd82290 Compare May 28, 2024 15:02
@httpstorm httpstorm marked this pull request as ready for review May 28, 2024 15:03
@httpstorm httpstorm force-pushed the frr.gcc-14-compatibility branch from fd82290 to c9755bb Compare May 28, 2024 15:18
@httpstorm
Copy link
Contributor Author

@neheb
Changes:
Pass a copy of netnspath to basename, and use the result in all places that would call basename.
Let me know of any other changes are needed. I also added a git label for sending the patch upstream.

@neheb
Copy link
Contributor

neheb commented May 28, 2024

basename is

char *basename(char *path)

yet const char* are passed.

I wonder if the build warns because of this.

@httpstorm httpstorm force-pushed the frr.gcc-14-compatibility branch from c9755bb to 3e67390 Compare May 28, 2024 20:13
@httpstorm
Copy link
Contributor Author

@neheb
My bad, it should be netnspath_basename = basename(strdupa(netnspath));. Yes, it does warn.

Before

arm-openwrt-linux-muslgnueabi-gcc -DHAVE_CONFIG_H -DSYSCONFDIR=\"/etc/frr/\" -DCONFDATE=0 -I.  -I./lib/assert -I. -I./include -I./lib -I.    -I/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/usr/include -I/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include -I/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify  -fms-extensions -fno-omit-frame-pointer -funwind-tables -Wall -Wextra -Wformat-nonliteral -Wformat-security -Wswitch-enum -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Wundef -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers  -I/Volumes/wrt3200/openwrt/staging_dir/target-arm_cortex-a9+vfpv3-d16_musl_eabi/usr/include      -Os -pipe -fno-caller-saves -fno-plt -fhonour-copts -mfloat-abi=hard -fmacro-prefix-map=/Volumes/wrt3200/openwrt/build_dir/target-arm_cortex-a9+vfpv3-d16_musl_eabi/frr-9852228d1e87bdbad13e0fed8313203f00bf26af=frr-9852228d1e87bdbad13e0fed8313203f00bf26af -flto=auto -fno-fat-lto-objects -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro  -c -o zebra/zebra_netns_notify.o zebra/zebra_netns_notify.c
In file included from ./lib/zebra.h:16,
                 from zebra/zebra_netns_notify.c:7:
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h: In function 'snprintf':
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h:101:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  101 |         return __orig_snprintf(__s, __n, __f, __builtin_va_arg_pack());
      |         ^~~~~~
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h: In function 'sprintf':
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h:110:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  110 |                 __r = __orig_snprintf(__s, __b, __f, __builtin_va_arg_pack());
      |                 ^~~
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h:114:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  114 |                 __r = __orig_sprintf(__s, __f, __builtin_va_arg_pack());
      |                 ^~~
zebra/zebra_netns_notify.c: In function 'zebra_ns_ready_read':
zebra/zebra_netns_notify.c:265:39: warning: passing argument 1 of 'basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
  265 |         netnspath_basename = basename(netnspath);
      |                                       ^~~~~~~~~
In file included from zebra/zebra_netns_notify.c:17:
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/libgen.h:9:16: note: expected 'char *' but argument is of type 'const char *'
    9 | char *basename(char *);
      |                ^~~~~~

After

arm-openwrt-linux-muslgnueabi-gcc -DHAVE_CONFIG_H -DSYSCONFDIR=\"/etc/frr/\" -DCONFDATE=0 -I.  -I./lib/assert -I. -I./include -I./lib -I.    -I/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/usr/include -I/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include -I/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify  -fms-extensions -fno-omit-frame-pointer -funwind-tables -Wall -Wextra -Wformat-nonliteral -Wformat-security -Wswitch-enum -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Wundef -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers  -I/Volumes/wrt3200/openwrt/staging_dir/target-arm_cortex-a9+vfpv3-d16_musl_eabi/usr/include      -Os -pipe -fno-caller-saves -fno-plt -fhonour-copts -mfloat-abi=hard -fmacro-prefix-map=/Volumes/wrt3200/openwrt/build_dir/target-arm_cortex-a9+vfpv3-d16_musl_eabi/frr-9852228d1e87bdbad13e0fed8313203f00bf26af=frr-9852228d1e87bdbad13e0fed8313203f00bf26af -flto=auto -fno-fat-lto-objects -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro  -c -o zebra/zebra_netns_notify.o zebra/zebra_netns_notify.c
In file included from ./lib/zebra.h:16,
                 from zebra/zebra_netns_notify.c:7:
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h: In function 'snprintf':
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h:101:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  101 |         return __orig_snprintf(__s, __n, __f, __builtin_va_arg_pack());
      |         ^~~~~~
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h: In function 'sprintf':
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h:110:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  110 |                 __r = __orig_snprintf(__s, __b, __f, __builtin_va_arg_pack());
      |                 ^~~
/Volumes/wrt3200/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-14.1.0_musl_eabi/include/fortify/stdio.h:114:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  114 |                 __r = __orig_sprintf(__s, __f, __builtin_va_arg_pack());
      |                 ^~~

@BKPepe
Copy link
Member

BKPepe commented May 29, 2024

It looks like it is quite different from FRRouting/frr#15987 , which also tries to fix build errors for GCC14.

@httpstorm
Copy link
Contributor Author

httpstorm commented May 29, 2024

@BKPepe
That does nothing to address our build error. I tested to confirm.
Edit: If you like, I can submit my PR upstream once someone confirms it is good, then address any remaining issues with them, and once accepted, backport the results here.

@robimarko
Copy link
Contributor

It would be great if you open a PR against FRR to upstream this

@httpstorm httpstorm force-pushed the frr.gcc-14-compatibility branch 3 times, most recently from a8f360a to 2455b35 Compare June 4, 2024 09:01
@httpstorm
Copy link
Contributor Author

@robimarko @neheb
PR for upstream: FRRouting/frr#16155

Fixes:
zebra/zebra_netns_notify.c: In function 'zebra_ns_ready_read':
zebra/zebra_netns_notify.c:265:40: error: implicit declaration of function 'basename' [-Wimplicit-function-declaration]
  265 |         if (strmatch(VRF_DEFAULT_NAME, basename(netnspath))) {
      |                                        ^~~~~~~~

Fixed by including libgen.h, then since basename may modify its
parameter, allocate a copy on the stack, using strdupa, and pass the
temporary string to basename.

According to the man page for basename:
With glibc, one gets the POSIX version of basename() when
<libgen.h> is included, and the GNU version otherwise.

The POSIX version of basename may modify the contents of path,
so we should to pass a copy when calling this function.

[1] https://man7.org/linux/man-pages/man3/basename.3.html

Signed-off-by: Georgi Valkov <[email protected]>
@httpstorm httpstorm force-pushed the frr.gcc-14-compatibility branch from 2455b35 to cc3480f Compare June 5, 2024 13:59
@BKPepe
Copy link
Member

BKPepe commented Jun 5, 2024

It seems like upstream merged it. Great work! 👏 This is how it should be. Appreciated.

I will merge this once CI/CD succeeds.

@httpstorm
Copy link
Contributor Author

httpstorm commented Jun 5, 2024

@robimarko @neheb
Accepted upstream, so rebase on master and update PKG_RELEASE, which I previously forgot to do.

@BKPepe Thanks! :) tests completed

@BKPepe BKPepe merged commit 4ef2b7e into openwrt:master Jun 5, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants