Skip to content

Commit 784ed43

Browse files
committed
uidgid: add map_id_range_up()
Add map_id_range_up() to verify that the full kernel id range can be mapped up in a given idmapping. This will be used in follow-up patches. Link: https://lore.kernel.org/r/20250204-work-mnt_idmap-statmount-v2-1-007720f39f2e@kernel.org Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 3129946 commit 784ed43

2 files changed

Lines changed: 23 additions & 9 deletions

File tree

include/linux/uidgid.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid)
132132

133133
u32 map_id_down(struct uid_gid_map *map, u32 id);
134134
u32 map_id_up(struct uid_gid_map *map, u32 id);
135+
u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count);
135136

136137
#else
137138

@@ -186,6 +187,11 @@ static inline u32 map_id_down(struct uid_gid_map *map, u32 id)
186187
return id;
187188
}
188189

190+
static inline u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count)
191+
{
192+
return id;
193+
}
194+
189195
static inline u32 map_id_up(struct uid_gid_map *map, u32 id)
190196
{
191197
return id;

kernel/user_namespace.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ EXPORT_SYMBOL(__put_user_ns);
238238
struct idmap_key {
239239
bool map_up; /* true -> id from kid; false -> kid from id */
240240
u32 id; /* id to find */
241-
u32 count; /* == 0 unless used with map_id_range_down() */
241+
u32 count;
242242
};
243243

244244
/*
@@ -343,16 +343,19 @@ u32 map_id_down(struct uid_gid_map *map, u32 id)
343343
* UID_GID_MAP_MAX_BASE_EXTENTS.
344344
*/
345345
static struct uid_gid_extent *
346-
map_id_up_base(unsigned extents, struct uid_gid_map *map, u32 id)
346+
map_id_range_up_base(unsigned extents, struct uid_gid_map *map, u32 id, u32 count)
347347
{
348348
unsigned idx;
349-
u32 first, last;
349+
u32 first, last, id2;
350+
351+
id2 = id + count - 1;
350352

351353
/* Find the matching extent */
352354
for (idx = 0; idx < extents; idx++) {
353355
first = map->extent[idx].lower_first;
354356
last = first + map->extent[idx].count - 1;
355-
if (id >= first && id <= last)
357+
if (id >= first && id <= last &&
358+
(id2 >= first && id2 <= last))
356359
return &map->extent[idx];
357360
}
358361
return NULL;
@@ -363,28 +366,28 @@ map_id_up_base(unsigned extents, struct uid_gid_map *map, u32 id)
363366
* Can only be called if number of mappings exceeds UID_GID_MAP_MAX_BASE_EXTENTS.
364367
*/
365368
static struct uid_gid_extent *
366-
map_id_up_max(unsigned extents, struct uid_gid_map *map, u32 id)
369+
map_id_range_up_max(unsigned extents, struct uid_gid_map *map, u32 id, u32 count)
367370
{
368371
struct idmap_key key;
369372

370373
key.map_up = true;
371-
key.count = 1;
374+
key.count = count;
372375
key.id = id;
373376

374377
return bsearch(&key, map->reverse, extents,
375378
sizeof(struct uid_gid_extent), cmp_map_id);
376379
}
377380

378-
u32 map_id_up(struct uid_gid_map *map, u32 id)
381+
u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count)
379382
{
380383
struct uid_gid_extent *extent;
381384
unsigned extents = map->nr_extents;
382385
smp_rmb();
383386

384387
if (extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
385-
extent = map_id_up_base(extents, map, id);
388+
extent = map_id_range_up_base(extents, map, id, count);
386389
else
387-
extent = map_id_up_max(extents, map, id);
390+
extent = map_id_range_up_max(extents, map, id, count);
388391

389392
/* Map the id or note failure */
390393
if (extent)
@@ -395,6 +398,11 @@ u32 map_id_up(struct uid_gid_map *map, u32 id)
395398
return id;
396399
}
397400

401+
u32 map_id_up(struct uid_gid_map *map, u32 id)
402+
{
403+
return map_id_range_up(map, id, 1);
404+
}
405+
398406
/**
399407
* make_kuid - Map a user-namespace uid pair into a kuid.
400408
* @ns: User namespace that the uid is in

0 commit comments

Comments
 (0)