Skip to content

Commit 6a26a9d

Browse files
yhcotepmladek
authored andcommitted
selftests/livepatch: rework test-klp-shadow-vars
The initial idea was to make a change to please cppcheck and remove void pointer arithmetics found a few times: portability: 'obj' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined. [arithOperationsOnVoidPointer] The rest of the changes are to help make the test read as an example while continuing to verify the shadow variable code. The logic of the test is unchanged but restructured to use descriptive names. Signed-off-by: Yannick Cote <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Reviewed-by: Kamalesh Babulal <[email protected]> Acked-by: Miroslav Benes <[email protected]> Acked-by: Joe Lawrence <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 547840b commit 6a26a9d

File tree

1 file changed

+57
-44
lines changed

1 file changed

+57
-44
lines changed

lib/livepatch/test_klp_shadow_vars.c

Lines changed: 57 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ static void shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
109109
static void shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
110110
{
111111
klp_shadow_free_all(id, dtor);
112-
pr_info("klp_%s(id=0x%lx, dtor=PTR%d)\n",
113-
__func__, id, ptr_id(dtor));
112+
pr_info("klp_%s(id=0x%lx, dtor=PTR%d)\n", __func__, id, ptr_id(dtor));
114113
}
115114

116115

@@ -124,8 +123,7 @@ static int shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
124123
return -EINVAL;
125124

126125
*sv = *var;
127-
pr_info("%s: PTR%d -> PTR%d\n",
128-
__func__, ptr_id(sv), ptr_id(*var));
126+
pr_info("%s: PTR%d -> PTR%d\n", __func__, ptr_id(sv), ptr_id(*var));
129127

130128
return 0;
131129
}
@@ -138,125 +136,140 @@ static void shadow_dtor(void *obj, void *shadow_data)
138136
__func__, ptr_id(obj), ptr_id(sv));
139137
}
140138

