From: Łukasz Stelmach Date: Fri, 9 Aug 2024 12:53:37 +0000 (+0200) Subject: kdbus: Translate new u64-based kernel_cap_t to u32-based kdbus_caps X-Git-Tag: accepted/tizen/unified/20240812.190117^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=deeb72f8e7ae8bed01af6719730b282b72843040;p=platform%2Fkernel%2Flinux-tizen-modules-source.git kdbus: Translate new u64-based kernel_cap_t to u32-based kdbus_caps Using kernel_cap_t in kdbus_meta_caps changes the alignment of userland facing structures which breaks userland code trying to parse the structure sent in kdbus header. Translate kernel_cap_t to u32 similarly to what's done in capget(2). Change-Id: I8c21746dca2972cbc0ad48dfea4dba2216c0669c Ref: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f122a08b197d076ccf136c73fae0146875812a88 Fixes: e59920a ("kdbus: use u64 capability for v6.3 or later version") Signed-off-by: Łukasz Stelmach --- diff --git a/kernel/kdbus/metadata.c b/kernel/kdbus/metadata.c index 58cd85e..a9e819e 100644 --- a/kernel/kdbus/metadata.c +++ b/kernel/kdbus/metadata.c @@ -128,16 +128,18 @@ struct kdbus_meta_conn { char *conn_description; }; +/* The macros has been missing since 6.3 */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) +#define _KERNEL_CAPABILITY_U32S 2 +#define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1) +#endif + /* fixed size equivalent of "kdbus_caps" */ struct kdbus_meta_caps { u32 last_cap; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) - kernel_cap_t cap_sets[4]; -#else struct { u32 caps[_KERNEL_CAPABILITY_U32S]; } set[4]; -#endif }; /** @@ -771,25 +773,35 @@ static void kdbus_meta_export_caps(struct kdbus_meta_caps *out, #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) if (parent) { - out->cap_sets[0] = cred->cap_inheritable; - out->cap_sets[1] = cred->cap_permitted; - out->cap_sets[2] = cred->cap_effective; - out->cap_sets[3] = cred->cap_bset; + out->set[0].caps[0] = cred->cap_inheritable.val; + out->set[0].caps[1] = cred->cap_inheritable.val >> 32; + out->set[1].caps[0] = cred->cap_permitted.val; + out->set[1].caps[1] = cred->cap_permitted.val >> 32; + out->set[2].caps[0] = cred->cap_effective.val; + out->set[2].caps[1] = cred->cap_effective.val >> 32; + out->set[3].caps[0] = cred->cap_bset.val; + out->set[3].caps[1] = cred->cap_bset.val >> 32; } else if (owner) { - out->cap_sets[0] = CAP_EMPTY_SET; - out->cap_sets[1] = CAP_FULL_SET; - out->cap_sets[2] = CAP_FULL_SET; - out->cap_sets[3] = CAP_FULL_SET; + out->set[0].caps[0] = CAP_EMPTY_SET.val; + out->set[0].caps[1] = CAP_EMPTY_SET.val >> 32; + out->set[1].caps[0] = CAP_FULL_SET.val; + out->set[1].caps[1] = CAP_FULL_SET.val >> 32; + out->set[2].caps[0] = CAP_FULL_SET.val; + out->set[2].caps[1] = CAP_FULL_SET.val >> 32; + out->set[3].caps[0] = CAP_FULL_SET.val; + out->set[3].caps[1] = CAP_FULL_SET.val >> 32; + } else { - out->cap_sets[0] = CAP_EMPTY_SET; - out->cap_sets[1] = CAP_EMPTY_SET; - out->cap_sets[2] = CAP_EMPTY_SET; - out->cap_sets[3] = CAP_EMPTY_SET; + out->set[0].caps[0] = CAP_EMPTY_SET.val; + out->set[0].caps[1] = CAP_EMPTY_SET.val >> 32; + out->set[1].caps[0] = CAP_EMPTY_SET.val; + out->set[1].caps[1] = CAP_EMPTY_SET.val >> 32; + out->set[2].caps[0] = CAP_EMPTY_SET.val; + out->set[2].caps[1] = CAP_EMPTY_SET.val >> 32; + out->set[3].caps[0] = CAP_EMPTY_SET.val; + out->set[3].caps[1] = CAP_EMPTY_SET.val >> 32; } - /* clear unused bits */ - for (i = 0; i < 4; i++) - out->cap_sets[i].val &= CAP_VALID_MASK; #else CAP_FOR_EACH_U32(i) { if (parent) { @@ -810,11 +822,11 @@ static void kdbus_meta_export_caps(struct kdbus_meta_caps *out, } } +#endif /* clear unused bits */ for (i = 0; i < 4; i++) out->set[i].caps[CAP_TO_INDEX(CAP_LAST_CAP)] &= CAP_LAST_U32_VALID_MASK; -#endif } /* This is equivalent to from_kuid_munged(), but maps INVALID_UID to itself */