Skip to content

Commit b69f0ae

Browse files
keestorvalds
authored andcommitted
pid: Replace struct pid 1-element array with flex-array
For pid namespaces, struct pid uses a dynamically sized array member, "numbers". This was implemented using the ancient 1-element fake flexible array, which has been deprecated for decades. Replace it with a C99 flexible array, refactor the array size calculations to use struct_size(), and address elements via indexes. Note that the static initializer (which defines a single element) works as-is, and requires no special handling. Without this, CONFIG_UBSAN_BOUNDS (and potentially CONFIG_FORTIFY_SOURCE) will trigger bounds checks: https://lore.kernel.org/lkml/20230517-bushaltestelle-super-e223978c1ba6@brauner Cc: Christian Brauner <[email protected]> Cc: Jan Kara <[email protected]> Cc: Jeff Xu <[email protected]> Cc: Andreas Gruenbacher <[email protected]> Cc: Daniel Verkamp <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: Jeff Xu <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Boqun Feng <[email protected]> Cc: Luis Chamberlain <[email protected]> Cc: Frederic Weisbecker <[email protected]> Reported-by: [email protected] [brauner: dropped unrelated changes and remove 0 with NULL cast] Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Christian Brauner <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 112e7e2 commit b69f0ae

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

include/linux/pid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct pid
6767
/* wait queue for pidfd notifications */
6868
wait_queue_head_t wait_pidfd;
6969
struct rcu_head rcu;
70-
struct upid numbers[1];
70+
struct upid numbers[];
7171
};
7272

7373
extern struct pid init_struct_pid;

kernel/pid.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,8 +656,11 @@ void __init pid_idr_init(void)
656656

657657
idr_init(&init_pid_ns.idr);
658658

659-
init_pid_ns.pid_cachep = KMEM_CACHE(pid,
660-
SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT);
659+
init_pid_ns.pid_cachep = kmem_cache_create("pid",
660+
struct_size((struct pid *)NULL, numbers, 1),
661+
__alignof__(struct pid),
662+
SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT,
663+
NULL);
661664
}
662665

663666
static struct file *__pidfd_fget(struct task_struct *task, int fd)

kernel/pid_namespace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static struct kmem_cache *create_pid_cachep(unsigned int level)
4848
return kc;
4949

5050
snprintf(name, sizeof(name), "pid_%u", level + 1);
51-
len = sizeof(struct pid) + level * sizeof(struct upid);
51+
len = struct_size((struct pid *)NULL, numbers, level + 1);
5252
mutex_lock(&pid_caches_mutex);
5353
/* Name collision forces to do allocation under mutex. */
5454
if (!*pkc)

0 commit comments

Comments
 (0)