提交 62589419 编写于 作者: A Anson Jacob 提交者: Zheng Zengkai

drm/amd/display: Fix UBSAN: shift-out-of-bounds warning

stable inclusion
from stable-5.10.36
commit 081cec78467f7d3166432f3529d279dc6db233c2
bugzilla: 51867
CVE: NA

--------------------------------

[ Upstream commit 54718747 ]

[Why]
On NAVI14 CONFIG_UBSAN reported shift-out-of-bounds at
display_rq_dlg_calc_20v2.c:304:38

rq_param->misc.rq_c.blk256_height is 0 when chroma(*_c) is invalid.
dml_log2 returns -1023 for log2(0), although log2(0) is undefined.

Which ended up as:
rq_param->dlg.rq_c.swath_height = 1 << -1023

[How]
Fix applied on all dml versions.
1. Ensure dml_log2 is only called if the argument is greater than 0.
2. Subtract req128_l/req128_c from log2_swath_height_l/log2_swath_height_c
   only when it is greater than 0.
Tested-by: NDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: NAnson Jacob <Anson.Jacob@amd.com>
Reviewed-by: NDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: NJun Lei <Jun.Lei@amd.com>
Acked-by: NSolomon Chiu <solomon.chiu@amd.com>
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 f16ca9ed
...@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, ...@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
if (surf_linear) { if (surf_linear) {
log2_swath_height_l = 0; log2_swath_height_l = 0;
log2_swath_height_c = 0; log2_swath_height_c = 0;
} else if (!surf_vert) {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
} else { } else {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; unsigned int swath_height_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; unsigned int swath_height_c;
if (!surf_vert) {
swath_height_l = rq_param->misc.rq_l.blk256_height;
swath_height_c = rq_param->misc.rq_c.blk256_height;
} else {
swath_height_l = rq_param->misc.rq_l.blk256_width;
swath_height_c = rq_param->misc.rq_c.blk256_width;
}
if (swath_height_l > 0)
log2_swath_height_l = dml_log2(swath_height_l);
if (req128_l && log2_swath_height_l > 0)
log2_swath_height_l -= 1;
if (swath_height_c > 0)
log2_swath_height_c = dml_log2(swath_height_c);
if (req128_c && log2_swath_height_c > 0)
log2_swath_height_c -= 1;
} }
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
......
...@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, ...@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
if (surf_linear) { if (surf_linear) {
log2_swath_height_l = 0; log2_swath_height_l = 0;
log2_swath_height_c = 0; log2_swath_height_c = 0;
} else if (!surf_vert) {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
} else { } else {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; unsigned int swath_height_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; unsigned int swath_height_c;
if (!surf_vert) {
swath_height_l = rq_param->misc.rq_l.blk256_height;
swath_height_c = rq_param->misc.rq_c.blk256_height;
} else {
swath_height_l = rq_param->misc.rq_l.blk256_width;
swath_height_c = rq_param->misc.rq_c.blk256_width;
}
if (swath_height_l > 0)
log2_swath_height_l = dml_log2(swath_height_l);
if (req128_l && log2_swath_height_l > 0)
log2_swath_height_l -= 1;
if (swath_height_c > 0)
log2_swath_height_c = dml_log2(swath_height_c);
if (req128_c && log2_swath_height_c > 0)
log2_swath_height_c -= 1;
} }
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
......
...@@ -277,13 +277,31 @@ static void handle_det_buf_split( ...@@ -277,13 +277,31 @@ static void handle_det_buf_split(
if (surf_linear) { if (surf_linear) {
log2_swath_height_l = 0; log2_swath_height_l = 0;
log2_swath_height_c = 0; log2_swath_height_c = 0;
} else if (!surf_vert) {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
} else { } else {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; unsigned int swath_height_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; unsigned int swath_height_c;
if (!surf_vert) {
swath_height_l = rq_param->misc.rq_l.blk256_height;
swath_height_c = rq_param->misc.rq_c.blk256_height;
} else {
swath_height_l = rq_param->misc.rq_l.blk256_width;
swath_height_c = rq_param->misc.rq_c.blk256_width;
}
if (swath_height_l > 0)
log2_swath_height_l = dml_log2(swath_height_l);
if (req128_l && log2_swath_height_l > 0)
log2_swath_height_l -= 1;
if (swath_height_c > 0)
log2_swath_height_c = dml_log2(swath_height_c);
if (req128_c && log2_swath_height_c > 0)
log2_swath_height_c -= 1;
} }
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
......
...@@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, ...@@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
if (surf_linear) { if (surf_linear) {
log2_swath_height_l = 0; log2_swath_height_l = 0;
log2_swath_height_c = 0; log2_swath_height_c = 0;
} else if (!surf_vert) {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
} else { } else {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; unsigned int swath_height_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; unsigned int swath_height_c;
if (!surf_vert) {
swath_height_l = rq_param->misc.rq_l.blk256_height;
swath_height_c = rq_param->misc.rq_c.blk256_height;
} else {
swath_height_l = rq_param->misc.rq_l.blk256_width;
swath_height_c = rq_param->misc.rq_c.blk256_width;
}
if (swath_height_l > 0)
log2_swath_height_l = dml_log2(swath_height_l);
if (req128_l && log2_swath_height_l > 0)
log2_swath_height_l -= 1;
if (swath_height_c > 0)
log2_swath_height_c = dml_log2(swath_height_c);
if (req128_c && log2_swath_height_c > 0)
log2_swath_height_c -= 1;
} }
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
......
...@@ -344,13 +344,31 @@ static void handle_det_buf_split( ...@@ -344,13 +344,31 @@ static void handle_det_buf_split(
if (surf_linear) { if (surf_linear) {
log2_swath_height_l = 0; log2_swath_height_l = 0;
log2_swath_height_c = 0; log2_swath_height_c = 0;
} else if (!surf_vert) {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
} else { } else {
log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; unsigned int swath_height_l;
log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; unsigned int swath_height_c;
if (!surf_vert) {
swath_height_l = rq_param->misc.rq_l.blk256_height;
swath_height_c = rq_param->misc.rq_c.blk256_height;
} else {
swath_height_l = rq_param->misc.rq_l.blk256_width;
swath_height_c = rq_param->misc.rq_c.blk256_width;
}
if (swath_height_l > 0)
log2_swath_height_l = dml_log2(swath_height_l);
if (req128_l && log2_swath_height_l > 0)
log2_swath_height_l -= 1;
if (swath_height_c > 0)
log2_swath_height_c = dml_log2(swath_height_c);
if (req128_c && log2_swath_height_c > 0)
log2_swath_height_c -= 1;
} }
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册