diff options
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch | 73 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch | 132 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch | 34 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch | 80 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu_2.4.0.bb | 4 |
5 files changed, 323 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch new file mode 100644 index 0000000000..07582ef929 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | From 46aff2c7e91ef9f372ad38ba5e90c42b9b27ac75 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Gerd Hoffmann <kraxel@redhat.com> | ||
| 3 | Date: Tue, 26 Apr 2016 14:11:34 +0200 | ||
| 4 | Subject: [PATCH 1/4] vga: add vbe_enabled() helper | ||
| 5 | |||
| 6 | Makes code a bit easier to read. | ||
| 7 | |||
| 8 | Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 9 | Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> | ||
| 10 | |||
| 11 | Upstream-Status: Backport | ||
| 12 | CVE: CVE-2016-3712 patch1 | ||
| 13 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
| 14 | |||
| 15 | --- | ||
| 16 | hw/display/vga.c | 13 +++++++++---- | ||
| 17 | 1 file changed, 9 insertions(+), 4 deletions(-) | ||
| 18 | |||
| 19 | diff --git a/hw/display/vga.c b/hw/display/vga.c | ||
| 20 | index 442fee9..cc1a682 100644 | ||
| 21 | --- a/hw/display/vga.c | ||
| 22 | +++ b/hw/display/vga.c | ||
| 23 | @@ -140,6 +140,11 @@ static uint32_t expand4[256]; | ||
| 24 | static uint16_t expand2[256]; | ||
| 25 | static uint8_t expand4to8[16]; | ||
| 26 | |||
| 27 | +static inline bool vbe_enabled(VGACommonState *s) | ||
| 28 | +{ | ||
| 29 | + return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | static void vga_update_memory_access(VGACommonState *s) | ||
| 33 | { | ||
| 34 | hwaddr base, offset, size; | ||
| 35 | @@ -562,7 +567,7 @@ static void vbe_fixup_regs(VGACommonState *s) | ||
| 36 | uint16_t *r = s->vbe_regs; | ||
| 37 | uint32_t bits, linelength, maxy, offset; | ||
| 38 | |||
| 39 | - if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { | ||
| 40 | + if (!vbe_enabled(s)) { | ||
| 41 | /* vbe is turned off -- nothing to do */ | ||
| 42 | return; | ||
| 43 | } | ||
| 44 | @@ -1056,7 +1061,7 @@ static void vga_get_offsets(VGACommonState *s, | ||
| 45 | { | ||
| 46 | uint32_t start_addr, line_offset, line_compare; | ||
| 47 | |||
| 48 | - if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { | ||
| 49 | + if (vbe_enabled(s)) { | ||
| 50 | line_offset = s->vbe_line_offset; | ||
| 51 | start_addr = s->vbe_start_addr; | ||
| 52 | line_compare = 65535; | ||
| 53 | @@ -1381,7 +1386,7 @@ static int vga_get_bpp(VGACommonState *s) | ||
| 54 | { | ||
| 55 | int ret; | ||
| 56 | |||
| 57 | - if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { | ||
| 58 | + if (vbe_enabled(s)) { | ||
| 59 | ret = s->vbe_regs[VBE_DISPI_INDEX_BPP]; | ||
| 60 | } else { | ||
| 61 | ret = 0; | ||
| 62 | @@ -1393,7 +1398,7 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight) | ||
| 63 | { | ||
| 64 | int width, height; | ||
| 65 | |||
| 66 | - if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { | ||
| 67 | + if (vbe_enabled(s)) { | ||
| 68 | width = s->vbe_regs[VBE_DISPI_INDEX_XRES]; | ||
| 69 | height = s->vbe_regs[VBE_DISPI_INDEX_YRES]; | ||
| 70 | } else { | ||
| 71 | -- | ||
| 72 | 2.7.4 | ||
| 73 | |||
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch new file mode 100644 index 0000000000..11330d766d --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch | |||
| @@ -0,0 +1,132 @@ | |||
| 1 | From 2f2f74e87c15e830f5a4dda7a166effcab5047ec Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Gerd Hoffmann <kraxel@redhat.com> | ||
| 3 | Date: Tue, 26 Apr 2016 15:24:18 +0200 | ||
| 4 | Subject: [PATCH 2/4] vga: factor out vga register setup | ||
| 5 | |||
| 6 | When enabling vbe mode qemu will setup a bunch of vga registers to make | ||
| 7 | sure the vga emulation operates in correct mode for a linear | ||
| 8 | framebuffer. Move that code to a separate function so we can call it | ||
| 9 | from other places too. | ||
| 10 | |||
| 11 | Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 12 | Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> | ||
| 13 | |||
| 14 | Upstream-Status: Backport | ||
| 15 | CVE: CVE-2016-3712 patch2 | ||
| 16 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
| 17 | |||
| 18 | --- | ||
| 19 | hw/display/vga.c | 78 ++++++++++++++++++++++++++++++++------------------------ | ||
| 20 | 1 file changed, 44 insertions(+), 34 deletions(-) | ||
| 21 | |||
| 22 | diff --git a/hw/display/vga.c b/hw/display/vga.c | ||
| 23 | index cc1a682..f1987e3 100644 | ||
| 24 | --- a/hw/display/vga.c | ||
| 25 | +++ b/hw/display/vga.c | ||
| 26 | @@ -642,6 +642,49 @@ static void vbe_fixup_regs(VGACommonState *s) | ||
| 27 | s->vbe_start_addr = offset / 4; | ||
| 28 | } | ||
| 29 | |||
| 30 | +/* we initialize the VGA graphic mode */ | ||
| 31 | +static void vbe_update_vgaregs(VGACommonState *s) | ||
| 32 | +{ | ||
| 33 | + int h, shift_control; | ||
| 34 | + | ||
| 35 | + if (!vbe_enabled(s)) { | ||
| 36 | + /* vbe is turned off -- nothing to do */ | ||
| 37 | + return; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + /* graphic mode + memory map 1 */ | ||
| 41 | + s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 | | ||
| 42 | + VGA_GR06_GRAPHICS_MODE; | ||
| 43 | + s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */ | ||
| 44 | + s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3; | ||
| 45 | + /* width */ | ||
| 46 | + s->cr[VGA_CRTC_H_DISP] = | ||
| 47 | + (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; | ||
| 48 | + /* height (only meaningful if < 1024) */ | ||
| 49 | + h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; | ||
| 50 | + s->cr[VGA_CRTC_V_DISP_END] = h; | ||
| 51 | + s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) | | ||
| 52 | + ((h >> 7) & 0x02) | ((h >> 3) & 0x40); | ||
| 53 | + /* line compare to 1023 */ | ||
| 54 | + s->cr[VGA_CRTC_LINE_COMPARE] = 0xff; | ||
| 55 | + s->cr[VGA_CRTC_OVERFLOW] |= 0x10; | ||
| 56 | + s->cr[VGA_CRTC_MAX_SCAN] |= 0x40; | ||
| 57 | + | ||
| 58 | + if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { | ||
| 59 | + shift_control = 0; | ||
| 60 | + s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ | ||
| 61 | + } else { | ||
| 62 | + shift_control = 2; | ||
| 63 | + /* set chain 4 mode */ | ||
| 64 | + s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; | ||
| 65 | + /* activate all planes */ | ||
| 66 | + s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; | ||
| 67 | + } | ||
| 68 | + s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) | | ||
| 69 | + (shift_control << 5); | ||
| 70 | + s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */ | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr) | ||
| 74 | { | ||
| 75 | VGACommonState *s = opaque; | ||
| 76 | @@ -728,52 +771,19 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) | ||
| 77 | case VBE_DISPI_INDEX_ENABLE: | ||
| 78 | if ((val & VBE_DISPI_ENABLED) && | ||
| 79 | !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { | ||
| 80 | - int h, shift_control; | ||
| 81 | |||
| 82 | s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0; | ||
| 83 | s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; | ||
| 84 | s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; | ||
| 85 | s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED; | ||
| 86 | vbe_fixup_regs(s); | ||
| 87 | + vbe_update_vgaregs(s); | ||
| 88 | |||
| 89 | /* clear the screen */ | ||
| 90 | if (!(val & VBE_DISPI_NOCLEARMEM)) { | ||
| 91 | memset(s->vram_ptr, 0, | ||
| 92 | s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); | ||
| 93 | } | ||
| 94 | - | ||
| 95 | - /* we initialize the VGA graphic mode */ | ||
| 96 | - /* graphic mode + memory map 1 */ | ||
| 97 | - s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 | | ||
| 98 | - VGA_GR06_GRAPHICS_MODE; | ||
| 99 | - s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */ | ||
| 100 | - s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3; | ||
| 101 | - /* width */ | ||
| 102 | - s->cr[VGA_CRTC_H_DISP] = | ||
| 103 | - (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; | ||
| 104 | - /* height (only meaningful if < 1024) */ | ||
| 105 | - h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; | ||
| 106 | - s->cr[VGA_CRTC_V_DISP_END] = h; | ||
| 107 | - s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) | | ||
| 108 | - ((h >> 7) & 0x02) | ((h >> 3) & 0x40); | ||
| 109 | - /* line compare to 1023 */ | ||
| 110 | - s->cr[VGA_CRTC_LINE_COMPARE] = 0xff; | ||
| 111 | - s->cr[VGA_CRTC_OVERFLOW] |= 0x10; | ||
| 112 | - s->cr[VGA_CRTC_MAX_SCAN] |= 0x40; | ||
| 113 | - | ||
| 114 | - if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { | ||
| 115 | - shift_control = 0; | ||
| 116 | - s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ | ||
| 117 | - } else { | ||
| 118 | - shift_control = 2; | ||
| 119 | - /* set chain 4 mode */ | ||
| 120 | - s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; | ||
| 121 | - /* activate all planes */ | ||
| 122 | - s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; | ||
| 123 | - } | ||
| 124 | - s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) | | ||
| 125 | - (shift_control << 5); | ||
| 126 | - s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */ | ||
| 127 | } else { | ||
| 128 | s->bank_offset = 0; | ||
| 129 | } | ||
| 130 | -- | ||
| 131 | 2.7.4 | ||
| 132 | |||
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch new file mode 100644 index 0000000000..3e6644d942 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | From a6e5e5dd4bbc022acbd10ebcf415a6a57418d09e Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Gerd Hoffmann <kraxel@redhat.com> | ||
| 3 | Date: Tue, 26 Apr 2016 15:39:22 +0200 | ||
| 4 | Subject: [PATCH 3/4] vga: update vga register setup on vbe changes | ||
| 5 | |||
| 6 | Call the new vbe_update_vgaregs() function on vbe configuration | ||
| 7 | changes, to make sure vga registers are up-to-date. | ||
| 8 | |||
| 9 | Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 10 | Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> | ||
| 11 | |||
| 12 | Upstream-Status: Backport | ||
| 13 | CVE: CVE-2016-3712 patch3 | ||
| 14 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
| 15 | |||
| 16 | --- | ||
| 17 | hw/display/vga.c | 1 + | ||
| 18 | 1 file changed, 1 insertion(+) | ||
| 19 | |||
| 20 | diff --git a/hw/display/vga.c b/hw/display/vga.c | ||
| 21 | index f1987e3..10ac7df 100644 | ||
| 22 | --- a/hw/display/vga.c | ||
| 23 | +++ b/hw/display/vga.c | ||
| 24 | @@ -761,6 +761,7 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) | ||
| 25 | case VBE_DISPI_INDEX_Y_OFFSET: | ||
| 26 | s->vbe_regs[s->vbe_index] = val; | ||
| 27 | vbe_fixup_regs(s); | ||
| 28 | + vbe_update_vgaregs(s); | ||
| 29 | break; | ||
| 30 | case VBE_DISPI_INDEX_BANK: | ||
| 31 | val &= s->vbe_bank_mask; | ||
| 32 | -- | ||
| 33 | 2.7.4 | ||
| 34 | |||
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch new file mode 100644 index 0000000000..96e980a58d --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | From 44b86aa32e4147c727fadd9a0f0bc503a5dedb72 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Gerd Hoffmann <kraxel@redhat.com> | ||
| 3 | Date: Tue, 26 Apr 2016 14:48:06 +0200 | ||
| 4 | Subject: [PATCH 4/4] vga: make sure vga register setup for vbe stays intact | ||
| 5 | (CVE-2016-3712). | ||
| 6 | |||
| 7 | Call vbe_update_vgaregs() when the guest touches GFX, SEQ or CRT | ||
| 8 | registers, to make sure the vga registers will always have the | ||
| 9 | values needed by vbe mode. This makes sure the sanity checks | ||
| 10 | applied by vbe_fixup_regs() are effective. | ||
| 11 | |||
| 12 | Without this guests can muck with shift_control, can turn on planar | ||
| 13 | vga modes or text mode emulation while VBE is active, making qemu | ||
| 14 | take code paths meant for CGA compatibility, but with the very | ||
| 15 | large display widths and heigts settable using VBE registers. | ||
| 16 | |||
| 17 | Which is good for one or another buffer overflow. Not that | ||
| 18 | critical as they typically read overflows happening somewhere | ||
| 19 | in the display code. So guests can DoS by crashing qemu with a | ||
| 20 | segfault, but it is probably not possible to break out of the VM. | ||
| 21 | |||
| 22 | Fixes: CVE-2016-3712 | ||
| 23 | Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com> | ||
| 24 | Reported-by: P J P <ppandit@redhat.com> | ||
| 25 | Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 26 | Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> | ||
| 27 | |||
| 28 | Upstream-Status: Backport | ||
| 29 | CVE: CVE-2016-3712 patch4 ( the fix) | ||
| 30 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
| 31 | |||
| 32 | --- | ||
| 33 | hw/display/vga.c | 6 ++++++ | ||
| 34 | 1 file changed, 6 insertions(+) | ||
| 35 | |||
| 36 | diff --git a/hw/display/vga.c b/hw/display/vga.c | ||
| 37 | index 10ac7df..679070e 100644 | ||
| 38 | --- a/hw/display/vga.c | ||
| 39 | +++ b/hw/display/vga.c | ||
| 40 | @@ -140,6 +140,8 @@ static uint32_t expand4[256]; | ||
| 41 | static uint16_t expand2[256]; | ||
| 42 | static uint8_t expand4to8[16]; | ||
| 43 | |||
| 44 | +static void vbe_update_vgaregs(VGACommonState *s); | ||
| 45 | + | ||
| 46 | static inline bool vbe_enabled(VGACommonState *s) | ||
| 47 | { | ||
| 48 | return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; | ||
| 49 | @@ -482,6 +484,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 50 | printf("vga: write SR%x = 0x%02x\n", s->sr_index, val); | ||
| 51 | #endif | ||
| 52 | s->sr[s->sr_index] = val & sr_mask[s->sr_index]; | ||
| 53 | + vbe_update_vgaregs(s); | ||
| 54 | if (s->sr_index == VGA_SEQ_CLOCK_MODE) { | ||
| 55 | s->update_retrace_info(s); | ||
| 56 | } | ||
| 57 | @@ -513,6 +516,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 58 | printf("vga: write GR%x = 0x%02x\n", s->gr_index, val); | ||
| 59 | #endif | ||
| 60 | s->gr[s->gr_index] = val & gr_mask[s->gr_index]; | ||
| 61 | + vbe_update_vgaregs(s); | ||
| 62 | vga_update_memory_access(s); | ||
| 63 | break; | ||
| 64 | case VGA_CRT_IM: | ||
| 65 | @@ -531,10 +535,12 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 66 | if (s->cr_index == VGA_CRTC_OVERFLOW) { | ||
| 67 | s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | | ||
| 68 | (val & 0x10); | ||
| 69 | + vbe_update_vgaregs(s); | ||
| 70 | } | ||
| 71 | return; | ||
| 72 | } | ||
| 73 | s->cr[s->cr_index] = val; | ||
| 74 | + vbe_update_vgaregs(s); | ||
| 75 | |||
| 76 | switch(s->cr_index) { | ||
| 77 | case VGA_CRTC_H_TOTAL: | ||
| 78 | -- | ||
| 79 | 2.7.4 | ||
| 80 | |||
diff --git a/meta/recipes-devtools/qemu/qemu_2.4.0.bb b/meta/recipes-devtools/qemu/qemu_2.4.0.bb index f32424200d..85dd39eccb 100644 --- a/meta/recipes-devtools/qemu/qemu_2.4.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.4.0.bb | |||
| @@ -21,6 +21,10 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ | |||
| 21 | file://CVE-2016-2197.patch \ | 21 | file://CVE-2016-2197.patch \ |
| 22 | file://CVE-2016-2198.patch \ | 22 | file://CVE-2016-2198.patch \ |
| 23 | file://CVE-2016-3710.patch \ | 23 | file://CVE-2016-3710.patch \ |
| 24 | file://CVE-2016-3712_p1.patch \ | ||
| 25 | file://CVE-2016-3712_p2.patch \ | ||
| 26 | file://CVE-2016-3712_p3.patch \ | ||
| 27 | file://CVE-2016-3712_p4.patch \ | ||
| 24 | " | 28 | " |
| 25 | SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" | 29 | SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" |
| 26 | SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4" | 30 | SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4" |
