mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] NGROUPS_MAX definition conflicts with kernel one
@ 2021-07-03  2:58 Érico Nogueira
  0 siblings, 0 replies; only message in thread
From: Érico Nogueira @ 2021-07-03  2:58 UTC (permalink / raw)
  To: musl


[-- Attachment #1.1: Type: text/plain, Size: 3239 bytes --]

Hello all.

I brought this up on IRC and we thought it best to bring it up on the ML
as well.

musl's NGROUPS_MAX is defined to 32, which is the kernel's definition
for the value for linux < 2.6.4. Meanwhile, linux >= 2.6.4 has 65536.
Linux 2.6.4 also introduced /proc/sys/kernel/ngroups_max, to allow for
this value to be changed in the kernel without libc having to keep
changing their definitions.

glibc's headers define NGROUPS_MAX to 65536, the new limit, so there is
already some discrepancy between the two libraries. Fortunately, the man
pages for getgroups(2) suggests using sysconf(_SC_NGROUPS_MAX) instead
of the NGROUPS_MAX value directly, since the sysconf function can,
theoretically, query the information from the currently running kernel.
glibc's does just that: it tries to read from /proc, and if that fails,
it will return NGROUPS_MAX as defined in <limits.h>. Unfortunately,
musl's implementation directly returns NGROUPS_MAX from its own
definition of it, which means it returns 32.

There are few scenarios where I can see this being relevant, to be
honest; hardly anyone is going to have more than 32 supplementary
groups. However, in the case they do, functions like getgroups(2) will
fail even if the caller passes a buffer with size
sysconf(_SC_NGROUPS_MAX). An application could be forgiven for not
trying to increase the buffer size past it in the case that
sysconf(_SC_NGROUPS_MAX) exists (doesn't return -1).

There are a few ways forward from here: NGROUPS_MAX can be updated to
the latest kernel maximum and/or sysconf(_SC_NGROUPS_MAX) can be fixed
to try and read values from /proc; or we do nothing.

Not doing nothing would also require rolling out further fixes:

- musl's initgroups(3) uses a static array with 32 members for the
  groups, which isn't enough if we want to support cases with more
  groups; that would require implementing dynamic allocation, which,
  with naive logic, would allocate 256KB (65536 entries * sizeof(gid_t))
- any applications/libraries mainly used in the musl ecosystem might be
  relying on NPROCS_MAX being a small value that can be used, for
  example, as the size of a stack-allocated array; with a bigger size,
  this would no longer be true (see [1] as an example, though I am
  already looking into fixing that particular case)

[1] https://github.com/pikhq/musl-nscd/blob/9ab730cfb5fe3dc224ded1033e1b36ea60c60be6/src/socket_handle.c#L232

In conclusion, as mentioned on IRC, "it's a place where the old limit
was a feature", since it avoids big allocations when very very few use
cases need them. IMO, if we want to be more correct while keeping the
advantage of a low value, sysconf(_SC_NPROCS_MAX) could read /proc, but
NPROCS_MAX could be kept as 32. But I don't know how the initgroups(3)
case would deal with it. If we decide to do nothing, such a limitation
(even if derived from a design choice) should at least end up documented
clearly.

A suggestion on IRC was also that users requiring more than 32
supplementary groups could patch musl to work on their environment. For
that purpose, I have attached a patch to this email to make it simpler
for such patching to occur.

Cheers,
Érico

[-- Attachment #2: 0001-use-NGROUPS_MAX-instead-of-hardcoded-value-where-pos.patch --]
[-- Type: text/plain, Size: 1351 bytes --]

From fb980d64744e076cfcb3e93d8f5e46b3ff9543bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=89rico=20Nogueira?= <ericonr@disroot.org>
Date: Sat, 3 Jul 2021 00:31:55 -0300
Subject: [PATCH] use NGROUPS_MAX instead of hardcoded value where possible

if someone using musl finds it necessary to patch musl to use 65536 as
NGROUPS_MAX, as defined by kernels >= 2.6.4, they can patch it in one
place, include/limits.h, instead of having to find all the places where
it's hardcoded
---
 include/sys/param.h | 2 +-
 src/conf/sysconf.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/sys/param.h b/include/sys/param.h
index ce6b8019..f4780588 100644
--- a/include/sys/param.h
+++ b/include/sys/param.h
@@ -6,7 +6,7 @@
 #define MAXNAMLEN 255
 #define MAXPATHLEN 4096
 #define NBBY 8
-#define NGROUPS 32
+#define NGROUPS NGROUPS_MAX
 #define CANBSIZ 255
 #define NOFILE 256
 #define NCARGS 131072
diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c
index 3baaed32..1a5d3860 100644
--- a/src/conf/sysconf.c
+++ b/src/conf/sysconf.c
@@ -28,7 +28,7 @@ long sysconf(int name)
 		[_SC_ARG_MAX] = JT_ARG_MAX,
 		[_SC_CHILD_MAX] = RLIM(NPROC),
 		[_SC_CLK_TCK] = 100,
-		[_SC_NGROUPS_MAX] = 32,
+		[_SC_NGROUPS_MAX] = NGROUPS_MAX,
 		[_SC_OPEN_MAX] = RLIM(NOFILE),
 		[_SC_STREAM_MAX] = -1,
 		[_SC_TZNAME_MAX] = TZNAME_MAX,
-- 
2.32.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-03  4:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-03  2:58 [musl] NGROUPS_MAX definition conflicts with kernel one Érico Nogueira

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).