diff options
-rw-r--r-- | config-arm-generic | 1 | ||||
-rw-r--r-- | config-arm64 | 3 | ||||
-rw-r--r-- | config-armv7-generic | 1 | ||||
-rw-r--r-- | drm-i915-Acquire-audio-powerwell-for-HD-Audio-regist.patch | 64 | ||||
-rw-r--r-- | gitrev | 2 | ||||
-rw-r--r-- | kernel.spec | 26 | ||||
-rw-r--r-- | openstack_fix.patch | 53 | ||||
-rw-r--r-- | qxl-reapply-cursor-after-SetCrtc-calls.patch | 308 | ||||
-rw-r--r-- | sources | 2 | ||||
-rw-r--r-- | tcp-fix-use-after-free-in-tcp_xmit_retransmit_queue.patch | 46 |
10 files changed, 358 insertions, 148 deletions
diff --git a/config-arm-generic b/config-arm-generic index e4e705670..bae4c1640 100644 --- a/config-arm-generic +++ b/config-arm-generic @@ -198,6 +198,7 @@ CONFIG_PCI_TEGRA=y CONFIG_AHCI_TEGRA=m CONFIG_MMC_SDHCI_TEGRA=m CONFIG_TEGRA_WATCHDOG=m +CONFIG_GPIO_TEGRA=y CONFIG_I2C_TEGRA=m CONFIG_SPI_TEGRA114=m CONFIG_PWM_TEGRA=m diff --git a/config-arm64 b/config-arm64 index 5ec79ca83..591a60a06 100644 --- a/config-arm64 +++ b/config-arm64 @@ -183,8 +183,7 @@ CONFIG_MFD_MAX77620=y CONFIG_PINCTRL_MAX77620=m CONFIG_REGULATOR_MAX77620=m CONFIG_GPIO_MAX77620=m -# CONFIG_GPIO_TEGRA is not set -# CONFIG_TEGRA_ACONNECT is not set +CONFIG_TEGRA_ACONNECT=y # AllWinner CONFIG_MACH_SUN50I=y diff --git a/config-armv7-generic b/config-armv7-generic index 9a407c349..a8f26d36d 100644 --- a/config-armv7-generic +++ b/config-armv7-generic @@ -390,7 +390,6 @@ CONFIG_SND_SOC_TEGRA_RT5677=m CONFIG_AD525X_DPOT=m CONFIG_AD525X_DPOT_I2C=m CONFIG_AD525X_DPOT_SPI=m -# CONFIG_GPIO_TEGRA is not set # Jetson TK1 CONFIG_PINCTRL_AS3722=y diff --git a/drm-i915-Acquire-audio-powerwell-for-HD-Audio-regist.patch b/drm-i915-Acquire-audio-powerwell-for-HD-Audio-regist.patch deleted file mode 100644 index a5dc6f3a2..000000000 --- a/drm-i915-Acquire-audio-powerwell-for-HD-Audio-regist.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 74f829a6e44fe217b6161f8935524fc807be0648 Mon Sep 17 00:00:00 2001 -From: Chris Wilson <chris@chris-wilson.co.uk> -Date: Sat, 9 Jul 2016 11:01:20 +0100 -Subject: [PATCH] drm/i915: Acquire audio powerwell for HD-Audio registers - -On Haswell/Broadwell, the HD-Audio block is inside the HDMI/display -power well and so the sna-hda audio codec acquires the display power -well while it is operational. However, Skylake separates the powerwells -again, but yet we still need the audio powerwell to setup the registers. -(But then the hardware uses those registers even while powered off???) - -v2: Grab both rpm wakelock and audio wakelock - -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96214 -Fixes: 03b135cebc47 "ALSA: hda - remove dependency on i915 power well for SKL") -Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> -Cc: Libin Yang <libin.yang@intel.com> -Cc: Takashi Iwai <tiwai@suse.de> -Cc: Marius Vlad <marius.c.vlad@intel.com> ---- - drivers/gpu/drm/i915/intel_audio.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c -index 5d5f6bc10e85..948a7a52e3f8 100644 ---- a/drivers/gpu/drm/i915/intel_audio.c -+++ b/drivers/gpu/drm/i915/intel_audio.c -@@ -600,6 +600,8 @@ static void i915_audio_component_codec_wake_override(struct device *dev, - if (!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv)) - return; - -+ i915_audio_component_get_power(dev); -+ - /* - * Enable/disable generating the codec wake signal, overriding the - * internal logic to generate the codec wake to controller. -@@ -615,6 +617,8 @@ static void i915_audio_component_codec_wake_override(struct device *dev, - I915_WRITE(HSW_AUD_CHICKENBIT, tmp); - usleep_range(1000, 1500); - } -+ -+ i915_audio_component_put_power(dev); - } - - /* Get CDCLK in kHz */ -@@ -648,6 +652,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev, - !IS_HASWELL(dev_priv)) - return 0; - -+ i915_audio_component_get_power(dev); - mutex_lock(&dev_priv->av_mutex); - /* 1. get the pipe */ - intel_encoder = dev_priv->dig_port_map[port]; -@@ -698,6 +703,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev, - - unlock: - mutex_unlock(&dev_priv->av_mutex); -+ i915_audio_component_put_power(dev); - return err; - } - --- -2.8.1 - @@ -1 +1 @@ -ae5d68be42cd0275a91faf56d2b527b448c3caf4 +6040e57658eee6eb1315a26119101ca832d1f854 diff --git a/kernel.spec b/kernel.spec index 4f97c2193..5610ec4c7 100644 --- a/kernel.spec +++ b/kernel.spec @@ -77,7 +77,7 @@ Summary: The Linux kernel # The rc snapshot level %define rcrev 2 # The git snapshot level -%define gitrev 1 +%define gitrev 4 # Set rpm version accordingly %define rpmversion 4.%{upstream_sublevel}.0 %endif @@ -616,15 +616,12 @@ Patch508: kexec-uefi-copy-secure_boot-flag-in-boot-params.patch #CVE-2016-3134 rhbz 1317383 1317384 Patch665: netfilter-x_tables-deal-with-bogus-nextoffset-values.patch -# https://lists.fedoraproject.org/archives/list/kernel@lists.fedoraproject.org/message/A4YCP7OGMX6JLFT5V44H57GOMAQLC3M4/ -Patch839: drm-i915-Acquire-audio-powerwell-for-HD-Audio-regist.patch - -#rhbz 1361414 -Patch841: openstack_fix.patch - #rhbz 1200901 (There should be something better upstream at some point) Patch842: qxl-reapply-cursor-after-SetCrtc-calls.patch +#CVE-2016-6828 rhbz 1367091,1367092 +Patch843: tcp-fix-use-after-free-in-tcp_xmit_retransmit_queue.patch + # END OF PATCH DEFINITIONS %endif @@ -2162,6 +2159,19 @@ fi # # %changelog +* Fri Aug 19 2016 Justin M. Forbes <jforbes@fedoraproject.org> - 4.8.0-0.rc2.git4.1 +- Linux v4.8-rc2-348-g6040e57 + +* Fri Aug 19 2016 Justin M. Forbes <jforbes@fedoraproject.org> - 4.8.0-0.rc2.git3.1 +- Linux v4.8-rc2-232-g3408fef + +* Fri Aug 19 2016 Peter Robinson <pbrobinson@fedoraproject.org> +- Minor Tegra changes + +* Wed Aug 17 2016 Justin M. Forbes <jforbes@fedoraproject.org> - 4.8.0-0.rc2.git2.1 +- Linux v4.8-rc2-42-g5ff132c +- CVE-2016-6828 tcp fix use after free in tcp_xmit_retransmit_queue (rhbz 1367091 1367092) + * Tue Aug 16 2016 Justin M. Forbes <jforbes@fedoraproject.org> - 4.8.0-0.rc2.git1.1 - Linux v4.8-rc2-17-gae5d68b - Add patch for qxl cursor bug (rhbz 1200901) @@ -2280,7 +2290,7 @@ fi - Reenable debugging options. * Tue Jul 12 2016 Josh Boyer <jwboyer@fedoraproject.org> -- CVE-2016-5389 CVE-2016-5969 tcp challenge ack info leak (rhbz 1354708 1355615) +- CVE-2016-5389 CVE-2016-5696 tcp challenge ack info leak (rhbz 1354708 1355615) * Mon Jul 11 2016 Justin M. Forbes <jforbes@fedoraproject.org> - 4.7.0-0.rc7.git0.1 - Disable debugging options. diff --git a/openstack_fix.patch b/openstack_fix.patch deleted file mode 100644 index a967c350e..000000000 --- a/openstack_fix.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 5ef9f289c4e698054e5687edb54f0da3cdc9173a Mon Sep 17 00:00:00 2001 -From: Ian Wienand <iwienand@redhat.com> -Date: Wed, 3 Aug 2016 15:44:57 +1000 -Subject: OVS: Ignore negative headroom value - -net_device->ndo_set_rx_headroom (introduced in -871b642adebe300be2e50aa5f65a418510f636ec) says - - "Setting a negtaive value reset the rx headroom - to the default value". - -It seems that the OVS implementation in -3a927bc7cf9d0fbe8f4a8189dd5f8440228f64e7 overlooked this and sets -dev->needed_headroom unconditionally. - -This doesn't have an immediate effect, but can mess up later -LL_RESERVED_SPACE calculations, such as done in -net/ipv6/mcast.c:mld_newpack. For reference, this issue was found -from a skb_panic raised there after the length calculations had given -the wrong result. - -Note the other current users of this interface -(drivers/net/tun.c:tun_set_headroom and -drivers/net/veth.c:veth_set_rx_headroom) are both checking this -correctly thus need no modification. - -Thanks to Ben for some pointers from the crash dumps! - -Cc: Benjamin Poirier <bpoirier@suse.com> -Cc: Paolo Abeni <pabeni@redhat.com> -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1361414 -Signed-off-by: Ian Wienand <iwienand@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - net/openvswitch/vport-internal_dev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c -index 434e04c..95c3614 100644 ---- a/net/openvswitch/vport-internal_dev.c -+++ b/net/openvswitch/vport-internal_dev.c -@@ -140,7 +140,7 @@ internal_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) - - static void internal_set_rx_headroom(struct net_device *dev, int new_hr) - { -- dev->needed_headroom = new_hr; -+ dev->needed_headroom = new_hr < 0 ? 0 : new_hr; - } - - static const struct net_device_ops internal_dev_netdev_ops = { --- -cgit v0.12 - diff --git a/qxl-reapply-cursor-after-SetCrtc-calls.patch b/qxl-reapply-cursor-after-SetCrtc-calls.patch index 2787cf7d1..d70acc4eb 100644 --- a/qxl-reapply-cursor-after-SetCrtc-calls.patch +++ b/qxl-reapply-cursor-after-SetCrtc-calls.patch @@ -1,4 +1,4 @@ -From 99ea1a3c387899424fb5c6b17baa56e8d68a3484 Mon Sep 17 00:00:00 2001 +From 92777b4dfc3920edb449d0be6ead65d8460653cc Mon Sep 17 00:00:00 2001 From: Ray Strode <rstrode@redhat.com> Date: Tue, 12 May 2015 12:51:18 -0400 Subject: [PATCH] drm/qxl: reapply cursor after SetCrtc calls @@ -23,21 +23,102 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1200901 2 files changed, 99 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c -index 3aef127..fcc5f3b 100644 +index 3aef127..34ab444 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c -@@ -211,6 +211,7 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc) +@@ -184,60 +184,61 @@ static struct mode_size { + {1440, 900}, + {1400, 1050}, + {1680, 1050}, + {1600, 1200}, + {1920, 1080}, + {1920, 1200} + }; + + static int qxl_add_common_modes(struct drm_connector *connector, + unsigned pwidth, + unsigned pheight) + { + struct drm_device *dev = connector->dev; + struct drm_display_mode *mode = NULL; + int i; + for (i = 0; i < ARRAY_SIZE(common_modes); i++) { + mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, + 60, false, false, false); + if (common_modes[i].w == pwidth && common_modes[i].h == pheight) + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + } + return i - 1; + } + + static void qxl_crtc_destroy(struct drm_crtc *crtc) + { struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc); - + drm_crtc_cleanup(crtc); + kfree(qxl_crtc->cursor); kfree(qxl_crtc); } - -@@ -296,6 +297,92 @@ qxl_hide_cursor(struct qxl_device *qdev) + + static int qxl_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) + { + struct drm_device *dev = crtc->dev; + struct qxl_device *qdev = dev->dev_private; + struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb); + struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb); + struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj); + struct qxl_bo *bo = gem_to_qxl_bo(qfb_src->obj); + unsigned long flags; + struct drm_clip_rect norect = { + .x1 = 0, + .y1 = 0, + .x2 = fb->width, + .y2 = fb->height + }; + int inc = 1; + int one_clip_rect = 1; + int ret = 0; + + crtc->primary->fb = fb; + bo_old->is_primary = false; + bo->is_primary = true; + + ret = qxl_bo_reserve(bo, false); +@@ -269,60 +270,145 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc, return 0; } - + + static int + qxl_hide_cursor(struct qxl_device *qdev) + { + struct qxl_release *release; + struct qxl_cursor_cmd *cmd; + int ret; + + ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), QXL_RELEASE_CURSOR_CMD, + &release, NULL); + if (ret) + return ret; + + ret = qxl_release_reserve_list(release, true); + if (ret) { + qxl_release_free(qdev, release); + return ret; + } + + cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); + cmd->type = QXL_CURSOR_HIDE; + qxl_release_unmap(qdev, release, &cmd->release_info); + + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); + qxl_release_fence_buffer_objects(release); + return 0; + } + +static int qxl_crtc_stash_cursor(struct drm_crtc *crtc, + struct qxl_cursor *cursor) +{ @@ -100,12 +181,11 @@ index 3aef127..fcc5f3b 100644 + + cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); + cmd->type = QXL_CURSOR_SET; -+ cmd->u.set.position.x = qcrtc->cur_x; -+ cmd->u.set.position.y = qcrtc->cur_y; ++ cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; ++ cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; + + cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0); + -+ + cmd->u.set.visible = 1; + qxl_release_unmap(qdev, release, &cmd->release_info); + @@ -127,10 +207,64 @@ index 3aef127..fcc5f3b 100644 static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, -@@ -370,6 +457,12 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, - + uint32_t width, + uint32_t height, int32_t hot_x, int32_t hot_y) + { + struct drm_device *dev = crtc->dev; + struct qxl_device *qdev = dev->dev_private; + struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); + struct drm_gem_object *obj; + struct qxl_cursor *cursor; + struct qxl_cursor_cmd *cmd; + struct qxl_bo *cursor_bo, *user_bo; + struct qxl_release *release; + void *user_ptr; + + int size = 64*64*4; + int ret = 0; + if (!handle) + return qxl_hide_cursor(qdev); + + obj = drm_gem_object_lookup(file_priv, handle); + if (!obj) { + DRM_ERROR("cannot find cursor object\n"); + return -ENOENT; + } + + user_bo = gem_to_qxl_bo(obj); + + ret = qxl_bo_reserve(user_bo, false); +@@ -343,60 +429,66 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, + &release, NULL); + if (ret) + goto out_kunmap; + + ret = qxl_alloc_bo_reserved(qdev, release, sizeof(struct qxl_cursor) + size, + &cursor_bo); + if (ret) + goto out_free_release; + + ret = qxl_release_reserve_list(release, false); + if (ret) + goto out_free_bo; + + ret = qxl_bo_kmap(cursor_bo, (void **)&cursor); + if (ret) + goto out_backoff; + + cursor->header.unique = 0; + cursor->header.type = SPICE_CURSOR_TYPE_ALPHA; + cursor->header.width = 64; + cursor->header.height = 64; + cursor->header.hot_spot_x = hot_x; + cursor->header.hot_spot_y = hot_y; + cursor->data_size = size; + cursor->chunk.next_chunk = 0; + cursor->chunk.prev_chunk = 0; + cursor->chunk.data_size = size; + memcpy(cursor->chunk.data, user_ptr, size); - + + ret = qxl_crtc_stash_cursor(crtc, cursor); + if (ret) { + DRM_ERROR("cannot save cursor, may be lost on next mode set\n"); @@ -138,9 +272,63 @@ index 3aef127..fcc5f3b 100644 + } + qxl_bo_kunmap(cursor_bo); - + qxl_bo_kunmap(user_bo); -@@ -655,6 +748,12 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, + + qcrtc->cur_x += qcrtc->hot_spot_x - hot_x; + qcrtc->cur_y += qcrtc->hot_spot_y - hot_y; + qcrtc->hot_spot_x = hot_x; + qcrtc->hot_spot_y = hot_y; + + cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); + cmd->type = QXL_CURSOR_SET; + cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; + cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; + + cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0); + + cmd->u.set.visible = 1; + qxl_release_unmap(qdev, release, &cmd->release_info); + + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); + qxl_release_fence_buffer_objects(release); + + /* finish with the userspace bo */ + ret = qxl_bo_reserve(user_bo, false); + if (!ret) { + qxl_bo_unpin(user_bo); + qxl_bo_unreserve(user_bo); + } + drm_gem_object_unreference_unlocked(obj); + +@@ -628,60 +720,66 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, + x, y, + mode->hdisplay, mode->vdisplay, + adjusted_mode->hdisplay, + adjusted_mode->vdisplay); + + if (bo->is_primary == false) + recreate_primary = true; + + if (bo->surf.stride * bo->surf.height > qdev->vram_size) { + DRM_ERROR("Mode doesn't fit in vram size (vgamem)"); + return -EINVAL; + } + + ret = qxl_bo_reserve(bo, false); + if (ret != 0) + return ret; + ret = qxl_bo_pin(bo, bo->type, NULL); + if (ret != 0) { + qxl_bo_unreserve(bo); + return -EINVAL; + } + qxl_bo_unreserve(bo); + if (recreate_primary) { + qxl_io_destroy_primary(qdev); + qxl_io_log(qdev, + "recreate primary: %dx%d,%d,%d\n", + bo->surf.width, bo->surf.height, bo->surf.stride, bo->surf.format); qxl_io_create_primary(qdev, 0, bo); bo->is_primary = true; @@ -151,17 +339,101 @@ index 3aef127..fcc5f3b 100644 + ret = 0; + } } - + if (bo->is_primary) { + DRM_DEBUG_KMS("setting surface_id to 0 for primary surface %d on crtc %d\n", bo->surface_id, qcrtc->index); + surf_id = 0; + } else { + surf_id = bo->surface_id; + } + + if (old_bo && old_bo != bo) { + old_bo->is_primary = false; + ret = qxl_bo_reserve(old_bo, false); + qxl_bo_unpin(old_bo); + qxl_bo_unreserve(old_bo); + } + + qxl_monitors_config_set(qdev, qcrtc->index, x, y, + mode->hdisplay, + mode->vdisplay, surf_id); + return 0; + } + + static void qxl_crtc_prepare(struct drm_crtc *crtc) + { + DRM_DEBUG("current: %dx%d+%d+%d (%d).\n", + crtc->mode.hdisplay, crtc->mode.vdisplay, + crtc->x, crtc->y, crtc->enabled); + } + + static void qxl_crtc_commit(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 8e633ca..6b63c54 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h -@@ -137,6 +137,7 @@ struct qxl_crtc { +@@ -110,60 +110,61 @@ struct qxl_bo { + void *kptr; + int type; + + /* Constant after initialization */ + struct drm_gem_object gem_base; + bool is_primary; /* is this now a primary surface */ + bool hw_surf_alloc; + struct qxl_surface surf; + uint32_t surface_id; + struct qxl_release *surf_create; + }; + #define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base) + #define to_qxl_bo(tobj) container_of((tobj), struct qxl_bo, tbo) + + struct qxl_gem { + struct mutex mutex; + struct list_head objects; + }; + + struct qxl_bo_list { + struct ttm_validate_buffer tv; + }; + + struct qxl_crtc { + struct drm_crtc base; + int index; + int cur_x; int cur_y; int hot_spot_x; int hot_spot_y; + struct qxl_cursor *cursor; }; - + struct qxl_output { + int index; + struct drm_connector base; + struct drm_encoder enc; + }; + + struct qxl_framebuffer { + struct drm_framebuffer base; + struct drm_gem_object *obj; + }; + + #define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base) + #define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base) + #define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc) + #define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base) + + struct qxl_mman { + struct ttm_bo_global_ref bo_global_ref; + struct drm_global_reference mem_global_ref; + bool mem_global_referenced; + struct ttm_bo_device bdev; + }; + + struct qxl_mode_info { + int num_modes; + struct qxl_mode *modes; + bool mode_config_initialized; + +-- +2.7.4 + @@ -1,4 +1,4 @@ 5276563eb1f39a048e4a8a887408c031 linux-4.7.tar.xz fe259c02c75eec61d1aa4b1211f3c853 perf-man-4.7.tar.gz 0d6c6c82846042198bc6ac4260a88b03 patch-4.8-rc2.xz -c2585d3b7786c38e36218ef608ed9b16 patch-4.8-rc2-git1.xz +2ed5e41d0ce36c5042b564d493d8865e patch-4.8-rc2-git4.xz diff --git a/tcp-fix-use-after-free-in-tcp_xmit_retransmit_queue.patch b/tcp-fix-use-after-free-in-tcp_xmit_retransmit_queue.patch new file mode 100644 index 000000000..36ada7acf --- /dev/null +++ b/tcp-fix-use-after-free-in-tcp_xmit_retransmit_queue.patch @@ -0,0 +1,46 @@ +From: Eric Dumazet <edumazet@google.com> +Date: 2016-08-17 12:56:26 +Subject: [PATCH net] tcp: fix use after free in tcp_xmit_retransmit_queue() + +When tcp_sendmsg() allocates a fresh and empty skb, it puts it at the +tail of the write queue using tcp_add_write_queue_tail() + +Then it attempts to copy user data into this fresh skb. + +If the copy fails, we undo the work and remove the fresh skb. + +Unfortunately, this undo lacks the change done to tp->highest_sack and +we can leave a dangling pointer (to a freed skb) + +Later, tcp_xmit_retransmit_queue() can dereference this pointer and +access freed memory. For regular kernels where memory is not unmapped, +this might cause SACK bugs because tcp_highest_sack_seq() is buggy, +returning garbage instead of tp->snd_nxt, but with various debug +features like CONFIG_DEBUG_PAGEALLOC, this can crash the kernel. + +This bug was found by Marco Grassi thanks to syzkaller. + +Fixes: 6859d49475d4 ("[TCP]: Abstract tp->highest_sack accessing & point to next skb") +Reported-by: Marco Grassi <marco.gra@gmail.com> +Signed-off-by: Eric Dumazet <edumazet@google.com> +Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> +Cc: Yuchung Cheng <ycheng@google.com> +Cc: Neal Cardwell <ncardwell@google.com> +--- + include/net/tcp.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index c00e7d51bb18..7717302cab91 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -1523,6 +1523,8 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli + { + if (sk->sk_send_head == skb_unlinked) + sk->sk_send_head = NULL; ++ if (tcp_sk(sk)->highest_sack == skb_unlinked) ++ tcp_sk(sk)->highest_sack = NULL; + } + + static inline void tcp_init_send_head(struct sock *sk) + |