MINOR: capabilities: use _LINUX_CAPABILITY_VERSION_3

Linux kernel shows the warning below, when _LINUX_CAPABILITY_VERSION_1 is
used in capset() and capget().

        [1710243.523230] capability: warning: `haproxy' uses 32-bit capabilities (legacy support in use)

This triggers questions from users. Warning is shown by kernel, because
since Linux 2.6.25, 64-bit capabilities support was introduced in
_LINUX_CAPABILITY_VERSION_2. It's in order to be able to continiously
extend capabilities list with the new ones.

We can't use _LINUX_CAPABILITY_VERSION_2, because this version triggers
another warning, according linux/kernel/capability.c (see also more details
about it in comments from kernel sources and in man capset(2)).

kernel/capability.c:
    ...
    static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy)
    {
            __u32 version;

            if (get_user(version, &header->version))
                    return -EFAULT;

            switch (version) {
            case _LINUX_CAPABILITY_VERSION_1:
                    warn_legacy_capability_use();
                    *tocopy = _LINUX_CAPABILITY_U32S_1;
                    break;
            case _LINUX_CAPABILITY_VERSION_2:
                    warn_deprecated_v2();
                    fallthrough;    /* v3 is otherwise equivalent to v2 */
            case _LINUX_CAPABILITY_VERSION_3:
                    *tocopy = _LINUX_CAPABILITY_U32S_3;
                    break;
            default:
            ...

So, to avoid any warnings, lets use _LINUX_CAPABILITY_VERSION_3, which
according to comments in linux/kernel/capability.c, has the same
functionality as _LINUX_CAPABILITY_VERSION_2 (i.e. array of 2
__user_cap_data_struct with 32-bits integers for each capability set), but
comes in Linux 2.6.26 with a header change, in order to protect legacy
source code.

For the moment, we don't authorize capabilities higher, than CAP_SYS_ADMIN
(21-st bit), so we always check the "low" 32 bits, i.e.
__user_cap_data_struct[0].
This commit is contained in:
Valentine Krasnobaeva 2024-06-22 01:03:38 +02:00 committed by Willy Tarreau
parent e2e756a67d
commit fba9ade891
1 changed files with 4 additions and 4 deletions

View File

@ -28,7 +28,7 @@
struct __user_cap_header_struct cap_hdr_haproxy = {
.pid = 0, /* current process */
.version = _LINUX_CAPABILITY_VERSION_1,
.version = _LINUX_CAPABILITY_VERSION_3,
};
/* supported names, zero-terminated */
@ -87,7 +87,7 @@ int prepare_caps_from_permitted_set(int from_uid, int to_uid, const char *progra
* only _LINUX_CAPABILITY_U32S_1 * (sizeof(struct __user_cap_data_struct)),
* i.e. only the __user_cap_data_struct[0].
*/
struct __user_cap_data_struct start_cap_data[_LINUX_CAPABILITY_U32S_1] = { };
struct __user_cap_data_struct start_cap_data[_LINUX_CAPABILITY_U32S_3] = { };
/* started as root */
if (!from_uid)
@ -162,7 +162,7 @@ int prepare_caps_for_setuid(int from_uid, int to_uid)
* only _LINUX_CAPABILITY_U32S_1 * (sizeof(struct __user_cap_data_struct)),
* i.e. only the __user_cap_data_struct[0].
*/
struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_1] = { };
struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_3] = { };
if (from_uid != 0)
return 0;
@ -211,7 +211,7 @@ int prepare_caps_for_setuid(int from_uid, int to_uid)
*/
int finalize_caps_after_setuid(int from_uid, int to_uid)
{
struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_1] = { };
struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_3] = { };
if (from_uid != 0)
return 0;