This is the start of the stable review cycle for the 5.10.34 release.
There are 2 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Sun, 02 May 2021 14:19:04 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.34-rc…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 5.10.34-rc1
Tomas Winkler <tomas.winkler(a)intel.com>
mei: me: add Alder Lake P device id.
Jiri Kosina <jkosina(a)suse.cz>
iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_gen2_enqueue_hcmd()
-------------
Diffstat:
Makefile | 4 ++--
drivers/misc/mei/hw-me-regs.h | 1 +
drivers/misc/mei/pci-me.c | 1 +
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 7 ++++---
4 files changed, 8 insertions(+), 5 deletions(-)
From: Martin Wilck <mwilck(a)suse.com>
We have observed a few crashes run_timer_softirq(), where a broken
timer_list struct belonging to an anatt_timer was encountered. The broken
structures look like this, and we see actually multiple ones attached to
the same timer base:
crash> struct timer_list 0xffff92471bcfdc90
struct timer_list {
entry = {
next = 0xdead000000000122, // LIST_POISON2
pprev = 0x0
},
expires = 4296022933,
function = 0xffffffffc06de5e0 <nvme_anatt_timeout>,
flags = 20
}
If such a timer is encountered in run_timer_softirq(), the kernel
crashes. The test scenario was an I/O load test with lots of NVMe
controllers, some of which were removed and re-added on the storage side.
I think this may happen if the rdma recovery_work starts, in this call
chain:
nvme_rdma_error_recovery_work()
/* this stops all sorts of activity for the controller, but not
the multipath-related work queue and timer */
nvme_rdma_reconnect_or_remove(ctrl)
=> kicks reconnect_work
work queue: reconnect_work
nvme_rdma_reconnect_ctrl_work()
nvme_rdma_setup_ctrl()
nvme_rdma_configure_admin_queue()
nvme_init_identify()
nvme_mpath_init()
# this sets some fields of the timer_list without taking a lock
timer_setup()
nvme_read_ana_log()
mod_timer() or del_timer_sync()
Similar for TCP. The idea for the patch is based on the observation that
nvme_rdma_reset_ctrl_work() calls nvme_stop_ctrl()->nvme_mpath_stop(),
whereas nvme_rdma_error_recovery_work() stops only the keepalive timer, but
not the anatt timer. Also, nvme_mpath_init() is the only place where
the anatt_timer structure is accessed without locking.
[The following paragraph was contributed by Chao Leng <lengchao(a)huawei.com>]
The process maybe:1.ana_work add the timer;2.error recovery occurs,
in reconnecting, reinitialize the timer and call nvme_read_ana_log,
nvme_read_ana_log may add the timer again.
The same timer is added twice, crash will happens later.
This situation has actually been observed in a crash dump, where we
found an anatt timer pending that had been started ~80s ago, despite a
log message telling that the anatt timer for the same controller had
timed out a few seconds ago. This could only be explained by the same
timer having been attached multiple times.
Signed-off-by: Martin Wilck <mwilck(a)suse.com>
Reviewed-by: Sagi Grimberg <sagi(a)grimberg.me>
Reviewed-by: Chao Leng <lengchao(a)huawei.com>
Cc: stable(a)vger.kernel.org
----
Changes in v4: Updated commit message with Chao Leng's analysis, as
suggested by Daniel Wagner.
Changes in v3: Changed the subject line, as suggested by Sagi Grimberg
Changes in v2: Moved call to nvme_mpath_stop() further down, directly before
the call of nvme_rdma_reconnect_or_remove() (Chao Leng)
---
drivers/nvme/host/multipath.c | 1 +
drivers/nvme/host/rdma.c | 1 +
drivers/nvme/host/tcp.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index a1d476e1ac02..c63dd5dfa7ff 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -586,6 +586,7 @@ void nvme_mpath_stop(struct nvme_ctrl *ctrl)
del_timer_sync(&ctrl->anatt_timer);
cancel_work_sync(&ctrl->ana_work);
}
+EXPORT_SYMBOL_GPL(nvme_mpath_stop);
#define SUBSYS_ATTR_RW(_name, _mode, _show, _store) \
struct device_attribute subsys_attr_##_name = \
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index be905d4fdb47..fc07a7b0dc1d 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -1202,6 +1202,7 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)
return;
}
+ nvme_mpath_stop(&ctrl->ctrl);
nvme_rdma_reconnect_or_remove(ctrl);
}
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index a0f00cb8f9f3..46287b4f4d10 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -2068,6 +2068,7 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work)
return;
}
+ nvme_mpath_stop(ctrl);
nvme_tcp_reconnect_or_remove(ctrl);
}
--
2.31.1
When encoder validation of a display mode fails, retry with less bandwidth
heavy YCbCr420 color mode, if available. This enables some HDMI 1.4 setups
to support 4k60Hz output, which previously failed silently.
AMDGPU had nearly the exact same issue. This problem description is
therefore copied from my commit message of the AMDGPU patch.
On some setups, while the monitor and the gpu support display modes with
pixel clocks of up to 600MHz, the link encoder might not. This prevents
YCbCr444 and RGB encoding for 4k60Hz, but YCbCr420 encoding might still be
possible. However, which color mode is used is decided before the link
encoder capabilities are checked. This patch fixes the problem by retrying
to find a display mode with YCbCr420 enforced and using it, if it is
valid.
I'm not entierly sure if the second
"if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))" check in
intel_hdmi_compute_config(...) after forcing ycbcr420 is necessary. I
included it to better be safe then sorry.
Signed-off-by: Werner Sembach <wse(a)tuxedocomputers.com>
Cc: <stable(a)vger.kernel.org>
---
Rebased from 5.12 to drm-tip and resend to resolve merge conflict.
>From 876c1c8d970ff2a411ee8d08651bd4edbe9ecb3d Mon Sep 17 00:00:00 2001
From: Werner Sembach <wse(a)tuxedocomputers.com>
Date: Thu, 29 Apr 2021 13:59:30 +0200
Subject: [PATCH] Retry using YCbCr420 encoding if clock setup for RGB fails
---
drivers/gpu/drm/i915/display/intel_hdmi.c | 80 +++++++++++++++++------
1 file changed, 60 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 46de56af33db..c9b5a7d7f9c6 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1861,6 +1861,30 @@ static int intel_hdmi_port_clock(int clock, int bpc)
return clock * bpc / 8;
}
+static enum drm_mode_status
+intel_hdmi_check_bpc(struct intel_hdmi *hdmi, int clock, bool has_hdmi_sink, struct drm_i915_private *dev_priv)
+{
+ enum drm_mode_status status;
+
+ /* check if we can do 8bpc */
+ status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 8),
+ true, has_hdmi_sink);
+
+ if (has_hdmi_sink) {
+ /* if we can't do 8bpc we may still be able to do 12bpc */
+ if (status != MODE_OK && !HAS_GMCH(dev_priv))
+ status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 12),
+ true, has_hdmi_sink);
+
+ /* if we can't do 8,12bpc we may still be able to do 10bpc */
+ if (status != MODE_OK && DISPLAY_VER(dev_priv) >= 11)
+ status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 10),
+ true, has_hdmi_sink);
+ }
+
+ return status;
+}
+
static enum drm_mode_status
intel_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
@@ -1891,23 +1915,18 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
if (drm_mode_is_420_only(&connector->display_info, mode))
clock /= 2;
- /* check if we can do 8bpc */
- status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 8),
- true, has_hdmi_sink);
+ status = intel_hdmi_check_bpc(hdmi, clock, has_hdmi_sink, dev_priv);
- if (has_hdmi_sink) {
- /* if we can't do 8bpc we may still be able to do 12bpc */
- if (status != MODE_OK && !HAS_GMCH(dev_priv))
- status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 12),
- true, has_hdmi_sink);
+ if (status != MODE_OK) {
+ if (drm_mode_is_420_also(&connector->display_info, mode)) {
+ /* if we can't do full color resolution we may still be able to do reduced color resolution */
+ clock /= 2;
- /* if we can't do 8,12bpc we may still be able to do 10bpc */
- if (status != MODE_OK && DISPLAY_VER(dev_priv) >= 11)
- status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 10),
- true, has_hdmi_sink);
+ status = intel_hdmi_check_bpc(hdmi, clock, has_hdmi_sink, dev_priv);
+ }
+ if (status != MODE_OK)
+ return status;
}
- if (status != MODE_OK)
- return status;
return intel_mode_valid_max_plane_size(dev_priv, mode, false);
}
@@ -1990,14 +2009,17 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
static int
intel_hdmi_ycbcr420_config(struct intel_crtc_state *crtc_state,
- const struct drm_connector_state *conn_state)
+ const struct drm_connector_state *conn_state,
+ const bool force_ycbcr420)
{
struct drm_connector *connector = conn_state->connector;
struct drm_i915_private *i915 = to_i915(connector->dev);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
- if (!drm_mode_is_420_only(&connector->display_info, adjusted_mode))
+ if (!(drm_mode_is_420_only(&connector->display_info, adjusted_mode) ||
+ (force_ycbcr420 &&
+ drm_mode_is_420_also(&connector->display_info, adjusted_mode))))
return 0;
if (!connector->ycbcr_420_allowed) {
@@ -2126,7 +2148,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
struct drm_connector *connector = conn_state->connector;
struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
- int ret;
+ int ret, ret_saved;
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
@@ -2141,7 +2163,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
pipe_config->pixel_multiplier = 2;
- ret = intel_hdmi_ycbcr420_config(pipe_config, conn_state);
+ ret = intel_hdmi_ycbcr420_config(pipe_config, conn_state, false);
if (ret)
return ret;
@@ -2155,8 +2177,26 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
intel_hdmi_has_audio(encoder, pipe_config, conn_state);
ret = intel_hdmi_compute_clock(encoder, pipe_config);
- if (ret)
- return ret;
+ if (ret) {
+ ret_saved = ret;
+
+ ret = intel_hdmi_ycbcr420_config(pipe_config, conn_state, true);
+ if (ret)
+ return ret;
+
+ if (pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
+ return ret_saved;
+
+ pipe_config->limited_color_range =
+ intel_hdmi_limited_color_range(pipe_config, conn_state);
+
+ if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))
+ pipe_config->has_pch_encoder = true;
+
+ ret = intel_hdmi_compute_clock(encoder, pipe_config);
+ if (ret)
+ return ret;
+ }
if (conn_state->picture_aspect_ratio)
adjusted_mode->picture_aspect_ratio =
--
2.25.1
commit 4dbc6a4ef06d ("usb: typec: ucsi: save power data objects
in PD mode") introduced retrieval of the PDOs when connected to a
PD-capable source. But only the first 4 PDOs are received since
that is the maximum number that can be fetched at a time given the
MESSAGE_IN length limitation (16 bytes). However, as per the PD spec
a connected source may advertise up to a maximum of 7 PDOs.
If such a source is connected it's possible the UCSI FW could have
negotiated a power contract with one of the PDOs at index greater
than 4, and would be reflected in the request data object's (RDO)
object position field. This would result in an out-of-bounds access
when the rdo_index() is used to index into the src_pdos array in
ucsi_psy_get_voltage_now().
We can resolve this by instead retrieving and storing up to the
maximum of 7 PDOs in the con->src_pdos array. This would involve
two calls to the GET_PDOS command.
Fixes: 992a60ed0d5e ("usb: typec: ucsi: register with power_supply class")
Fixes: 4dbc6a4ef06d ("usb: typec: ucsi: save power data objects in PD mode")
Cc: stable(a)vger.kernel.org
Signed-off-by: Jack Pham <jackp(a)codeaurora.org>
---
drivers/usb/typec/ucsi/ucsi.c | 41 +++++++++++++++++++++++++++--------
drivers/usb/typec/ucsi/ucsi.h | 6 +++--
2 files changed, 36 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 244270755ae6..ac214b855986 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -495,7 +495,8 @@ static void ucsi_unregister_altmodes(struct ucsi_connector *con, u8 recipient)
}
}
-static void ucsi_get_pdos(struct ucsi_connector *con, int is_partner)
+static int ucsi_get_pdos(struct ucsi_connector *con, int is_partner,
+ u32 *pdos, int offset, int num_pdos)
{
struct ucsi *ucsi = con->ucsi;
u64 command;
@@ -503,17 +504,39 @@ static void ucsi_get_pdos(struct ucsi_connector *con, int is_partner)
command = UCSI_COMMAND(UCSI_GET_PDOS) | UCSI_CONNECTOR_NUMBER(con->num);
command |= UCSI_GET_PDOS_PARTNER_PDO(is_partner);
- command |= UCSI_GET_PDOS_NUM_PDOS(UCSI_MAX_PDOS - 1);
+ command |= UCSI_GET_PDOS_PDO_OFFSET(offset);
+ command |= UCSI_GET_PDOS_NUM_PDOS(num_pdos - 1);
command |= UCSI_GET_PDOS_SRC_PDOS;
- ret = ucsi_send_command(ucsi, command, con->src_pdos,
- sizeof(con->src_pdos));
- if (ret < 0) {
+ ret = ucsi_send_command(ucsi, command, pdos + offset,
+ num_pdos * sizeof(u32));
+ if (ret < 0)
dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret);
+ if (ret == 0 && offset == 0)
+ dev_warn(ucsi->dev, "UCSI_GET_PDOS returned 0 bytes\n");
+
+ return ret;
+}
+
+static void ucsi_get_src_pdos(struct ucsi_connector *con, int is_partner)
+{
+ int ret;
+
+ /* UCSI max payload means only getting at most 4 PDOs at a time */
+ ret = ucsi_get_pdos(con, 1, con->src_pdos, 0, UCSI_MAX_PDOS);
+ if (ret < 0)
return;
- }
+
con->num_pdos = ret / sizeof(u32); /* number of bytes to 32-bit PDOs */
- if (ret == 0)
- dev_warn(ucsi->dev, "UCSI_GET_PDOS returned 0 bytes\n");
+ if (con->num_pdos < UCSI_MAX_PDOS)
+ return;
+
+ /* get the remaining PDOs, if any */
+ ret = ucsi_get_pdos(con, 1, con->src_pdos, UCSI_MAX_PDOS,
+ PDO_MAX_OBJECTS - UCSI_MAX_PDOS);
+ if (ret < 0)
+ return;
+
+ con->num_pdos += ret / sizeof(u32);
}
static void ucsi_pwr_opmode_change(struct ucsi_connector *con)
@@ -522,7 +545,7 @@ static void ucsi_pwr_opmode_change(struct ucsi_connector *con)
case UCSI_CONSTAT_PWR_OPMODE_PD:
con->rdo = con->status.request_data_obj;
typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_PD);
- ucsi_get_pdos(con, 1);
+ ucsi_get_src_pdos(con, 1);
break;
case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5:
con->rdo = 0;
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 3920e20a9e9e..cee666790907 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -8,6 +8,7 @@
#include <linux/power_supply.h>
#include <linux/types.h>
#include <linux/usb/typec.h>
+#include <linux/usb/pd.h>
#include <linux/usb/role.h>
/* -------------------------------------------------------------------------- */
@@ -134,7 +135,9 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
/* GET_PDOS command bits */
#define UCSI_GET_PDOS_PARTNER_PDO(_r_) ((u64)(_r_) << 23)
+#define UCSI_GET_PDOS_PDO_OFFSET(_r_) ((u64)(_r_) << 24)
#define UCSI_GET_PDOS_NUM_PDOS(_r_) ((u64)(_r_) << 32)
+#define UCSI_MAX_PDOS (4)
#define UCSI_GET_PDOS_SRC_PDOS ((u64)1 << 34)
/* -------------------------------------------------------------------------- */
@@ -302,7 +305,6 @@ struct ucsi {
#define UCSI_MAX_SVID 5
#define UCSI_MAX_ALTMODES (UCSI_MAX_SVID * 6)
-#define UCSI_MAX_PDOS (4)
#define UCSI_TYPEC_VSAFE5V 5000
#define UCSI_TYPEC_1_5_CURRENT 1500
@@ -330,7 +332,7 @@ struct ucsi_connector {
struct power_supply *psy;
struct power_supply_desc psy_desc;
u32 rdo;
- u32 src_pdos[UCSI_MAX_PDOS];
+ u32 src_pdos[PDO_MAX_OBJECTS];
int num_pdos;
struct usb_role_switch *usb_role_sw;
--
2.24.0
While the DP specification isn't entirely clear on if this should be
allowed or not, some branch devices report having downstream ports present
while also reporting a downstream port count of 0. So to avoid breaking
those devices, we need to handle this in drm_dp_read_downstream_info().
So, to do this we assume there's no downstream port info when the
downstream port count is 0.
Signed-off-by: Lyude Paul <lyude(a)redhat.com>
Tested-by: Jérôme de Bretagne <jerome.debretagne(a)gmail.com>
Bugzilla: https://gitlab.freedesktop.org/drm/intel/-/issues/3416
Fixes: 3d3721ccb18a ("drm/i915/dp: Extract drm_dp_read_downstream_info()")
Cc: <stable(a)vger.kernel.org> # v5.10+
---
drivers/gpu/drm/drm_dp_helper.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index cb56d74e9d38..27c8c5bdf7d9 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -682,7 +682,14 @@ int drm_dp_read_downstream_info(struct drm_dp_aux *aux,
!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
return 0;
+ /* Some branches advertise having 0 downstream ports, despite also advertising they have a
+ * downstream port present. The DP spec isn't clear on if this is allowed or not, but since
+ * some branches do it we need to handle it regardless.
+ */
len = drm_dp_downstream_port_count(dpcd);
+ if (!len)
+ return 0;
+
if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE)
len *= 4;
--
2.30.2
On Sun, Apr 18, 2021 at 8:46 AM <gregkh(a)linuxfoundation.org> wrote:
>
>
> This is a note to let you know that I've just added the patch titled
>
> net: Make tcp_allowed_congestion_control readonly in non-init netns
>
> to the 5.10-stable tree which can be found at:
> http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
>
> The filename of the patch is:
> net-make-tcp_allowed_congestion_control-readonly-in-non-init-netns.patch
> and it can be found in the queue-5.10 subdirectory.
>
> If you, or anyone else, feels it should not be added to the stable tree,
> please let <stable(a)vger.kernel.org> know about it.
>
>
> From 97684f0970f6e112926de631fdd98d9693c7e5c1 Mon Sep 17 00:00:00 2001
> From: Jonathon Reinhart <jonathon.reinhart(a)gmail.com>
> Date: Tue, 13 Apr 2021 03:08:48 -0400
> Subject: net: Make tcp_allowed_congestion_control readonly in non-init netns
>
> From: Jonathon Reinhart <jonathon.reinhart(a)gmail.com>
>
> commit 97684f0970f6e112926de631fdd98d9693c7e5c1 upstream.
Hi Greg,
Thanks for picking this into the stable trees.
There's an earlier, somewhat related fix, which is only on net-next:
2671fa4dc010 ("netfilter: conntrack: Make global sysctls readonly in
non-init netns")
That probably could have been on "net", but it followed this other
commit which was not strictly a bug-fix. It's additional logic to
detect bugs like the former:
31c4d2f160eb ("net: Ensure net namespace isolation of sysctls")
Here's the series on Patchwork:
https://patchwork.kernel.org/project/netdevbpf/cover/20210412042453.32168-1…
I'm not yet sure where the threshold is for inclusion into "net" or
"stable". Could you please take a look and see if the first (or both)
of these should be included into the stable trees? If so, please feel
free to pick them yourself, or let me know which patches I should send
to "stable".
Thanks!
Jonathon Reinhart
Hi Greg, Sasha,
The config malta_qemu_32r6_defconfig for mips fails to build for gcc-10+.
Please apply 1d7ba0165d82 ("mips: Do not include hi and lo in clobber list for R6")
to 4.14-stable to 5.12-stable branches.
It will apply cleanly to 5.9-stable to 5.12-stable. I will send the backport
for 4.14-stable, 4.19-stable and 5.4-stable.
--
Regards
Sudip
This is a backport of the BPF verifier fixes for CVE-2021-29155. Original
series was part of the pull request here: https://lore.kernel.org/bpf/20210416223700.15611-1-daniel@iogearbox.net/T/
This wasn't a complicated backport, but copying bpf@ to see if
there are any concerns.
5.4 verifier selftests are clean with this backport:
Summary: 1566 PASSED, 0 SKIPPED, 0 FAILED
The individual commits:
960114839252 ("bpf: Use correct permission flag for mixed signed bounds arithmetic")
* Not applicable to 5.4, as 5.4 does not have
2c78ee898d8f ("bpf: Implement CAP_BPF").
6f55b2f2a117 ("bpf: Move off_reg into sanitize_ptr_alu")
* Clean cherry-pick.
24c109bb1537 ("bpf: Ensure off_reg has no mixed signed bounds for all types")
* Conflict: allow_ptr_leaks was replaced by bypass_spec_v1 in the
deleted PTR_TO_MAP_VALUE switch case by
2c78ee898d8f ("bpf: Implement CAP_BPF"). Resolution is easy,
the case statement gets deleted either way.
b658bbb844e2 ("bpf: Rework ptr_limit into alu_limit and add common error path")
* Clean cherry-pick.
a6aaece00a57 ("bpf: Improve verifier error messages for users")
* Resolved simple contextual conflict in adjust_scalar_min_max_vals().
because of a var declaration that was added by this post-5.4 commit:
3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking").
073815b756c5 ("bpf: Refactor and streamline bounds check into helper")
* Conflict: another allow_ptr_leaks that was replaced with
bypass_spec_v1 after 2c78ee898d8f.
* Conflict: Post-5.4 commit
01f810ace9ed ("bpf: Allow variable-offset stack access")
changed the call to check_stack_access to a new function,
check_stack_access_for_ptr_arithmetic(), and moved/changed an
error message.
* Since this commit just factors out some code from
adjust_ptr_min_max_vals() in to a new function, do the same
with the corresponding block in 5.4 that doesn't have the
changes listed above from post-5.4 commits.
f528819334 ("bpf: Move sanitize_val_alu out of op switch")
* Contextual conflict from post-5.4 commit
3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking"),
that added a comment on top of the switch referenced in the commit
message.
7fedb63a8307 ("bpf: Tighten speculative pointer arithmetic mask")
* Contextual conflict post-5.4 commit:
3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking")
added a call to a new function just above the switch statement in
adjust_ptr_min_max_vals. This doesn't affect the lines that were
actually changed.
d7a509135175 ("bpf: Update selftests to reflect new error states")
* The bounds.c tests have undergone several changes since 5.4, related
to commits that were not backported (like e.g. the ALU32 changes).
The error messages for those tests will remain the same on 5.4.
=====
Daniel Borkmann (8):
bpf: Move off_reg into sanitize_ptr_alu
bpf: Ensure off_reg has no mixed signed bounds for all types
bpf: Rework ptr_limit into alu_limit and add common error path
bpf: Improve verifier error messages for users
bpf: Refactor and streamline bounds check into helper
bpf: Move sanitize_val_alu out of op switch
bpf: Tighten speculative pointer arithmetic mask
bpf: Update selftests to reflect new error states
kernel/bpf/verifier.c | 233 ++++++++++++------
.../selftests/bpf/verifier/bounds_deduction.c | 21 +-
.../bpf/verifier/bounds_mix_sign_unsign.c | 13 -
tools/testing/selftests/bpf/verifier/unpriv.c | 2 +-
.../selftests/bpf/verifier/value_ptr_arith.c | 6 +-
5 files changed, 173 insertions(+), 102 deletions(-)
--
2.23.3