|
54 | 54 | #include "qemu/rcu.h" |
55 | 55 | #include "block/coroutines.h" |
56 | 56 |
|
| 57 | +#include "libafl/syx-snapshot/syx-snapshot.h" |
| 58 | + |
57 | 59 | #ifdef CONFIG_BSD |
58 | 60 | #include <sys/ioctl.h> |
59 | 61 | #include <sys/queue.h> |
@@ -1259,6 +1261,34 @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options, |
1259 | 1261 | *child_flags &= ~BDRV_O_NATIVE_AIO; |
1260 | 1262 | } |
1261 | 1263 |
|
| 1264 | +//// --- Begin LibAFL code --- |
| 1265 | + |
| 1266 | +/* |
| 1267 | + * Returns the options and flags that a temporary snapshot should get, based on |
| 1268 | + * the originally requested flags (the originally requested image will have |
| 1269 | + * flags like a backing file) |
| 1270 | + */ |
| 1271 | +static void bdrv_syx_cow_cache_options(int *child_flags, QDict *child_options, |
| 1272 | + int parent_flags, QDict *parent_options) |
| 1273 | +{ |
| 1274 | + GLOBAL_STATE_CODE(); |
| 1275 | + *child_flags = parent_flags; |
| 1276 | + |
| 1277 | + /* For temporary files, unconditional cache=unsafe is fine */ |
| 1278 | + qdict_set_default_str(child_options, BDRV_OPT_CACHE_DIRECT, "off"); |
| 1279 | + qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on"); |
| 1280 | + |
| 1281 | + /* Copy the read-only and discard options from the parent */ |
| 1282 | + qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY); |
| 1283 | + qdict_copy_default(child_options, parent_options, BDRV_OPT_DISCARD); |
| 1284 | + |
| 1285 | + /* aio=native doesn't work for cache.direct=off, so disable it for the |
| 1286 | + * temporary snapshot */ |
| 1287 | + *child_flags &= ~BDRV_O_NATIVE_AIO; |
| 1288 | +} |
| 1289 | + |
| 1290 | +//// --- End LibAFL code --- |
| 1291 | + |
1262 | 1292 | static void GRAPH_WRLOCK bdrv_backing_attach(BdrvChild *c) |
1263 | 1293 | { |
1264 | 1294 | BlockDriverState *parent = c->opaque; |
@@ -3870,6 +3900,33 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp) |
3870 | 3900 | return bs; |
3871 | 3901 | } |
3872 | 3902 |
|
| 3903 | +//// --- Begin LibAFL code --- |
| 3904 | + |
| 3905 | +static BlockDriverState *bdrv_append_syx_cow_cache(BlockDriverState *bs, |
| 3906 | + int flags, |
| 3907 | + QDict *scc_options, |
| 3908 | + Error **errp) |
| 3909 | +{ |
| 3910 | + BlockDriverState* bs_scc = NULL; |
| 3911 | + |
| 3912 | + /* We add a syx-cow-cache layer on top of the node being opened */ |
| 3913 | + qdict_put_str(scc_options, "driver", "syx-cow-cache"); |
| 3914 | + qdict_put_str(scc_options, "file", bs->node_name); |
| 3915 | + |
| 3916 | + /* Open the syx cow cache */ |
| 3917 | + bs_scc = bdrv_open(NULL, NULL, scc_options, flags, errp); |
| 3918 | + scc_options = NULL; |
| 3919 | + if (!bs_scc) { |
| 3920 | + goto out; |
| 3921 | + } |
| 3922 | + |
| 3923 | +out: |
| 3924 | + qobject_unref(scc_options); |
| 3925 | + return bs_scc; |
| 3926 | +} |
| 3927 | + |
| 3928 | +//// --- End LibAFL code --- |
| 3929 | + |
3873 | 3930 | static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, |
3874 | 3931 | int flags, |
3875 | 3932 | QDict *snapshot_options, |
@@ -3966,6 +4023,14 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, |
3966 | 4023 | QDict *snapshot_options = NULL; |
3967 | 4024 | int snapshot_flags = 0; |
3968 | 4025 |
|
| 4026 | +//// --- Begin LibAFL code --- |
| 4027 | + |
| 4028 | + QDict* scc_options = NULL; |
| 4029 | + int scc_flags = 0; |
| 4030 | + bool attach_syx_continue = false; |
| 4031 | + |
| 4032 | +//// --- End LibAFL code --- |
| 4033 | + |
3969 | 4034 | assert(!child_class || !flags); |
3970 | 4035 | assert(!child_class == !parent); |
3971 | 4036 | GLOBAL_STATE_CODE(); |
@@ -4152,6 +4217,24 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, |
4152 | 4217 | * (the inverse results in an error message from bdrv_open_common()) */ |
4153 | 4218 | assert(!(flags & BDRV_O_PROTOCOL) || !file); |
4154 | 4219 |
|
| 4220 | +//// --- Begin LibAFL code --- |
| 4221 | + if (!(flags & BDRV_O_NOSYX) && syx_snapshot_use_scc() && !strcmp(drv->format_name, "file") && bs->open_flags & BDRV_O_RDWR) { |
| 4222 | + if (snapshot_flags) { |
| 4223 | + error_setg(errp, "Syx snapshots should not be used with any QEMU snapshot option"); |
| 4224 | + goto close_and_fail; |
| 4225 | + } |
| 4226 | + |
| 4227 | + scc_options = qdict_new(); |
| 4228 | + bdrv_syx_cow_cache_options(&scc_flags, scc_options, |
| 4229 | + flags, options); |
| 4230 | + |
| 4231 | + // qdict_put_bool(options, BDRV_OPT_READ_ONLY, true); |
| 4232 | + // bs->open_flags &= ~BDRV_O_RDWR; |
| 4233 | + |
| 4234 | + attach_syx_continue = true; |
| 4235 | + } |
| 4236 | +//// --- End LibAFL code --- |
| 4237 | + |
4155 | 4238 | /* Open the image */ |
4156 | 4239 | ret = bdrv_open_common(bs, file, options, &local_err); |
4157 | 4240 | if (ret < 0) { |
@@ -4221,6 +4304,17 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, |
4221 | 4304 | bs = snapshot_bs; |
4222 | 4305 | } |
4223 | 4306 |
|
| 4307 | + if (attach_syx_continue) { |
| 4308 | + BlockDriverState* scc_bs; |
| 4309 | + scc_bs = bdrv_append_syx_cow_cache(bs, scc_flags, scc_options, &local_err); |
| 4310 | + scc_options = NULL; |
| 4311 | + if (local_err) { |
| 4312 | + goto close_and_fail; |
| 4313 | + } |
| 4314 | + bdrv_unref(bs); |
| 4315 | + bs = scc_bs; |
| 4316 | + } |
| 4317 | + |
4224 | 4318 | return bs; |
4225 | 4319 |
|
4226 | 4320 | fail: |
|
0 commit comments