141-
static int test_klp_shadow_vars_init(void)
142-
{
143-
void *obj = THIS_MODULE;
144-
int id = 0x1234;
145-
gfp_t gfp_flags = GFP_KERNEL;
139+
/* dynamically created obj fields have the following shadow var id values */
140+
#define SV_ID1 0x1234
141+
#define SV_ID2 0x1235
146142

147-
int var1, var2, var3, var4;
148-
int *pv1, *pv2, *pv3, *pv4;
149-
int **sv1, **sv2, **sv3, **sv4;
143+
/*
144+
* The main test case adds/removes new fields (shadow var) to each of these
145+
* test structure instances. The last group of fields in the struct represent
146+
* the idea that shadow variables may be added and removed to and from the
147+
* struct during execution.
148+
*/
149+
struct test_object {
150+
/* add anything here below and avoid to define an empty struct */
151+
struct shadow_ptr sp;
150152

151-
int **sv;
153+
/* these represent shadow vars added and removed with SV_ID{1,2} */
154+
/* char nfield1; */
155+
/* int nfield2; */
156+
};
152157

153-
pv1 = &var1;
154-
pv2 = &var2;
155-
pv3 = &var3;
156-
pv4 = &var4;
158+
static int test_klp_shadow_vars_init(void)
159+
{
160+
struct test_object obj1, obj2, obj3;
161+
char nfield1, nfield2, *pnfield1, *pnfield2, **sv1, **sv2;
162+
int nfield3, nfield4, *pnfield3, *pnfield4, **sv3, **sv4;
163+
void **sv;
164+
165+
pnfield1 = &nfield1;
166+
pnfield2 = &nfield2;
167+
pnfield3 = &nfield3;
168+
pnfield4 = &nfield4;
157169

158170
ptr_id(NULL);
159-
ptr_id(pv1);
160-
ptr_id(pv2);
161-
ptr_id(pv3);
162-
ptr_id(pv4);
171+
ptr_id(pnfield1);
172+
ptr_id(pnfield2);
173+
ptr_id(pnfield3);
174+
ptr_id(pnfield4);
163175

164176
/*
165177
* With an empty shadow variable hash table, expect not to find
166178
* any matches.
167179
*/
168-
sv = shadow_get(obj, id);
180+
sv = shadow_get(&obj1, SV_ID1);
169181
if (!sv)
170182
pr_info(" got expected NULL result\n");
171183

172184
/*
173185
* Allocate a few shadow variables with different <obj> and <id>.
174186
*/
175-
sv1 = shadow_alloc(obj, id, sizeof(pv1), gfp_flags, shadow_ctor, &pv1);
187+
sv1 = shadow_alloc(&obj1, SV_ID1, sizeof(pnfield1), GFP_KERNEL, shadow_ctor, &pnfield1);
176188
if (!sv1)
177189
return -ENOMEM;
178190

179-
sv2 = shadow_alloc(obj + 1, id, sizeof(pv2), gfp_flags, shadow_ctor, &pv2);
191+
sv2 = shadow_alloc(&obj2, SV_ID1, sizeof(pnfield2), GFP_KERNEL, shadow_ctor, &pnfield2);
180192
if (!sv2)
181193
return -ENOMEM;
182194

183-
sv3 = shadow_alloc(obj, id + 1, sizeof(pv3), gfp_flags, shadow_ctor, &pv3);
195+
sv3 = shadow_alloc(&obj1, SV_ID2, sizeof(pnfield3), GFP_KERNEL, shadow_ctor, &pnfield3);
184196
if (!sv3)
185197
return -ENOMEM;
186198

187199
/*
188200
* Verify we can find our new shadow variables and that they point
189201
* to expected data.
190202
*/
191-
sv = shadow_get(obj, id);
203+
sv = shadow_get(&obj1, SV_ID1);
192204
if (!sv)
193205
return -EINVAL;
194-
if (sv == sv1 && *sv1 == pv1)
206+
if ((char **)sv == sv1 && *sv1 == pnfield1)
195207
pr_info(" got expected PTR%d -> PTR%d result\n",
196208
ptr_id(sv1), ptr_id(*sv1));
197209

198-
sv = shadow_get(obj + 1, id);
210+
sv = shadow_get(&obj2, SV_ID1);
199211
if (!sv)
200212
return -EINVAL;
201-
if (sv == sv2 && *sv2 == pv2)
213+
if ((char **)sv == sv2 && *sv2 == pnfield2)
202214
pr_info(" got expected PTR%d -> PTR%d result\n",
203215
ptr_id(sv2), ptr_id(*sv2));
204-
sv = shadow_get(obj, id + 1);
216+
217+
sv = shadow_get(&obj1, SV_ID2);
205218
if (!sv)
206219
return -EINVAL;
207-
if (sv == sv3 && *sv3 == pv3)
220+
if ((int **)sv == sv3 && *sv3 == pnfield3)
208221
pr_info(" got expected PTR%d -> PTR%d result\n",
209222
ptr_id(sv3), ptr_id(*sv3));
210223

211224
/*
212225
* Allocate or get a few more, this time with the same <obj>, <id>.
213226
* The second invocation should return the same shadow var.
214227
*/
215-
sv4 = shadow_get_or_alloc(obj + 2, id, sizeof(pv4), gfp_flags, shadow_ctor, &pv4);
228+
sv4 = shadow_get_or_alloc(&obj3, SV_ID1, sizeof(pnfield4), GFP_KERNEL, shadow_ctor, &pnfield4);
216229
if (!sv4)
217230
return -ENOMEM;
218231

219-
sv = shadow_get_or_alloc(obj + 2, id, sizeof(pv4), gfp_flags, shadow_ctor, &pv4);
232+
sv = shadow_get_or_alloc(&obj3, SV_ID1, sizeof(pnfield4), GFP_KERNEL, shadow_ctor, &pnfield4);
220233
if (!sv)
221234
return -EINVAL;
222-
if (sv == sv4 && *sv4 == pv4)
235+
if ((int **)sv == sv4 && *sv4 == pnfield4)
223236
pr_info(" got expected PTR%d -> PTR%d result\n",
224237
ptr_id(sv4), ptr_id(*sv4));
225238

226239
/*
227240
* Free the <obj=*, id> shadow variables and check that we can no
228241
* longer find them.
229242
*/
230-
shadow_free(obj, id, shadow_dtor); /* sv1 */
231-
sv = shadow_get(obj, id);
243+
shadow_free(&obj1, SV_ID1, shadow_dtor); /* sv1 */
244+
sv = shadow_get(&obj1, SV_ID1);
232245
if (!sv)
233246
pr_info(" got expected NULL result\n");
234247

235-
shadow_free(obj + 1, id, shadow_dtor); /* sv2 */
236-
sv = shadow_get(obj + 1, id);
248+
shadow_free(&obj2, SV_ID1, shadow_dtor); /* sv2 */
249+
sv = shadow_get(&obj2, SV_ID1);
237250
if (!sv)
238251
pr_info(" got expected NULL result\n");
239252

240-
shadow_free(obj + 2, id, shadow_dtor); /* sv4 */
241-
sv = shadow_get(obj + 2, id);
253+
shadow_free(&obj3, SV_ID1, shadow_dtor); /* sv4 */
254+
sv = shadow_get(&obj3, SV_ID1);
242255
if (!sv)
243256
pr_info(" got expected NULL result\n");
244257

245258
/*
246259
* We should still find an <id+1> variable.
247260
*/
248-
sv = shadow_get(obj, id + 1);
261+
sv = shadow_get(&obj1, SV_ID2);
249262
if (!sv)
250263
return -EINVAL;
251-
if (sv == sv3 && *sv3 == pv3)
264+
if ((int **)sv == sv3 && *sv3 == pnfield3)
252265
pr_info(" got expected PTR%d -> PTR%d result\n",
253266
ptr_id(sv3), ptr_id(*sv3));
254267

255268
/*
256269
* Free all the <id+1> variables, too.
257270
*/
258-
shadow_free_all(id + 1, shadow_dtor); /* sv3 */
259-
sv = shadow_get(obj, id);
271+
shadow_free_all(SV_ID2, shadow_dtor); /* sv3 */
272+
sv = shadow_get(&obj1, SV_ID1);
260273
if (!sv)
261274
pr_info(" shadow_get() got expected NULL result\n");
262275

0 commit comments

Comments
 (0)