Skip to content

Commit 89f42df

Browse files
iii-iakpm00
authored andcommitted
lib/zlib: unpoison DFLTCC output buffers
The constraints of the DFLTCC inline assembly are not precise: they do not communicate the size of the output buffers to the compiler, so it cannot automatically instrument it. Add the manual kmsan_unpoison_memory() calls for the output buffers. The logic is the same as in [1]. [1] zlib-ng/zlib-ng@1f5ddcc Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ilya Leoshkevich <[email protected]> Reported-by: Alexander Gordeev <[email protected]> Reviewed-by: Alexander Potapenko <[email protected]> Cc: Christian Borntraeger <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: David Rientjes <[email protected]> Cc: Dmitry Vyukov <[email protected]> Cc: Heiko Carstens <[email protected]> Cc: Hyeonggon Yoo <[email protected]> Cc: Joonsoo Kim <[email protected]> Cc: <[email protected]> Cc: Marco Elver <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Masami Hiramatsu (Google) <[email protected]> Cc: Pekka Enberg <[email protected]> Cc: Roman Gushchin <[email protected]> Cc: Steven Rostedt (Google) <[email protected]> Cc: Sven Schnelle <[email protected]> Cc: Vasily Gorbik <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 4d7b5a2 commit 89f42df

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

lib/zlib_dfltcc/dfltcc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct dfltcc_param_v0 {
8080
uint8_t csb[1152];
8181
};
8282

83+
static_assert(offsetof(struct dfltcc_param_v0, csb) == 384);
8384
static_assert(sizeof(struct dfltcc_param_v0) == 1536);
8485

8586
#define CVT_CRC32 0

lib/zlib_dfltcc/dfltcc_util.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#ifndef DFLTCC_UTIL_H
33
#define DFLTCC_UTIL_H
44

5+
#include "dfltcc.h"
6+
#include <linux/kmsan-checks.h>
57
#include <linux/zutil.h>
68

79
/*
@@ -20,6 +22,7 @@ typedef enum {
2022
#define DFLTCC_CMPR 2
2123
#define DFLTCC_XPND 4
2224
#define HBT_CIRCULAR (1 << 7)
25+
#define DFLTCC_FN_MASK ((1 << 7) - 1)
2326
#define HB_BITS 15
2427
#define HB_SIZE (1 << HB_BITS)
2528

@@ -34,6 +37,7 @@ static inline dfltcc_cc dfltcc(
3437
)
3538
{
3639
Byte *t2 = op1 ? *op1 : NULL;
40+
unsigned char *orig_t2 = t2;
3741
size_t t3 = len1 ? *len1 : 0;
3842
const Byte *t4 = op2 ? *op2 : NULL;
3943
size_t t5 = len2 ? *len2 : 0;
@@ -59,6 +63,30 @@ static inline dfltcc_cc dfltcc(
5963
: "cc", "memory");
6064
t2 = r2; t3 = r3; t4 = r4; t5 = r5;
6165

66+
/*
67+
* Unpoison the parameter block and the output buffer.
68+
* This is a no-op in non-KMSAN builds.
69+
*/
70+
switch (fn & DFLTCC_FN_MASK) {
71+
case DFLTCC_QAF:
72+
kmsan_unpoison_memory(param, sizeof(struct dfltcc_qaf_param));
73+
break;
74+
case DFLTCC_GDHT:
75+
kmsan_unpoison_memory(param, offsetof(struct dfltcc_param_v0, csb));
76+
break;
77+
case DFLTCC_CMPR:
78+
kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
79+
kmsan_unpoison_memory(
80+
orig_t2,
81+
t2 - orig_t2 +
82+
(((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1));
83+
break;
84+
case DFLTCC_XPND:
85+
kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
86+
kmsan_unpoison_memory(orig_t2, t2 - orig_t2);
87+
break;
88+
}
89+
6290
if (op1)
6391
*op1 = t2;
6492
if (len1)

0 commit comments

Comments
 (0)