-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtaint.c
124 lines (103 loc) · 2.36 KB
/
taint.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// SPDX-License-Identifier: GPL-2.0-only
/*
* Various blithe uses of attacker-controlled values.
*
* (C) 2021 David Malcolm, Red Hat
* Written by David Malcolm <[email protected]>
*/
#include <linux/uaccess.h>
#include "antipatterns.h"
struct cmd_1
{
u32 idx;
u32 val;
};
static u32 arr[16];
int taint_array_access(void __user *src)
{
struct cmd_1 cmd;
if (copy_from_user(&cmd, src, sizeof(cmd)))
return -EFAULT;
/*
* cmd.idx is an unsanitized value from user-space, hence
* this is an arbitrary kernel memory access.
*/
arr[cmd.idx] = cmd.val;
return 0;
}
struct cmd_2
{
s32 idx;
u32 val;
};
int taint_signed_array_access(void __user *src)
{
struct cmd_2 cmd;
if (copy_from_user(&cmd, src, sizeof(cmd)))
return -EFAULT;
if (cmd.idx >= 16)
return -EFAULT;
/*
* cmd.idx hasn't been checked for being negative, hence
* this is an arbitrary kernel memory access.
*/
arr[cmd.idx] = cmd.val;
return 0;
}
struct cmd_s32_binop
{
s32 a;
s32 b;
s32 result;
};
int taint_divide_by_zero_direct(void __user *uptr)
{
struct cmd_s32_binop cmd;
if (copy_from_user(&cmd, uptr, sizeof(cmd)))
return -EFAULT;
/* cmd.b is attacker-controlled and could be zero */
cmd.result = cmd.a / cmd.b;
if (copy_to_user (uptr, &cmd, sizeof(cmd)))
return -EFAULT;
return 0;
}
int taint_divide_by_zero_compound(void __user *uptr)
{
struct cmd_s32_binop cmd;
if (copy_from_user(&cmd, uptr, sizeof(cmd)))
return -EFAULT;
/*
* cmd.b is attacker-controlled and could be -1, hence
* the divisor could be zero
*/
cmd.result = cmd.a / (cmd.b + 1);
if (copy_to_user (uptr, &cmd, sizeof(cmd)))
return -EFAULT;
return 0;
}
int taint_mod_by_zero_direct(void __user *uptr)
{
struct cmd_s32_binop cmd;
if (copy_from_user(&cmd, uptr, sizeof(cmd)))
return -EFAULT;
/* cmd.b is attacker-controlled and could be zero */
cmd.result = cmd.a % cmd.b;
if (copy_to_user (uptr, &cmd, sizeof(cmd)))
return -EFAULT;
return 0;
}
int taint_mod_by_zero_compound(void __user *uptr)
{
struct cmd_s32_binop cmd;
if (copy_from_user(&cmd, uptr, sizeof(cmd)))
return -EFAULT;
/*
* cmd.b is attacker-controlled and could be -1, hence
* the divisor could be zero
*/
cmd.result = cmd.a % (cmd.b + 1);
if (copy_to_user (uptr, &cmd, sizeof(cmd)))
return -EFAULT;
return 0;
}
/* TODO: etc. */