Skip to content

Commit abe3c63

Browse files
GONG, Ruiqipcmoore
authored andcommitted
selinux: enable use of both GFP_KERNEL and GFP_ATOMIC in convert_context()
The following warning was triggered on a hardware environment: SELinux: Converting 162 SID table entries... BUG: sleeping function called from invalid context at __might_sleep+0x60/0x74 0x0 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 5943, name: tar CPU: 7 PID: 5943 Comm: tar Tainted: P O 5.10.0 #1 Call trace: dump_backtrace+0x0/0x1c8 show_stack+0x18/0x28 dump_stack+0xe8/0x15c ___might_sleep+0x168/0x17c __might_sleep+0x60/0x74 __kmalloc_track_caller+0xa0/0x7dc kstrdup+0x54/0xac convert_context+0x48/0x2e4 sidtab_context_to_sid+0x1c4/0x36c security_context_to_sid_core+0x168/0x238 security_context_to_sid_default+0x14/0x24 inode_doinit_use_xattr+0x164/0x1e4 inode_doinit_with_dentry+0x1c0/0x488 selinux_d_instantiate+0x20/0x34 security_d_instantiate+0x70/0xbc d_splice_alias+0x4c/0x3c0 ext4_lookup+0x1d8/0x200 [ext4] __lookup_slow+0x12c/0x1e4 walk_component+0x100/0x200 path_lookupat+0x88/0x118 filename_lookup+0x98/0x130 user_path_at_empty+0x48/0x60 vfs_statx+0x84/0x140 vfs_fstatat+0x20/0x30 __se_sys_newfstatat+0x30/0x74 __arm64_sys_newfstatat+0x1c/0x2c el0_svc_common.constprop.0+0x100/0x184 do_el0_svc+0x1c/0x2c el0_svc+0x20/0x34 el0_sync_handler+0x80/0x17c el0_sync+0x13c/0x140 SELinux: Context system_u:object_r:pssp_rsyslog_log_t:s0:c0 is not valid (left unmapped). It was found that within a critical section of spin_lock_irqsave in sidtab_context_to_sid(), convert_context() (hooked by sidtab_convert_params.func) might cause the process to sleep via allocating memory with GFP_KERNEL, which is problematic. As Ondrej pointed out [1], convert_context()/sidtab_convert_params.func has another caller sidtab_convert_tree(), which is okay with GFP_KERNEL. Therefore, fix this problem by adding a gfp_t argument for convert_context()/sidtab_convert_params.func and pass GFP_KERNEL/_ATOMIC properly in individual callers. Cc: [email protected] Link: https://lore.kernel.org/all/[email protected]/ [1] Reported-by: Tan Ninghao <[email protected]> Fixes: ee1a84f ("selinux: overhaul sidtab to fix bug and improve performance") Signed-off-by: GONG, Ruiqi <[email protected]> Reviewed-by: Ondrej Mosnacek <[email protected]> [PM: wrap long BUG() output lines, tweak subject line] Signed-off-by: Paul Moore <[email protected]>
1 parent 9abf231 commit abe3c63

File tree

3 files changed

+6
-5
lines changed

3 files changed

+6
-5
lines changed

security/selinux/ss/services.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,7 +2022,8 @@ static inline int convert_context_handle_invalid_context(
20222022
* in `newc'. Verify that the context is valid
20232023
* under the new policy.
20242024
*/
2025-
static int convert_context(struct context *oldc, struct context *newc, void *p)
2025+
static int convert_context(struct context *oldc, struct context *newc, void *p,
2026+
gfp_t gfp_flags)
20262027
{
20272028
struct convert_context_args *args;
20282029
struct ocontext *oc;
@@ -2036,7 +2037,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p)
20362037
args = p;
20372038

20382039
if (oldc->str) {
2039-
s = kstrdup(oldc->str, GFP_KERNEL);
2040+
s = kstrdup(oldc->str, gfp_flags);
20402041
if (!s)
20412042
return -ENOMEM;
20422043

security/selinux/ss/sidtab.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
325325
}
326326

327327
rc = convert->func(context, &dst_convert->context,
328-
convert->args);
328+
convert->args, GFP_ATOMIC);
329329
if (rc) {
330330
context_destroy(&dst->context);
331331
goto out_unlock;
@@ -404,7 +404,7 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst,
404404
while (i < SIDTAB_LEAF_ENTRIES && *pos < count) {
405405
rc = convert->func(&esrc->ptr_leaf->entries[i].context,
406406
&edst->ptr_leaf->entries[i].context,
407-
convert->args);
407+
convert->args, GFP_KERNEL);
408408
if (rc)
409409
return rc;
410410
(*pos)++;

security/selinux/ss/sidtab.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct sidtab_isid_entry {
6565
};
6666

6767
struct sidtab_convert_params {
68-
int (*func)(struct context *oldc, struct context *newc, void *args);
68+
int (*func)(struct context *oldc, struct context *newc, void *args, gfp_t gfp_flags);
6969
void *args;
7070
struct sidtab *target;
7171
};

0 commit comments

Comments
 (0)