1
The following changes since commit 812b835fb4d23dd108b2f9802158472d50b73579:
1
The following changes since commit 15ef89d2a1a7b93845a6b09c2ee8e1979f6eb30b:
2
2
3
Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2019-05-07' into staging (2019-05-09 16:31:12 +0100)
3
Update version for v7.0.0-rc1 release (2022-03-22 22:58:44 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/stefanha/qemu.git tags/block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to e84125761f78919fe63616d9888ea45e72dc956f:
9
for you to fetch changes up to 2539eade4f689eda7e9fe45486f18334bfbafaf0:
10
10
11
docs: add Security chapter to the documentation (2019-05-10 10:53:52 +0100)
11
hw: Fix misleading hexadecimal format (2022-03-24 10:38:42 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
Philippe found cases where the 0x%d format string was used, leading to
17
misleading output. The patches look harmless and could save people time, so I
18
think it's worth including them in 7.0.
19
16
----------------------------------------------------------------
20
----------------------------------------------------------------
17
21
18
Andrey Shinkevich (1):
22
Philippe Mathieu-Daudé (2):
19
block/io.c: fix for the allocation failure
23
block: Fix misleading hexadecimal format
24
hw: Fix misleading hexadecimal format
20
25
21
Jules Irenge (3):
26
block/parallels-ext.c | 2 +-
22
util/readline: add a space to fix errors by checkpatch tool
27
hw/i386/sgx.c | 2 +-
23
util: readline: replace tab indent by four spaces to fix checkpatch
28
hw/i386/trace-events | 6 +++---
24
errors
29
hw/misc/trace-events | 4 ++--
25
util/readline: Add braces to fix checkpatch errors
30
hw/scsi/trace-events | 4 ++--
26
31
5 files changed, 9 insertions(+), 9 deletions(-)
27
Nikita Alekseev (1):
28
block: Add coroutine_fn to bdrv_check_co_entry
29
30
Paolo Bonzini (1):
31
aio-posix: ensure poll mode is left when aio_notify is called
32
33
Stefan Hajnoczi (2):
34
docs: add Secure Coding Practices to developer docs
35
docs: add Security chapter to the documentation
36
37
Makefile | 2 +-
38
block.c | 2 +-
39
block/io.c | 2 +-
40
util/aio-posix.c | 12 +-
41
util/readline.c | 174 ++++++++++++++-----------
42
docs/devel/index.rst | 1 +
43
docs/devel/secure-coding-practices.rst | 106 +++++++++++++++
44
docs/security.texi | 131 +++++++++++++++++++
45
qemu-doc.texi | 3 +
46
9 files changed, 347 insertions(+), 86 deletions(-)
47
create mode 100644 docs/devel/secure-coding-practices.rst
48
create mode 100644 docs/security.texi
49
32
50
--
33
--
51
2.21.0
34
2.35.1
52
35
53
diff view generated by jsdifflib
Deleted patch
1
From: Jules Irenge <jbi.octave@gmail.com>
2
1
3
util/readline: add a space to fix errors reported by checkpatch.pl tool
4
"ERROR: space required before the open parenthesis"
5
"ERROR: space required after that ..."
6
within "util/redline.c" file
7
8
Signed-off-by: Jules Irenge <jbi.octave@gmail.com>
9
Reviewed-by: Thomas Huth <thuth@redhat.com>
10
Message-id: 20190401024406.10819-2-jbi.octave@gmail.com
11
Message-Id: <20190401024406.10819-2-jbi.octave@gmail.com>
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
util/readline.c | 34 +++++++++++++++++-----------------
15
1 file changed, 17 insertions(+), 17 deletions(-)
16
17
diff --git a/util/readline.c b/util/readline.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/util/readline.c
20
+++ b/util/readline.c
21
@@ -XXX,XX +XXX,XX @@ static void readline_update(ReadLineState *rs)
22
23
if (rs->cmd_buf_size != rs->last_cmd_buf_size ||
24
memcmp(rs->cmd_buf, rs->last_cmd_buf, rs->cmd_buf_size) != 0) {
25
- for(i = 0; i < rs->last_cmd_buf_index; i++) {
26
+ for (i = 0; i < rs->last_cmd_buf_index; i++) {
27
rs->printf_func(rs->opaque, "\033[D");
28
}
29
rs->cmd_buf[rs->cmd_buf_size] = '\0';
30
if (rs->read_password) {
31
len = strlen(rs->cmd_buf);
32
- for(i = 0; i < len; i++)
33
+ for (i = 0; i < len; i++)
34
rs->printf_func(rs->opaque, "*");
35
} else {
36
rs->printf_func(rs->opaque, "%s", rs->cmd_buf);
37
@@ -XXX,XX +XXX,XX @@ static void readline_update(ReadLineState *rs)
38
if (rs->cmd_buf_index != rs->last_cmd_buf_index) {
39
delta = rs->cmd_buf_index - rs->last_cmd_buf_index;
40
if (delta > 0) {
41
- for(i = 0;i < delta; i++) {
42
+ for (i = 0; i < delta; i++) {
43
rs->printf_func(rs->opaque, "\033[C");
44
}
45
} else {
46
delta = -delta;
47
- for(i = 0;i < delta; i++) {
48
+ for (i = 0; i < delta; i++) {
49
rs->printf_func(rs->opaque, "\033[D");
50
}
51
}
52
@@ -XXX,XX +XXX,XX @@ static void readline_completion(ReadLineState *rs)
53
return;
54
if (rs->nb_completions == 1) {
55
len = strlen(rs->completions[0]);
56
- for(i = rs->completion_index; i < len; i++) {
57
+ for (i = rs->completion_index; i < len; i++) {
58
readline_insert_char(rs, rs->completions[0][i]);
59
}
60
/* extra space for next argument. XXX: make it more generic */
61
@@ -XXX,XX +XXX,XX @@ static void readline_completion(ReadLineState *rs)
62
completion_comp);
63
rs->printf_func(rs->opaque, "\n");
64
max_width = 0;
65
- max_prefix = 0;    
66
- for(i = 0; i < rs->nb_completions; i++) {
67
+ max_prefix = 0;
68
+ for (i = 0; i < rs->nb_completions; i++) {
69
len = strlen(rs->completions[i]);
70
- if (i==0) {
71
+ if (i == 0) {
72
max_prefix = len;
73
} else {
74
if (len < max_prefix)
75
max_prefix = len;
76
- for(j=0; j<max_prefix; j++) {
77
+ for (j = 0; j < max_prefix; j++) {
78
if (rs->completions[i][j] != rs->completions[0][j])
79
max_prefix = j;
80
}
81
@@ -XXX,XX +XXX,XX @@ static void readline_completion(ReadLineState *rs)
82
if (len > max_width)
83
max_width = len;
84
}
85
- if (max_prefix > 0)
86
- for(i = rs->completion_index; i < max_prefix; i++) {
87
+ if (max_prefix > 0)
88
+ for (i = rs->completion_index; i < max_prefix; i++) {
89
readline_insert_char(rs, rs->completions[0][i]);
90
}
91
max_width += 2;
92
@@ -XXX,XX +XXX,XX @@ static void readline_completion(ReadLineState *rs)
93
max_width = 80;
94
nb_cols = 80 / max_width;
95
j = 0;
96
- for(i = 0; i < rs->nb_completions; i++) {
97
+ for (i = 0; i < rs->nb_completions; i++) {
98
rs->printf_func(rs->opaque, "%-*s", max_width, rs->completions[i]);
99
if (++j == nb_cols || i == (rs->nb_completions - 1)) {
100
rs->printf_func(rs->opaque, "\n");
101
@@ -XXX,XX +XXX,XX @@ static void readline_clear_screen(ReadLineState *rs)
102
/* return true if command handled */
103
void readline_handle_byte(ReadLineState *rs, int ch)
104
{
105
- switch(rs->esc_state) {
106
+ switch (rs->esc_state) {
107
case IS_NORM:
108
- switch(ch) {
109
+ switch (ch) {
110
case 1:
111
readline_bol(rs);
112
break;
113
@@ -XXX,XX +XXX,XX @@ void readline_handle_byte(ReadLineState *rs, int ch)
114
}
115
break;
116
case IS_CSI:
117
- switch(ch) {
118
+ switch (ch) {
119
    case 'A':
120
    case 'F':
121
     readline_up_char(rs);
122
@@ -XXX,XX +XXX,XX @@ void readline_handle_byte(ReadLineState *rs, int ch)
123
rs->esc_param = rs->esc_param * 10 + (ch - '0');
124
goto the_end;
125
case '~':
126
- switch(rs->esc_param) {
127
+ switch (rs->esc_param) {
128
case 1:
129
readline_bol(rs);
130
break;
131
@@ -XXX,XX +XXX,XX @@ void readline_handle_byte(ReadLineState *rs, int ch)
132
the_end:
133
break;
134
case IS_SS3:
135
- switch(ch) {
136
+ switch (ch) {
137
case 'F':
138
readline_eol(rs);
139
break;
140
--
141
2.21.0
142
143
diff view generated by jsdifflib
Deleted patch
1
From: Jules Irenge <jbi.octave@gmail.com>
2
1
3
Replace tab indent by four spaces to fix errors issued by checkpatch.pl tool
4
"ERROR: code indent should never use tabs" within "util/readline.c" file.
5
6
Signed-off-by: Jules Irenge <jbi.octave@gmail.com>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Message-id: 20190401024406.10819-3-jbi.octave@gmail.com
9
Message-Id: <20190401024406.10819-3-jbi.octave@gmail.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
util/readline.c | 98 ++++++++++++++++++++++++-------------------------
13
1 file changed, 49 insertions(+), 49 deletions(-)
14
15
diff --git a/util/readline.c b/util/readline.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/util/readline.c
18
+++ b/util/readline.c
19
@@ -XXX,XX +XXX,XX @@ static void readline_up_char(ReadLineState *rs)
20
int idx;
21
22
if (rs->hist_entry == 0)
23
-    return;
24
+ return;
25
if (rs->hist_entry == -1) {
26
-    /* Find latest entry */
27
-    for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
28
-     if (rs->history[idx] == NULL)
29
-        break;
30
-    }
31
-    rs->hist_entry = idx;
32
+ /* Find latest entry */
33
+ for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
34
+ if (rs->history[idx] == NULL)
35
+ break;
36
+ }
37
+ rs->hist_entry = idx;
38
}
39
rs->hist_entry--;
40
if (rs->hist_entry >= 0) {
41
-    pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
42
+ pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
43
rs->history[rs->hist_entry]);
44
-    rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf);
45
+ rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf);
46
}
47
}
48
49
@@ -XXX,XX +XXX,XX @@ static void readline_down_char(ReadLineState *rs)
50
return;
51
if (rs->hist_entry < READLINE_MAX_CMDS - 1 &&
52
rs->history[++rs->hist_entry] != NULL) {
53
-    pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
54
+ pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
55
rs->history[rs->hist_entry]);
56
} else {
57
rs->cmd_buf[0] = 0;
58
-    rs->hist_entry = -1;
59
+ rs->hist_entry = -1;
60
}
61
rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf);
62
}
63
@@ -XXX,XX +XXX,XX @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline)
64
int idx;
65
66
if (cmdline[0] == '\0')
67
-    return;
68
+ return;
69
new_entry = NULL;
70
if (rs->hist_entry != -1) {
71
-    /* We were editing an existing history entry: replace it */
72
-    hist_entry = rs->history[rs->hist_entry];
73
-    idx = rs->hist_entry;
74
-    if (strcmp(hist_entry, cmdline) == 0) {
75
-     goto same_entry;
76
-    }
77
+ /* We were editing an existing history entry: replace it */
78
+ hist_entry = rs->history[rs->hist_entry];
79
+ idx = rs->hist_entry;
80
+ if (strcmp(hist_entry, cmdline) == 0) {
81
+ goto same_entry;
82
+ }
83
}
84
/* Search cmdline in history buffers */
85
for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
86
-    hist_entry = rs->history[idx];
87
-    if (hist_entry == NULL)
88
-     break;
89
-    if (strcmp(hist_entry, cmdline) == 0) {
90
-    same_entry:
91
-     new_entry = hist_entry;
92
-     /* Put this entry at the end of history */
93
-     memmove(&rs->history[idx], &rs->history[idx + 1],
94
-         (READLINE_MAX_CMDS - (idx + 1)) * sizeof(char *));
95
-     rs->history[READLINE_MAX_CMDS - 1] = NULL;
96
-     for (; idx < READLINE_MAX_CMDS; idx++) {
97
-        if (rs->history[idx] == NULL)
98
-         break;
99
-     }
100
-     break;
101
-    }
102
+ hist_entry = rs->history[idx];
103
+ if (hist_entry == NULL)
104
+ break;
105
+ if (strcmp(hist_entry, cmdline) == 0) {
106
+ same_entry:
107
+ new_entry = hist_entry;
108
+ /* Put this entry at the end of history */
109
+ memmove(&rs->history[idx], &rs->history[idx + 1],
110
+ (READLINE_MAX_CMDS - (idx + 1)) * sizeof(char *));
111
+ rs->history[READLINE_MAX_CMDS - 1] = NULL;
112
+ for (; idx < READLINE_MAX_CMDS; idx++) {
113
+ if (rs->history[idx] == NULL)
114
+ break;
115
+ }
116
+ break;
117
+ }
118
}
119
if (idx == READLINE_MAX_CMDS) {
120
-    /* Need to get one free slot */
121
+ /* Need to get one free slot */
122
g_free(rs->history[0]);
123
-    memmove(rs->history, &rs->history[1],
124
-     (READLINE_MAX_CMDS - 1) * sizeof(char *));
125
-    rs->history[READLINE_MAX_CMDS - 1] = NULL;
126
-    idx = READLINE_MAX_CMDS - 1;
127
+ memmove(rs->history, &rs->history[1],
128
+ (READLINE_MAX_CMDS - 1) * sizeof(char *));
129
+ rs->history[READLINE_MAX_CMDS - 1] = NULL;
130
+ idx = READLINE_MAX_CMDS - 1;
131
}
132
if (new_entry == NULL)
133
new_entry = g_strdup(cmdline);
134
@@ -XXX,XX +XXX,XX @@ void readline_handle_byte(ReadLineState *rs, int ch)
135
case 8:
136
readline_backspace(rs);
137
break;
138
-    case 155:
139
+ case 155:
140
rs->esc_state = IS_CSI;
141
-     break;
142
+ break;
143
default:
144
if (ch >= 32) {
145
readline_insert_char(rs, ch);
146
@@ -XXX,XX +XXX,XX @@ void readline_handle_byte(ReadLineState *rs, int ch)
147
break;
148
case IS_CSI:
149
switch (ch) {
150
-    case 'A':
151
-    case 'F':
152
-     readline_up_char(rs);
153
-     break;
154
-    case 'B':
155
-    case 'E':
156
-     readline_down_char(rs);
157
-     break;
158
+ case 'A':
159
+ case 'F':
160
+ readline_up_char(rs);
161
+ break;
162
+ case 'B':
163
+ case 'E':
164
+ readline_down_char(rs);
165
+ break;
166
case 'D':
167
readline_backward_char(rs);
168
break;
169
--
170
2.21.0
171
172
diff view generated by jsdifflib
Deleted patch
1
From: Jules Irenge <jbi.octave@gmail.com>
2
1
3
Add braces to fix errors issued by checkpatch.pl tool
4
"ERROR: braces {} are necessary for all arms of this statement"
5
Within "util/readline.c" file
6
Message-Id: <20190330112142.14082-1-jbi.octave@gmail.com>
7
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
10
util/readline.c | 50 ++++++++++++++++++++++++++++++++-----------------
11
1 file changed, 33 insertions(+), 17 deletions(-)
12
13
diff --git a/util/readline.c b/util/readline.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/util/readline.c
16
+++ b/util/readline.c
17
@@ -XXX,XX +XXX,XX @@ static void readline_update(ReadLineState *rs)
18
rs->cmd_buf[rs->cmd_buf_size] = '\0';
19
if (rs->read_password) {
20
len = strlen(rs->cmd_buf);
21
- for (i = 0; i < len; i++)
22
+ for (i = 0; i < len; i++) {
23
rs->printf_func(rs->opaque, "*");
24
+ }
25
} else {
26
rs->printf_func(rs->opaque, "%s", rs->cmd_buf);
27
}
28
@@ -XXX,XX +XXX,XX @@ static void readline_up_char(ReadLineState *rs)
29
{
30
int idx;
31
32
- if (rs->hist_entry == 0)
33
+ if (rs->hist_entry == 0) {
34
return;
35
+ }
36
if (rs->hist_entry == -1) {
37
/* Find latest entry */
38
for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
39
- if (rs->history[idx] == NULL)
40
+ if (rs->history[idx] == NULL) {
41
break;
42
+ }
43
}
44
rs->hist_entry = idx;
45
}
46
@@ -XXX,XX +XXX,XX @@ static void readline_up_char(ReadLineState *rs)
47
48
static void readline_down_char(ReadLineState *rs)
49
{
50
- if (rs->hist_entry == -1)
51
+ if (rs->hist_entry == -1) {
52
return;
53
+ }
54
if (rs->hist_entry < READLINE_MAX_CMDS - 1 &&
55
rs->history[++rs->hist_entry] != NULL) {
56
pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
57
@@ -XXX,XX +XXX,XX @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline)
58
char *hist_entry, *new_entry;
59
int idx;
60
61
- if (cmdline[0] == '\0')
62
+ if (cmdline[0] == '\0') {
63
return;
64
+ }
65
new_entry = NULL;
66
if (rs->hist_entry != -1) {
67
/* We were editing an existing history entry: replace it */
68
@@ -XXX,XX +XXX,XX @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline)
69
/* Search cmdline in history buffers */
70
for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
71
hist_entry = rs->history[idx];
72
- if (hist_entry == NULL)
73
+ if (hist_entry == NULL) {
74
break;
75
+ }
76
if (strcmp(hist_entry, cmdline) == 0) {
77
same_entry:
78
new_entry = hist_entry;
79
@@ -XXX,XX +XXX,XX @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline)
80
(READLINE_MAX_CMDS - (idx + 1)) * sizeof(char *));
81
rs->history[READLINE_MAX_CMDS - 1] = NULL;
82
for (; idx < READLINE_MAX_CMDS; idx++) {
83
- if (rs->history[idx] == NULL)
84
+ if (rs->history[idx] == NULL) {
85
break;
86
+ }
87
}
88
break;
89
}
90
@@ -XXX,XX +XXX,XX @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline)
91
rs->history[READLINE_MAX_CMDS - 1] = NULL;
92
idx = READLINE_MAX_CMDS - 1;
93
}
94
- if (new_entry == NULL)
95
+ if (new_entry == NULL) {
96
new_entry = g_strdup(cmdline);
97
+ }
98
rs->history[idx] = new_entry;
99
rs->hist_entry = -1;
100
}
101
@@ -XXX,XX +XXX,XX @@ static void readline_completion(ReadLineState *rs)
102
g_free(cmdline);
103
104
/* no completion found */
105
- if (rs->nb_completions <= 0)
106
+ if (rs->nb_completions <= 0) {
107
return;
108
+ }
109
if (rs->nb_completions == 1) {
110
len = strlen(rs->completions[0]);
111
for (i = rs->completion_index; i < len; i++) {
112
readline_insert_char(rs, rs->completions[0][i]);
113
}
114
/* extra space for next argument. XXX: make it more generic */
115
- if (len > 0 && rs->completions[0][len - 1] != '/')
116
+ if (len > 0 && rs->completions[0][len - 1] != '/') {
117
readline_insert_char(rs, ' ');
118
+ }
119
} else {
120
qsort(rs->completions, rs->nb_completions, sizeof(char *),
121
completion_comp);
122
@@ -XXX,XX +XXX,XX @@ static void readline_completion(ReadLineState *rs)
123
if (i == 0) {
124
max_prefix = len;
125
} else {
126
- if (len < max_prefix)
127
+ if (len < max_prefix) {
128
max_prefix = len;
129
+ }
130
for (j = 0; j < max_prefix; j++) {
131
- if (rs->completions[i][j] != rs->completions[0][j])
132
+ if (rs->completions[i][j] != rs->completions[0][j]) {
133
max_prefix = j;
134
+ }
135
}
136
}
137
- if (len > max_width)
138
+ if (len > max_width) {
139
max_width = len;
140
+ }
141
}
142
if (max_prefix > 0)
143
for (i = rs->completion_index; i < max_prefix; i++) {
144
readline_insert_char(rs, rs->completions[0][i]);
145
}
146
max_width += 2;
147
- if (max_width < 10)
148
+ if (max_width < 10) {
149
max_width = 10;
150
- else if (max_width > 80)
151
+ } else if (max_width > 80) {
152
max_width = 80;
153
+ }
154
nb_cols = 80 / max_width;
155
j = 0;
156
for (i = 0; i < rs->nb_completions; i++) {
157
@@ -XXX,XX +XXX,XX @@ void readline_handle_byte(ReadLineState *rs, int ch)
158
case 10:
159
case 13:
160
rs->cmd_buf[rs->cmd_buf_size] = '\0';
161
- if (!rs->read_password)
162
+ if (!rs->read_password) {
163
readline_hist_add(rs, rs->cmd_buf);
164
+ }
165
rs->printf_func(rs->opaque, "\n");
166
rs->cmd_buf_index = 0;
167
rs->cmd_buf_size = 0;
168
@@ -XXX,XX +XXX,XX @@ void readline_restart(ReadLineState *rs)
169
170
const char *readline_get_history(ReadLineState *rs, unsigned int index)
171
{
172
- if (index >= READLINE_MAX_CMDS)
173
+ if (index >= READLINE_MAX_CMDS) {
174
return NULL;
175
+ }
176
return rs->history[index];
177
}
178
179
--
180
2.21.0
181
182
diff view generated by jsdifflib
Deleted patch
1
From: Nikita Alekseev <n.alekseev2104@gmail.com>
2
1
3
bdrv_check_co_entry calls bdrv_co_check, which is a coroutine function.
4
Thus, it also needs to be marked as a coroutine.
5
6
Signed-off-by: Nikita Alekseev <n.alekseev2104@gmail.com>
7
Message-id: 20190401093051.16488-1-n.alekseev2104@gmail.com
8
Message-Id: <20190401093051.16488-1-n.alekseev2104@gmail.com>
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
11
block.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct CheckCo {
19
int ret;
20
} CheckCo;
21
22
-static void bdrv_check_co_entry(void *opaque)
23
+static void coroutine_fn bdrv_check_co_entry(void *opaque)
24
{
25
CheckCo *cco = opaque;
26
cco->ret = bdrv_co_check(cco->bs, cco->res, cco->fix);
27
--
28
2.21.0
29
30
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
On a file system used by the customer, fallocate() returns an error
3
"0x%u" format is very misleading, replace by "0x%x".
4
if the block is not properly aligned. So, bdrv_co_pwrite_zeroes()
5
fails. We can handle that case the same way as it is done for the
6
unsupported cases, namely, call to bdrv_driver_pwritev() that writes
7
zeroes to an image for the unaligned chunk of the block.
8
4
9
Suggested-by: Denis V. Lunev <den@openvz.org>
5
Found running:
10
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
6
11
Reviewed-by: John Snow <jsnow@redhat.com>
7
$ git grep -E '0x%[0-9]*([lL]*|" ?PRI)[dDuU]' block/
12
Message-id: 1554474244-553661-1-git-send-email-andrey.shinkevich@virtuozzo.com
8
13
Message-Id: <1554474244-553661-1-git-send-email-andrey.shinkevich@virtuozzo.com>
9
Inspired-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
12
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
13
Reviewed-by: Denis V. Lunev <den@openvz.org>
14
Message-id: 20220323114718.58714-2-philippe.mathieu.daude@gmail.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
16
---
16
block/io.c | 2 +-
17
block/parallels-ext.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
18
19
19
diff --git a/block/io.c b/block/io.c
20
diff --git a/block/parallels-ext.c b/block/parallels-ext.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/block/io.c
22
--- a/block/parallels-ext.c
22
+++ b/block/io.c
23
+++ b/block/parallels-ext.c
23
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
24
@@ -XXX,XX +XXX,XX @@ static int parallels_parse_format_extension(BlockDriverState *bs,
24
assert(!bs->supported_zero_flags);
25
break;
26
27
default:
28
- error_setg(errp, "Unknown feature: 0x%" PRIu64, fh.magic);
29
+ error_setg(errp, "Unknown feature: 0x%" PRIx64, fh.magic);
30
goto fail;
25
}
31
}
26
32
27
- if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
28
+ if (ret < 0 && !(flags & BDRV_REQ_NO_FALLBACK)) {
29
/* Fall back to bounce buffer if write zeroes is unsupported */
30
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
31
32
--
33
--
33
2.21.0
34
2.35.1
34
35
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
With aio=thread, adaptive polling makes latency worse rather than
4
better, because it delays the execution of the ThreadPool's
5
completion bottom half.
6
7
event_notifier_poll() does run while polling, detecting that
8
a bottom half was scheduled by a worker thread, but because
9
ctx->notifier is explicitly ignored in run_poll_handlers_once(),
10
scheduling the BH does not count as making progress and
11
run_poll_handlers() keeps running. Fix this by recomputing
12
the deadline after *timeout could have changed.
13
14
With this change, ThreadPool still cannot participate in polling
15
but at least it does not suffer from extra latency.
16
17
Reported-by: Sergio Lopez <slp@redhat.com>
18
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
19
Message-id: 20190409122823.12416-1-pbonzini@redhat.com
20
Cc: Stefan Hajnoczi <stefanha@gmail.com>
21
Cc: Kevin Wolf <kwolf@redhat.com>
22
Cc: qemu-block@nongnu.org
23
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
24
Message-Id: <1553692145-86728-1-git-send-email-pbonzini@redhat.com>
25
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
26
Message-Id: <20190409122823.12416-1-pbonzini@redhat.com>
27
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
28
---
29
util/aio-posix.c | 12 ++++++++----
30
1 file changed, 8 insertions(+), 4 deletions(-)
31
32
diff --git a/util/aio-posix.c b/util/aio-posix.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/util/aio-posix.c
35
+++ b/util/aio-posix.c
36
@@ -XXX,XX +XXX,XX @@ static bool run_poll_handlers_once(AioContext *ctx, int64_t *timeout)
37
if (!node->deleted && node->io_poll &&
38
aio_node_check(ctx, node->is_external) &&
39
node->io_poll(node->opaque)) {
40
+ /*
41
+ * Polling was successful, exit try_poll_mode immediately
42
+ * to adjust the next polling time.
43
+ */
44
*timeout = 0;
45
if (node->opaque != &ctx->notifier) {
46
progress = true;
47
@@ -XXX,XX +XXX,XX @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout)
48
do {
49
progress = run_poll_handlers_once(ctx, timeout);
50
elapsed_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start_time;
51
- } while (!progress && elapsed_time < max_ns
52
- && !atomic_read(&ctx->poll_disable_cnt));
53
+ max_ns = qemu_soonest_timeout(*timeout, max_ns);
54
+ assert(!(max_ns && progress));
55
+ } while (elapsed_time < max_ns && !atomic_read(&ctx->poll_disable_cnt));
56
57
/* If time has passed with no successful polling, adjust *timeout to
58
* keep the same ending time.
59
@@ -XXX,XX +XXX,XX @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout)
60
*/
61
static bool try_poll_mode(AioContext *ctx, int64_t *timeout)
62
{
63
- /* See qemu_soonest_timeout() uint64_t hack */
64
- int64_t max_ns = MIN((uint64_t)*timeout, (uint64_t)ctx->poll_ns);
65
+ int64_t max_ns = qemu_soonest_timeout(*timeout, ctx->poll_ns);
66
67
if (max_ns && !atomic_read(&ctx->poll_disable_cnt)) {
68
poll_set_started(ctx, true);
69
--
70
2.21.0
71
72
diff view generated by jsdifflib
Deleted patch
1
At KVM Forum 2018 I gave a presentation on security in QEMU:
2
https://www.youtube.com/watch?v=YAdRf_hwxU8 (video)
3
https://vmsplice.net/~stefan/stefanha-kvm-forum-2018.pdf (slides)
4
1
5
This patch adds a guide to secure coding practices. This document
6
covers things that developers should know about security in QEMU. It is
7
just a starting point that we can expand on later. I hope it will be
8
useful as a resource for new contributors and will save code reviewers
9
from explaining the same concepts many times.
10
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
16
Reviewed-by: Li Qiang <liq3ea@gmail.com>
17
Message-id: 20190509121820.16294-2-stefanha@redhat.com
18
Message-Id: <20190509121820.16294-2-stefanha@redhat.com>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
---
21
docs/devel/index.rst | 1 +
22
docs/devel/secure-coding-practices.rst | 106 +++++++++++++++++++++++++
23
2 files changed, 107 insertions(+)
24
create mode 100644 docs/devel/secure-coding-practices.rst
25
26
diff --git a/docs/devel/index.rst b/docs/devel/index.rst
27
index XXXXXXX..XXXXXXX 100644
28
--- a/docs/devel/index.rst
29
+++ b/docs/devel/index.rst
30
@@ -XXX,XX +XXX,XX @@ Contents:
31
stable-process
32
testing
33
decodetree
34
+ secure-coding-practices
35
diff --git a/docs/devel/secure-coding-practices.rst b/docs/devel/secure-coding-practices.rst
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/docs/devel/secure-coding-practices.rst
40
@@ -XXX,XX +XXX,XX @@
41
+=======================
42
+Secure Coding Practices
43
+=======================
44
+This document covers topics that both developers and security researchers must
45
+be aware of so that they can develop safe code and audit existing code
46
+properly.
47
+
48
+Reporting Security Bugs
49
+-----------------------
50
+For details on how to report security bugs or ask questions about potential
51
+security bugs, see the `Security Process wiki page
52
+<https://wiki.qemu.org/SecurityProcess>`_.
53
+
54
+General Secure C Coding Practices
55
+---------------------------------
56
+Most CVEs (security bugs) reported against QEMU are not specific to
57
+virtualization or emulation. They are simply C programming bugs. Therefore
58
+it's critical to be aware of common classes of security bugs.
59
+
60
+There is a wide selection of resources available covering secure C coding. For
61
+example, the `CERT C Coding Standard
62
+<https://wiki.sei.cmu.edu/confluence/display/c/SEI+CERT+C+Coding+Standard>`_
63
+covers the most important classes of security bugs.
64
+
65
+Instead of describing them in detail here, only the names of the most important
66
+classes of security bugs are mentioned:
67
+
68
+* Buffer overflows
69
+* Use-after-free and double-free
70
+* Integer overflows
71
+* Format string vulnerabilities
72
+
73
+Some of these classes of bugs can be detected by analyzers. Static analysis is
74
+performed regularly by Coverity and the most obvious of these bugs are even
75
+reported by compilers. Dynamic analysis is possible with valgrind, tsan, and
76
+asan.
77
+
78
+Input Validation
79
+----------------
80
+Inputs from the guest or external sources (e.g. network, files) cannot be
81
+trusted and may be invalid. Inputs must be checked before using them in a way
82
+that could crash the program, expose host memory to the guest, or otherwise be
83
+exploitable by an attacker.
84
+
85
+The most sensitive attack surface is device emulation. All hardware register
86
+accesses and data read from guest memory must be validated. A typical example
87
+is a device that contains multiple units that are selectable by the guest via
88
+an index register::
89
+
90
+ typedef struct {
91
+ ProcessingUnit unit[2];
92
+ ...
93
+ } MyDeviceState;
94
+
95
+ static void mydev_writel(void *opaque, uint32_t addr, uint32_t val)
96
+ {
97
+ MyDeviceState *mydev = opaque;
98
+ ProcessingUnit *unit;
99
+
100
+ switch (addr) {
101
+ case MYDEV_SELECT_UNIT:
102
+ unit = &mydev->unit[val]; <-- this input wasn't validated!
103
+ ...
104
+ }
105
+ }
106
+
107
+If ``val`` is not in range [0, 1] then an out-of-bounds memory access will take
108
+place when ``unit`` is dereferenced. The code must check that ``val`` is 0 or
109
+1 and handle the case where it is invalid.
110
+
111
+Unexpected Device Accesses
112
+--------------------------
113
+The guest may access device registers in unusual orders or at unexpected
114
+moments. Device emulation code must not assume that the guest follows the
115
+typical "theory of operation" presented in driver writer manuals. The guest
116
+may make nonsense accesses to device registers such as starting operations
117
+before the device has been fully initialized.
118
+
119
+A related issue is that device emulation code must be prepared for unexpected
120
+device register accesses while asynchronous operations are in progress. A
121
+well-behaved guest might wait for a completion interrupt before accessing
122
+certain device registers. Device emulation code must handle the case where the
123
+guest overwrites registers or submits further requests before an ongoing
124
+request completes. Unexpected accesses must not cause memory corruption or
125
+leaks in QEMU.
126
+
127
+Invalid device register accesses can be reported with
128
+``qemu_log_mask(LOG_GUEST_ERROR, ...)``. The ``-d guest_errors`` command-line
129
+option enables these log messages.
130
+
131
+Live Migration
132
+--------------
133
+Device state can be saved to disk image files and shared with other users.
134
+Live migration code must validate inputs when loading device state so an
135
+attacker cannot gain control by crafting invalid device states. Device state
136
+is therefore considered untrusted even though it is typically generated by QEMU
137
+itself.
138
+
139
+Guest Memory Access Races
140
+-------------------------
141
+Guests with multiple vCPUs may modify guest RAM while device emulation code is
142
+running. Device emulation code must copy in descriptors and other guest RAM
143
+structures and only process the local copy. This prevents
144
+time-of-check-to-time-of-use (TOCTOU) race conditions that could cause QEMU to
145
+crash when a vCPU thread modifies guest RAM while device emulation is
146
+processing it.
147
--
148
2.21.0
149
150
diff view generated by jsdifflib
1
This new chapter in the QEMU documentation covers the security
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
requirements that QEMU is designed to meet and principles for securely
3
deploying QEMU.
4
2
5
It is just a starting point that can be extended in the future with more
3
"0x%u" format is very misleading, replace by "0x%x".
6
information.
7
4
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Found running:
9
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
6
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
$ git grep -E '0x%[0-9]*([lL]*|" ?PRI)[dDuU]' hw/
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
9
Inspired-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
11
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
13
Reviewed-by: Li Qiang <liq3ea@gmail.com>
12
Message-id: 20220323114718.58714-3-philippe.mathieu.daude@gmail.com
14
Message-id: 20190509121820.16294-3-stefanha@redhat.com
15
Message-Id: <20190509121820.16294-3-stefanha@redhat.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
---
14
---
18
Makefile | 2 +-
15
hw/i386/sgx.c | 2 +-
19
docs/security.texi | 131 +++++++++++++++++++++++++++++++++++++++++++++
16
hw/i386/trace-events | 6 +++---
20
qemu-doc.texi | 3 ++
17
hw/misc/trace-events | 4 ++--
21
3 files changed, 135 insertions(+), 1 deletion(-)
18
hw/scsi/trace-events | 4 ++--
22
create mode 100644 docs/security.texi
19
4 files changed, 8 insertions(+), 8 deletions(-)
23
20
24
diff --git a/Makefile b/Makefile
21
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/Makefile
23
--- a/hw/i386/sgx.c
27
+++ b/Makefile
24
+++ b/hw/i386/sgx.c
28
@@ -XXX,XX +XXX,XX @@ qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
25
@@ -XXX,XX +XXX,XX @@ void pc_machine_init_sgx_epc(PCMachineState *pcms)
29
    qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-option-trace.texi \
26
}
30
    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \
27
31
    qemu-monitor-info.texi docs/qemu-block-drivers.texi \
28
if ((sgx_epc->base + sgx_epc->size) < sgx_epc->base) {
32
-    docs/qemu-cpu-models.texi
29
- error_report("Size of all 'sgx-epc' =0x%"PRIu64" causes EPC to wrap",
33
+    docs/qemu-cpu-models.texi docs/security.texi
30
+ error_report("Size of all 'sgx-epc' =0x%"PRIx64" causes EPC to wrap",
34
31
sgx_epc->size);
35
docs/interop/qemu-ga-ref.dvi docs/interop/qemu-ga-ref.html \
32
exit(EXIT_FAILURE);
36
docs/interop/qemu-ga-ref.info docs/interop/qemu-ga-ref.pdf \
33
}
37
diff --git a/docs/security.texi b/docs/security.texi
34
diff --git a/hw/i386/trace-events b/hw/i386/trace-events
38
new file mode 100644
35
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX
36
--- a/hw/i386/trace-events
40
--- /dev/null
37
+++ b/hw/i386/trace-events
41
+++ b/docs/security.texi
38
@@ -XXX,XX +XXX,XX @@ vtd_fault_disabled(void) "Fault processing disabled for context entry"
39
vtd_replay_ce_valid(const char *mode, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t domain, uint64_t hi, uint64_t lo) "%s: replay valid context device %02"PRIx8":%02"PRIx8".%02"PRIx8" domain 0x%"PRIx16" hi 0x%"PRIx64" lo 0x%"PRIx64
40
vtd_replay_ce_invalid(uint8_t bus, uint8_t dev, uint8_t fn) "replay invalid context device %02"PRIx8":%02"PRIx8".%02"PRIx8
41
vtd_page_walk_level(uint64_t addr, uint32_t level, uint64_t start, uint64_t end) "walk (base=0x%"PRIx64", level=%"PRIu32") iova range 0x%"PRIx64" - 0x%"PRIx64
42
-vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIu16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d"
43
+vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIx16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d"
44
vtd_page_walk_one_skip_map(uint64_t iova, uint64_t mask, uint64_t translated) "iova 0x%"PRIx64" mask 0x%"PRIx64" translated 0x%"PRIx64
45
vtd_page_walk_one_skip_unmap(uint64_t iova, uint64_t mask) "iova 0x%"PRIx64" mask 0x%"PRIx64
46
vtd_page_walk_skip_read(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to unable to read"
47
vtd_page_walk_skip_reserve(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to rsrv set"
48
vtd_switch_address_space(uint8_t bus, uint8_t slot, uint8_t fn, bool on) "Device %02x:%02x.%x switching address space (iommu enabled=%d)"
49
vtd_as_unmap_whole(uint8_t bus, uint8_t slot, uint8_t fn, uint64_t iova, uint64_t size) "Device %02x:%02x.%x start 0x%"PRIx64" size 0x%"PRIx64
50
-vtd_translate_pt(uint16_t sid, uint64_t addr) "source id 0x%"PRIu16", iova 0x%"PRIx64
51
-vtd_pt_enable_fast_path(uint16_t sid, bool success) "sid 0x%"PRIu16" %d"
52
+vtd_translate_pt(uint16_t sid, uint64_t addr) "source id 0x%"PRIx16", iova 0x%"PRIx64
53
+vtd_pt_enable_fast_path(uint16_t sid, bool success) "sid 0x%"PRIx16" %d"
54
vtd_irq_generate(uint64_t addr, uint64_t data) "addr 0x%"PRIx64" data 0x%"PRIx64
55
vtd_reg_read(uint64_t addr, uint64_t size) "addr 0x%"PRIx64" size 0x%"PRIx64
56
vtd_reg_write(uint64_t addr, uint64_t size, uint64_t val) "addr 0x%"PRIx64" size 0x%"PRIx64" value 0x%"PRIx64
57
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/misc/trace-events
60
+++ b/hw/misc/trace-events
42
@@ -XXX,XX +XXX,XX @@
61
@@ -XXX,XX +XXX,XX @@
43
+@node Security
62
# See docs/devel/tracing.rst for syntax documentation.
44
+@chapter Security
63
45
+
64
# allwinner-cpucfg.c
46
+@section Overview
65
-allwinner_cpucfg_cpu_reset(uint8_t cpu_id, uint32_t reset_addr) "id %u, reset_addr 0x%" PRIu32
47
+
66
+allwinner_cpucfg_cpu_reset(uint8_t cpu_id, uint32_t reset_addr) "id %u, reset_addr 0x%" PRIx32
48
+This chapter explains the security requirements that QEMU is designed to meet
67
allwinner_cpucfg_read(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32
49
+and principles for securely deploying QEMU.
68
allwinner_cpucfg_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32
50
+
69
51
+@section Security Requirements
70
@@ -XXX,XX +XXX,XX @@ imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" PRIx64 "value 0x%08
52
+
71
53
+QEMU supports many different use cases, some of which have stricter security
72
# mos6522.c
54
+requirements than others. The community has agreed on the overall security
73
mos6522_set_counter(int index, unsigned int val) "T%d.counter=%d"
55
+requirements that users may depend on. These requirements define what is
74
-mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d counter=0x%"PRId64 " delta_next=0x%"PRId64
56
+considered supported from a security perspective.
75
+mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d counter=0x%"PRIx64 " delta_next=0x%"PRIx64
57
+
76
mos6522_set_sr_int(void) "set sr_int"
58
+@subsection Virtualization Use Case
77
mos6522_write(uint64_t addr, const char *name, uint64_t val) "reg=0x%"PRIx64 " [%s] val=0x%"PRIx64
59
+
78
mos6522_read(uint64_t addr, const char *name, unsigned val) "reg=0x%"PRIx64 " [%s] val=0x%x"
60
+The virtualization use case covers cloud and virtual private server (VPS)
79
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
61
+hosting, as well as traditional data center and desktop virtualization. These
62
+use cases rely on hardware virtualization extensions to execute guest code
63
+safely on the physical CPU at close-to-native speed.
64
+
65
+The following entities are untrusted, meaning that they may be buggy or
66
+malicious:
67
+
68
+@itemize
69
+@item Guest
70
+@item User-facing interfaces (e.g. VNC, SPICE, WebSocket)
71
+@item Network protocols (e.g. NBD, live migration)
72
+@item User-supplied files (e.g. disk images, kernels, device trees)
73
+@item Passthrough devices (e.g. PCI, USB)
74
+@end itemize
75
+
76
+Bugs affecting these entities are evaluated on whether they can cause damage in
77
+real-world use cases and treated as security bugs if this is the case.
78
+
79
+@subsection Non-virtualization Use Case
80
+
81
+The non-virtualization use case covers emulation using the Tiny Code Generator
82
+(TCG). In principle the TCG and device emulation code used in conjunction with
83
+the non-virtualization use case should meet the same security requirements as
84
+the virtualization use case. However, for historical reasons much of the
85
+non-virtualization use case code was not written with these security
86
+requirements in mind.
87
+
88
+Bugs affecting the non-virtualization use case are not considered security
89
+bugs at this time. Users with non-virtualization use cases must not rely on
90
+QEMU to provide guest isolation or any security guarantees.
91
+
92
+@section Architecture
93
+
94
+This section describes the design principles that ensure the security
95
+requirements are met.
96
+
97
+@subsection Guest Isolation
98
+
99
+Guest isolation is the confinement of guest code to the virtual machine. When
100
+guest code gains control of execution on the host this is called escaping the
101
+virtual machine. Isolation also includes resource limits such as throttling of
102
+CPU, memory, disk, or network. Guests must be unable to exceed their resource
103
+limits.
104
+
105
+QEMU presents an attack surface to the guest in the form of emulated devices.
106
+The guest must not be able to gain control of QEMU. Bugs in emulated devices
107
+could allow malicious guests to gain code execution in QEMU. At this point the
108
+guest has escaped the virtual machine and is able to act in the context of the
109
+QEMU process on the host.
110
+
111
+Guests often interact with other guests and share resources with them. A
112
+malicious guest must not gain control of other guests or access their data.
113
+Disk image files and network traffic must be protected from other guests unless
114
+explicitly shared between them by the user.
115
+
116
+@subsection Principle of Least Privilege
117
+
118
+The principle of least privilege states that each component only has access to
119
+the privileges necessary for its function. In the case of QEMU this means that
120
+each process only has access to resources belonging to the guest.
121
+
122
+The QEMU process should not have access to any resources that are inaccessible
123
+to the guest. This way the guest does not gain anything by escaping into the
124
+QEMU process since it already has access to those same resources from within
125
+the guest.
126
+
127
+Following the principle of least privilege immediately fulfills guest isolation
128
+requirements. For example, guest A only has access to its own disk image file
129
+@code{a.img} and not guest B's disk image file @code{b.img}.
130
+
131
+In reality certain resources are inaccessible to the guest but must be
132
+available to QEMU to perform its function. For example, host system calls are
133
+necessary for QEMU but are not exposed to guests. A guest that escapes into
134
+the QEMU process can then begin invoking host system calls.
135
+
136
+New features must be designed to follow the principle of least privilege.
137
+Should this not be possible for technical reasons, the security risk must be
138
+clearly documented so users are aware of the trade-off of enabling the feature.
139
+
140
+@subsection Isolation mechanisms
141
+
142
+Several isolation mechanisms are available to realize this architecture of
143
+guest isolation and the principle of least privilege. With the exception of
144
+Linux seccomp, these mechanisms are all deployed by management tools that
145
+launch QEMU, such as libvirt. They are also platform-specific so they are only
146
+described briefly for Linux here.
147
+
148
+The fundamental isolation mechanism is that QEMU processes must run as
149
+unprivileged users. Sometimes it seems more convenient to launch QEMU as
150
+root to give it access to host devices (e.g. @code{/dev/net/tun}) but this poses a
151
+huge security risk. File descriptor passing can be used to give an otherwise
152
+unprivileged QEMU process access to host devices without running QEMU as root.
153
+It is also possible to launch QEMU as a non-root user and configure UNIX groups
154
+for access to @code{/dev/kvm}, @code{/dev/net/tun}, and other device nodes.
155
+Some Linux distros already ship with UNIX groups for these devices by default.
156
+
157
+@itemize
158
+@item SELinux and AppArmor make it possible to confine processes beyond the
159
+traditional UNIX process and file permissions model. They restrict the QEMU
160
+process from accessing processes and files on the host system that are not
161
+needed by QEMU.
162
+
163
+@item Resource limits and cgroup controllers provide throughput and utilization
164
+limits on key resources such as CPU time, memory, and I/O bandwidth.
165
+
166
+@item Linux namespaces can be used to make process, file system, and other system
167
+resources unavailable to QEMU. A namespaced QEMU process is restricted to only
168
+those resources that were granted to it.
169
+
170
+@item Linux seccomp is available via the QEMU @option{--sandbox} option. It disables
171
+system calls that are not needed by QEMU, thereby reducing the host kernel
172
+attack surface.
173
+@end itemize
174
diff --git a/qemu-doc.texi b/qemu-doc.texi
175
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
176
--- a/qemu-doc.texi
81
--- a/hw/scsi/trace-events
177
+++ b/qemu-doc.texi
82
+++ b/hw/scsi/trace-events
178
@@ -XXX,XX +XXX,XX @@
83
@@ -XXX,XX +XXX,XX @@ lsi_bad_phase_interrupt(void) "Phase mismatch interrupt"
179
* QEMU Guest Agent::
84
lsi_bad_selection(uint32_t id) "Selected absent target %"PRIu32
180
* QEMU User space emulator::
85
lsi_do_dma_unavailable(void) "DMA no data available"
181
* System requirements::
86
lsi_do_dma(uint64_t addr, int len) "DMA addr=0x%"PRIx64" len=%d"
182
+* Security::
87
-lsi_queue_command(uint32_t tag) "Queueing tag=0x%"PRId32
183
* Implementation notes::
88
+lsi_queue_command(uint32_t tag) "Queueing tag=0x%"PRIx32
184
* Deprecated features::
89
lsi_add_msg_byte_error(void) "MSG IN data too long"
185
* Supported build platforms::
90
lsi_add_msg_byte(uint8_t data) "MSG IN 0x%02x"
186
@@ -XXX,XX +XXX,XX @@ added with Linux 4.5 which is supported by the major distros. And even
91
lsi_reselect(int id) "Reselected target %d"
187
if RHEL7 has kernel 3.10, KVM there has the required functionality there
92
@@ -XXX,XX +XXX,XX @@ lsi_do_msgout_noop(void) "MSG: No Operation"
188
to make it close to a 4.5 or newer kernel.
93
lsi_do_msgout_extended(uint8_t msg, uint8_t len) "Extended message 0x%x (len %d)"
189
94
lsi_do_msgout_ignored(const char *msg) "%s (ignored)"
190
+@include docs/security.texi
95
lsi_do_msgout_simplequeue(uint8_t select_tag) "SIMPLE queue tag=0x%x"
191
+
96
-lsi_do_msgout_abort(uint32_t tag) "MSG: ABORT TAG tag=0x%"PRId32
192
@include qemu-tech.texi
97
+lsi_do_msgout_abort(uint32_t tag) "MSG: ABORT TAG tag=0x%"PRIx32
193
98
lsi_do_msgout_clearqueue(uint32_t tag) "MSG: CLEAR QUEUE tag=0x%"PRIx32
194
@include qemu-deprecated.texi
99
lsi_do_msgout_busdevicereset(uint32_t tag) "MSG: BUS DEVICE RESET tag=0x%"PRIx32
100
lsi_do_msgout_select(int id) "Select LUN %d"
195
--
101
--
196
2.21.0
102
2.35.1
197
103
198
104
diff view generated by jsdifflib