Skip to content

Commit 60fb217

Browse files
committed
kernel: extend rh_waived to cope better with the CVE mitigations case
JIRA: https://issues.redhat.com/browse/RHEL-122981 This patch is a backport of the following RHEL-only commit: commit 77bb95c34bd75769a4e4d1c706cee2521bf7c455 Author: Ricardo Robaina <rrobaina@redhat.com> Date: Thu Oct 23 13:17:35 2025 -0300 kernel: extend rh_waived to cope better with the CVE mitigations case JIRA: https://issues.redhat.com/browse/RHEL-122979 This patch is a backport of the following RHEL-only commit: commit 022786346d6e09c70b647046231e0ac5d4af6f57 Author: Rafael Aquini <raquini@redhat.com> Date: Mon Oct 20 17:13:33 2025 -0400 kernel: extend rh_waived to cope better with the CVE mitigations case JIRA: https://issues.redhat.com/browse/RHEL-120391 Upstream status: RHEL-only Introduce the concept of "Waived Items" to the rh_waived original machinery so we can leverage the mechanism to allow customers waiving off issues other then just features, like performance impacting CVE mitigations, through the same interface in a consistent manner. Signed-off-by: Rafael Aquini <raquini@redhat.com> Signed-off-by: Ricardo Robaina <rrobaina@redhat.com> Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
1 parent db594c2 commit 60fb217

File tree

5 files changed

+109
-55
lines changed

5 files changed

+109
-55
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5735,12 +5735,15 @@
57355735
Set number of hash buckets for route cache
57365736

57375737
rh_waived=
5738-
Enable waived features in RHEL.
5738+
Enable waived items in RHEL.
57395739

5740-
Waived features are disabled by default in RHEL, this parameter
5741-
provides support to enable such features, as needed.
5740+
Some specific features, or security mitigations, can be
5741+
waived (toggled on/off) on demand in RHEL. However,
5742+
waiving any of these items should be used judiciously,
5743+
as it generally means the system might end up being
5744+
considered insecure or even out-of-scope for support.
57425745

5743-
Format: <feat-1>,<feat-2>...<feat-n>
5746+
Format: <item-1>,<item-2>...<item-n>
57445747

57455748
Use 'rh_waived' to enable all waived features listed at
57465749
Documentation/admin-guide/rh-waived-features.rst

Documentation/admin-guide/rh-waived-features.rst

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.. _rh_waived_items:
2+
3+
====================
4+
Red Hat Waived Items
5+
====================
6+
7+
Waived Items is a mechanism offered by Red Hat which allows customers to "waive"
8+
and utilize features that are not enabled by default as these are considered as
9+
unmaintained, insecure, rudimentary, or deprecated, but are shipped with the
10+
RHEL kernel for customer's convinience only.
11+
Waived Items can range from features that can be enabled on demand to specific
12+
security mitigations that can be disabled on demand.
13+
14+
To explicitly "waive" any of these items, RHEL offers the ``rh_waived``
15+
kernel boot parameter. To allow set of waived items, append
16+
``rh_waived=<item name>,...,<item name>`` to the kernel
17+
cmdline.
18+
Appending ``rh_waived=features`` will waive all features listed below,
19+
and appending ``rh_waived=cves`` will waive all security mitigations
20+
listed below.
21+
22+
The waived items listed in the next session follow the pattern below:
23+
24+
- item name
25+
item description
26+
27+
List of Red Hat Waived Items
28+
============================
29+

include/linux/rh_waived.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
#ifndef _RH_WAIVED_H
1010
#define _RH_WAIVED_H
1111

