]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
lib/idmapping.c: Fix get_map_ranges range check
authorTobias Stoeckmann <tobias@stoeckmann.org>
Mon, 11 Nov 2024 19:28:52 +0000 (20:28 +0100)
committerAlejandro Colomar <alx@kernel.org>
Wed, 13 Nov 2024 17:17:03 +0000 (18:17 +0100)
The get_map_ranges function shall support the whole accepted range
as specified in user_namespaces(7), i.e. upper and lower from 0 to
UINT_MAX - 1 as well as range from 1 to UINT_MAX. The actual limit of
range depends on values of upper and lower and adding the range
to either upper or lower shall never overflow UINT_MAX.

Fixes: 7c43eb2c4ea6 (2024-07-11, "lib/idmapping.c: get_map_ranges(): Move range check to a2ul() call")
Fixes: ff2baed5dbf8 (2016-08-14, "idmapping: add more checks for overflow")
Fixes: 94da3dc5c853 (2016-08-14, "also check upper for wrap")
Fixes: 7f5a14817d30 (2016-07-31, "get_map_ranges: check for overflow")
Co-authored-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/idmapping.c

index 248269c84006a2fe81cd736ef91f54b4de14841d..a46c8c2480c33f90d98651da38e81e50a3ace20a 100644 (file)
@@ -52,23 +52,19 @@ get_map_ranges(int ranges, int argc, char **argv)
        /* Gather up the ranges from the command line */
        m = mappings;
        for (int i = 0; i < ranges * 3; i+=3, m++) {
-               if (a2ul(&m->upper, argv[i + 0], NULL, 0, 0, UINT_MAX) == -1) {
+               if (a2ul(&m->upper, argv[i + 0], NULL, 0, 0, UINT_MAX - 1) == -1) {
                        if (errno == ERANGE)
                                fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
                        free(mappings);
                        return NULL;
                }
-               if (a2ul(&m->lower, argv[i + 1], NULL, 0, 0, UINT_MAX) == -1) {
+               if (a2ul(&m->lower, argv[i + 1], NULL, 0, 0, UINT_MAX - 1) == -1) {
                        if (errno == ERANGE)
                                fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
                        free(mappings);
                        return NULL;
                }
-               if (a2ul(&m->count, argv[i + 2], NULL, 0, 0,
-                        MIN(MIN(UINT_MAX, ULONG_MAX - 1) - m->lower,
-                            MIN(UINT_MAX, ULONG_MAX - 1) - m->upper))
-                   == -1)
-               {
+               if (a2ul(&m->count, argv[i + 2], NULL, 0, 1, UINT_MAX - MAX(m->lower, m->upper)) == -1) {
                        if (errno == ERANGE)
                                fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
                        free(mappings);