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

firejail.h: add missing linux/limits.h include & include cleanup #4583

Merged
merged 4 commits into from
Oct 9, 2021

Conversation

kmk3
Copy link
Collaborator

@kmk3 kmk3 commented Sep 28, 2021

Should fix #4578.

Cc: @Duncaen @dm9pZCAq (from #4578)

None of the files affected use any macros from linux/limits.h:

    $ git grep -Fl 'NGROUPS_MAX
    ARG_MAX
    LINK_MAX
    MAX_CANON
    MAX_INPUT
    NAME_MAX
    PATH_MAX
    PIPE_BUF
    XATTR_NAME_MAX
    XATTR_SIZE_MAX
    XATTR_LIST_MAX
    RTSIG_MAX' -- src
    src/firejail/cmdline.c
    src/firejail/firejail.h
    src/libtrace/libtrace.c
    src/libtracelog/libtracelog.c

Environment:

    $ grep '^NAME' /etc/os-release
    NAME="Artix Linux"
    $ pacman -Qo /usr/include/linux/limits.h
    /usr/include/linux/limits.h is owned by linux-api-headers 5.12.3-1

Note: This include has been present on all of the affected files since
their inception.  For restrict_users.c, that's on commit 4f003da
("prevent leaking user information by modifying /home directory,
/etc/passwd and /etc/group") and for every other file, it's on commit
1379851 ("Baseline firejail 0.9.28").

Relates to netblue30#4578.
@kmk3
Copy link
Collaborator Author

kmk3 commented Sep 28, 2021

From https://github.com/netblue30/firejail/pull/4583/checks?check_run_id=3736745444:

make[1]: Entering directory '/home/runner/work/firejail/firejail/src/libtracelog'
clang-11 -ggdb -W -Wall -Werror -O2 -DVERSION='"0.9.67"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security  -c libtracelog.c -o libtracelog.o
libtracelog.c:724:2: error: expected expression
        int rv = orig_fchdir(fd);
        ^
libtracelog.c:725:9: error: use of undeclared identifier 'rv'
        return rv;
               ^
2 errors generated.
make[1]: *** [Makefile:18: libtracelog.o] Error 1
make: *** [Makefile:42: src/libtracelog/libtracelog.so] Error 2
make[1]: Leaving directory '/home/runner/work/firejail/firejail/src/libtracelog'
Error: Process completed with exit code 2.

From https://github.com/netblue30/firejail/pull/4583/checks?check_run_id=3736745378:

  + make
  libtracelog.c: In function ‘fchdir’:
  libtracelog.c:724:2: error: a label can only be part of a statement and a declaration is not a statement
    724 |  int rv = orig_fchdir(fd);
        |  ^~~
  make[1]: *** [Makefile:18: libtracelog.o] Error 1
  make: *** [Makefile:42: src/libtracelog/libtracelog.so] Error 2

Interesting, this compiles with CC=gcc but fails with CC=clang.

Fixed by replacing ret: with ret:; and force-pushed.

@rusty-snake
Copy link
Collaborator

OT: +1 for leaving a comment about force push changes.

@kmk3
Copy link
Collaborator Author

kmk3 commented Sep 28, 2021

@dm9pZCAq Could you test if this branch fixes #4578?

@Duncaen
Copy link
Contributor

Duncaen commented Sep 28, 2021

limits.h should be fine, simple grep does not work because it includes other files, but its the right header for PATH_MAX.

@dm9pZCAq
Copy link
Contributor

@dm9pZCAq Could you test if this branch fixes?

yes, everything compiles successfully without any warnings or errors

thank you

@kmk3 kmk3 marked this pull request as draft September 28, 2021 23:51
firejail.h uses PATH_MAX when defining a macro.  Note that ARG_MAX and
PATH_MAX are not guaranteed to be (and potentially should not be)
defined.  From POSIX.1-2017's limits.h(0p)[1]:

> A definition of one of the symbolic constants in the following list
> shall be omitted from the <limits.h> header on specific
> implementations where the corresponding value is equal to or greater
> than the stated minimum, but where the value can vary depending on the
> file to which it is applied.  The actual value supported for a
> specific pathname shall be provided by the pathconf() function.

Use linux/limits.h instead of limits.h because glibc's limits.h
deliberately undefines ARG_MAX.  See glibc commit f96853beaf
("* sysdeps/unix/sysv/linux/bits/local_lim.h: Undefined ARG_MAX if",
2008-03-27)[2].

From /usr/include/bits/local_lim.h (glibc 2.33-5 on Artix Linux):

    #ifndef ARG_MAX
    # define __undef_ARG_MAX
    #endif

    /* The kernel sources contain a file with all the needed information.  */
    #include <linux/limits.h>
    /* [...] */
    /* Have to remove ARG_MAX?  */
    #ifdef __undef_ARG_MAX
    # undef ARG_MAX
    # undef __undef_ARG_MAX
    #endif

So if a file uses ARG_MAX (currently only cmdline.c) and limits.h (or a
firejail.h that includes limits.h) is included before linux/limits.h,
then the build will fail on glibc.  Build log from using limits.h
(instead of linux/limits.h) on firejail.h:

    $ make clean >/dev/null && make >/dev/null
    cmdline.c:145:12: error: use of undeclared identifier 'ARG_MAX'; did you mean 'CFG_MAX'?
            if (len > ARG_MAX) {
                      ^~~~~~~
                      CFG_MAX
    ./firejail.h:805:2: note: 'CFG_MAX' declared here
            CFG_MAX // this should always be the last entry
            ^
    [...]

Fixes netblue30#4578.

[1] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
[2] https://sourceware.org/git/?p=glibc.git;a=commit;h=f96853beafc26d4f030961b0b67a79b5bfad5733
@kmk3
Copy link
Collaborator Author

kmk3 commented Oct 1, 2021

Force-push changes:

Dropped these 2 commits:

  • f4171df ("Fix wrong limits.h include (should be linux/limits.h)")
  • 4ba2b17 ("Get ARG_MAX/PATH_MAX from sysconf/pathconf instead of linux/limits.h")

They require some changes and I found an alternative solution in one file. I
might submit them separately later.

Reworded this commit:

  • e228db3 ("firejail.h: add missing linux/limits.h include")

And added a comment about ARG_MAX.


@Duncaen commented on Sep 28:

limits.h should be fine, simple grep does not work because it includes
other files, but its the right header for PATH_MAX.

Using limits.h breaks the build on Artix. After much debugging and confusion,
the answer was in the POSIX man pages all along. I'll just copy and paste the
reworded commit (579f856):

firejail.h: add missing linux/limits.h include

firejail.h uses PATH_MAX when defining a macro. Note that ARG_MAX and
PATH_MAX are not guaranteed to be (and potentially should not be)
defined. From POSIX.1-2017's limits.h(0p)[1]:

A definition of one of the symbolic constants in the following list
shall be omitted from the <limits.h> header on specific
implementations where the corresponding value is equal to or greater
than the stated minimum, but where the value can vary depending on the
file to which it is applied. The actual value supported for a
specific pathname shall be provided by the pathconf() function.

Use linux/limits.h instead of limits.h because glibc's limits.h
deliberately undefines ARG_MAX. See glibc commit f96853beaf
("* sysdeps/unix/sysv/linux/bits/local_lim.h: Undefined ARG_MAX if",
2008-03-27)[2].

From /usr/include/bits/local_lim.h (glibc 2.33-5 on Artix Linux):

#ifndef ARG_MAX
# define __undef_ARG_MAX
#endif

/* The kernel sources contain a file with all the needed information.  */
#include <linux/limits.h>
/* [...] */
/* Have to remove ARG_MAX?  */
#ifdef __undef_ARG_MAX
# undef ARG_MAX
# undef __undef_ARG_MAX
#endif

So if a file uses ARG_MAX (currently only cmdline.c) and limits.h (or a
firejail.h that includes limits.h) is included before linux/limits.h,
then the build will fail on glibc. Build log from using limits.h
(instead of linux/limits.h) on firejail.h:

$ make clean >/dev/null && make >/dev/null
cmdline.c:145:12: error: use of undeclared identifier 'ARG_MAX'; did you mean 'CFG_MAX'?
        if (len > ARG_MAX) {
                  ^~~~~~~
                  CFG_MAX
./firejail.h:805:2: note: 'CFG_MAX' declared here
        CFG_MAX // this should always be the last entry
        ^
[...]

Fixes #4578.

[1] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
[2] https://sourceware.org/git/?p=glibc.git;a=commit;h=f96853beafc26d4f030961b0b67a79b5bfad5733

@kmk3
Copy link
Collaborator Author

kmk3 commented Oct 1, 2021

@dm9pZCAq commented on Sep 28:

@dm9pZCAq Could you test if this branch fixes?

yes, everything compiles successfully without any warnings or errors

thank you

Thanks for testing.

@kmk3 kmk3 changed the title Fix include limits.h & Use sysconf/pathconf when possible firejail.h: add missing linux/limits.h include & include cleanup Oct 1, 2021
@kmk3 kmk3 marked this pull request as ready for review October 1, 2021 22:40
@netblue30 netblue30 merged commit bb815a4 into netblue30:master Oct 9, 2021
@netblue30
Copy link
Owner

I ended up merging it myself!

kmk3 added a commit to kmk3/firejail that referenced this pull request Oct 14, 2021
PATH_MAX is not guaranteed to be defined and it may be defined to -1.
Avoid depending on it by getting the result directly from realpath.  See
commit 579f856 ("firejail.h: add missing linux/limits.h include") /
PR netblue30#4583 for details.

Note: This replaces the static char array currently used with a dynamic
one returned from realpath.

Misc: This is a continuation of netblue30#4583.
kmk3 added a commit to kmk3/firejail that referenced this pull request Oct 16, 2021
PATH_MAX is not guaranteed to be defined and it may be defined to -1.
Avoid depending on it by getting the result directly from realpath.  See
commit 579f856 ("firejail.h: add missing linux/limits.h include") /
PR netblue30#4583 for details.

Note: This replaces the static char array currently used with a dynamic
one returned from realpath.

Misc: This is a continuation of netblue30#4583.
kmk3 added a commit that referenced this pull request Feb 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done (on RELNOTES)
Development

Successfully merging this pull request may close these issues.

PATH_MAX is undeclared on musl libc
5 participants