12-
enum rh_waived_feat {
13-
/* RH_WAIVED_FEAT_ITEMS must always be the last item in the enum */
14-
RH_WAIVED_FEAT_ITEMS,
12+
enum rh_waived_items {
13+
/* RH_WAIVED_ITEMS must always be the last item in the enum */
14+
RH_WAIVED_ITEMS,
1515
};
1616

17-
bool is_rh_waived(enum rh_waived_feat feat);
17+
bool is_rh_waived(enum rh_waived_items feat);
1818

1919
#endif /* _RH_WAIVED_H */

kernel/rh_waived.c

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,72 +17,115 @@
1717
#include <linux/rh_waived.h>
1818

1919
/*
20-
* RH_INSERT_WAIVED_FEAT
20+
* * RH_INSERT_WAIVED_ITEM
2121
* This macro is intended to be used to insert items into the
22-
* rh_waived_feat_list array. It expects to get an item from
23-
* enum rh_waived_feat as its first argument, and a string
22+
* rh_waived_list array. It expects to get an item from
23+
* enum rh_waived_items as its first argument, and a string
2424
* holding the feature name as its second argument.
2525
*
2626
* The feature name is also utilized as the token for the
2727
* boot parameter parser.
2828
*
2929
* Example usage:
30-
* struct rh_waived_feat_item foo[RH_WAIVED_FEAT_ITEMS] = {
31-
* RH_INSERT_WAIVED_FEAT(FOO_FEAT, "foo_feat_short_str"),
30+
* struct rh_waived_item foo[RH_WAIVED_FEAT_ITEMS] = {
31+
* RH_INSERT_WAIVED_ITEM(FOO_FEAT, "foo_feat_short_str", "alias", RH_WAIVED_FEAT),
3232
* };
3333
*/
34-
#define RH_INSERT_WAIVED_FEAT(enum_item, name) \
35-
[(enum_item)] = {.feat_name = (name), .enabled = 0,}
34+
#define RH_INSERT_WAIVED_ITEM(enum_item, item, item_alt, class) \
35+
[(enum_item)] = { .name = (item), .alias = (item_alt), \
36+
.type = (class), .waived = 0, }
3637

3738
/* Indicates if the rh_flag 'rh_waived' should be added. */
3839
bool __initdata add_rh_flag = false;
3940

40-
struct rh_waived_feat_item {
41-
char *feat_name;
42-
unsigned int enabled;
41+
typedef enum {
42+
RH_WAIVED_FEAT,
43+
RH_WAIVED_CVE,
44+
RH_WAIVED_ANY
45+
} rh_waived_t;
46+
47+
struct rh_waived_item {
48+
char *name, *alias;
49+
rh_waived_t type;
50+
unsigned int waived;
51+
4352
};
4453

45-
/* Always use the marco RH_INSERT_WAIVED_FEAT to insert items to this array. */
46-
struct rh_waived_feat_item rh_waived_feat_list[RH_WAIVED_FEAT_ITEMS] = {
54+
/* Always use the marco RH_INSERT_WAIVED to insert items to this array. */
55+
struct rh_waived_item rh_waived_list[RH_WAIVED_ITEMS] = {
4756
};
4857

4958
/*
50-
* is_rh_waived() - Checks if a given waived feature has been enabled.
59+
* is_rh_waived() - Checks if a given item has been marked as waived.
5160
*
52-
* @feat: waived feature.
61+
* @item: waived item.
5362
*/
54-
__inline__ bool is_rh_waived(enum rh_waived_feat feat)
63+
__inline__ bool is_rh_waived(enum rh_waived_items item)
5564
{
56-
return !!rh_waived_feat_list[feat].enabled;
65+
return !!rh_waived_list[item].waived;
5766
}
5867
EXPORT_SYMBOL(is_rh_waived);
5968

60-
static int __init rh_waived_setup(char *s)
69+
static void __init rh_waived_parser(char *s, rh_waived_t type)
6170
{
6271
int i;
6372
char *token;
6473

6574
pr_info(KERN_CONT "rh_waived: ");
6675

6776
if (!s) {
68-
for (i = 0; i < RH_WAIVED_FEAT_ITEMS; i++) {
69-
rh_waived_feat_list[i].enabled = 1;
70-
pr_info(KERN_CONT "%s%s", rh_waived_feat_list[i].feat_name,
71-
i < RH_WAIVED_FEAT_ITEMS - 1 ? " " : "\n");
77+
for (i = 0; i < RH_WAIVED_ITEMS; i++) {
78+
if (type != RH_WAIVED_ANY && rh_waived_list[i].type != type)
79+
continue;
80+
81+
rh_waived_list[i].waived = 1;
82+
pr_info(KERN_CONT "%s%s", rh_waived_list[i].name,
83+
i < RH_WAIVED_ITEMS - 1 ? " " : "\n");
7284
}
85+
86+
add_rh_flag = true;
87+
return;
7388
}
7489

7590
while ((token = strsep(&s, ",")) != NULL) {
76-
for (i = 0; i < RH_WAIVED_FEAT_ITEMS; i++) {
77-
if (!strcmp(token, rh_waived_feat_list[i].feat_name)) {
78-
rh_waived_feat_list[i].enabled = 1;
79-
pr_info(KERN_CONT "%s%s", rh_waived_feat_list[i].feat_name,
80-
i < RH_WAIVED_FEAT_ITEMS - 1 ? " " : "\n");
91+
for (i = 0; i < RH_WAIVED_ITEMS; i++) {
92+
char *alias = rh_waived_list[i].alias;
93+
94+
if (type != RH_WAIVED_ANY && rh_waived_list[i].type != type)
95+
continue;
96+
97+
if (!strcmp(token, rh_waived_list[i].name) ||
98+
(alias && !strcmp(token, alias))) {
99+
rh_waived_list[i].waived = 1;
100+
pr_info(KERN_CONT "%s ", rh_waived_list[i].name);
81101
}
82102
}
83103
}
84104

105+
pr_info(KERN_CONT "\n");
85106
add_rh_flag = true;
107+
}
108+
109+
static int __init rh_waived_setup(char *s)
110+
{
111+
/*
112+
* originally, if no string was passed to the cmdline option
113+
* all listed features would be waived, so we keep that same
114+
* compromise with the new contract.
115+
*/
116+
if (!s || !strcmp(s, "features")) {
117+
rh_waived_parser(NULL, RH_WAIVED_FEAT);
118+
return 0;
119+
}
120+
121+
/* waive all possible mitigations in the list */
122+
if (!strcmp(s, "cves")) {
123+
rh_waived_parser(NULL, RH_WAIVED_CVE);
124+
return 0;
125+
}
126+
127+
/* otherwise, just deal with the enumerated waive list */
128+
rh_waived_parser(s, RH_WAIVED_ANY);
86129

87130
return 0;
88131
}

0 commit comments

Comments
 (0)