From: Greg Kroah-Hartman Date: Tue, 10 Oct 2017 18:15:55 +0000 (+0200) Subject: 4.13-stable patches X-Git-Tag: v3.18.75~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a8fdbc88137e56750b599d029903cc74bda87a06;p=thirdparty%2Fkernel%2Fstable-queue.git 4.13-stable patches added patches: brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch brcmfmac-setup-passive-scan-if-requested-by-user-space.patch bsg-lib-fix-use-after-free-under-memory-pressure.patch clk-samsung-exynos4-enable-vpll-and-epll-clocks-for-suspend-resume-cycle.patch drm-i915-always-update-eld-connector-type-after-get-modes.patch drm-i915-bios-ignore-hdmi-on-port-a.patch mmc-core-add-driver-strength-selection-when-selecting-hs400es.patch nl80211-define-policy-for-packet-pattern-attributes.patch nvme-pci-use-pci-bus-address-for-data-queues-in-cmb.patch udp-fix-bcast-packet-reception.patch udp-perform-source-validation-for-mcast-early-demux.patch --- diff --git a/queue-4.13/brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch b/queue-4.13/brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch new file mode 100644 index 00000000000..4bb82499ee4 --- /dev/null +++ b/queue-4.13/brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch @@ -0,0 +1,71 @@ +From 17df6453d4be17910456e99c5a85025aa1b7a246 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 12 Sep 2017 10:47:53 +0200 +Subject: brcmfmac: add length check in brcmf_cfg80211_escan_handler() + +From: Arend Van Spriel + +commit 17df6453d4be17910456e99c5a85025aa1b7a246 upstream. + +Upon handling the firmware notification for scans the length was +checked properly and may result in corrupting kernel heap memory +due to buffer overruns. This fix addresses CVE-2017-0786. + +Cc: Kevin Cernekee +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 18 ++++++++++-- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3162,6 +3162,7 @@ brcmf_cfg80211_escan_handler(struct brcm + struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + s32 status; + struct brcmf_escan_result_le *escan_result_le; ++ u32 escan_buflen; + struct brcmf_bss_info_le *bss_info_le; + struct brcmf_bss_info_le *bss = NULL; + u32 bi_length; +@@ -3181,11 +3182,23 @@ brcmf_cfg80211_escan_handler(struct brcm + + if (status == BRCMF_E_STATUS_PARTIAL) { + brcmf_dbg(SCAN, "ESCAN Partial result\n"); ++ if (e->datalen < sizeof(*escan_result_le)) { ++ brcmf_err("invalid event data length\n"); ++ goto exit; ++ } + escan_result_le = (struct brcmf_escan_result_le *) data; + if (!escan_result_le) { + brcmf_err("Invalid escan result (NULL pointer)\n"); + goto exit; + } ++ escan_buflen = le32_to_cpu(escan_result_le->buflen); ++ if (escan_buflen > BRCMF_ESCAN_BUF_SIZE || ++ escan_buflen > e->datalen || ++ escan_buflen < sizeof(*escan_result_le)) { ++ brcmf_err("Invalid escan buffer length: %d\n", ++ escan_buflen); ++ goto exit; ++ } + if (le16_to_cpu(escan_result_le->bss_count) != 1) { + brcmf_err("Invalid bss_count %d: ignoring\n", + escan_result_le->bss_count); +@@ -3202,9 +3215,8 @@ brcmf_cfg80211_escan_handler(struct brcm + } + + bi_length = le32_to_cpu(bss_info_le->length); +- if (bi_length != (le32_to_cpu(escan_result_le->buflen) - +- WL_ESCAN_RESULTS_FIXED_SIZE)) { +- brcmf_err("Invalid bss_info length %d: ignoring\n", ++ if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { ++ brcmf_err("Ignoring invalid bss_info length: %d\n", + bi_length); + goto exit; + } diff --git a/queue-4.13/brcmfmac-setup-passive-scan-if-requested-by-user-space.patch b/queue-4.13/brcmfmac-setup-passive-scan-if-requested-by-user-space.patch new file mode 100644 index 00000000000..2aa498c43ab --- /dev/null +++ b/queue-4.13/brcmfmac-setup-passive-scan-if-requested-by-user-space.patch @@ -0,0 +1,85 @@ +From 35f62727df0ed8e5e4857e162d94fd46d861f1cf Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 12 Sep 2017 10:47:54 +0200 +Subject: brcmfmac: setup passive scan if requested by user-space + +From: Arend Van Spriel + +commit 35f62727df0ed8e5e4857e162d94fd46d861f1cf upstream. + +The driver was not properly configuring firmware with regard to the +type of scan. It always performed an active scan even when user-space +was requesting for passive scan, ie. the scan request was done without +any SSIDs specified. + +Reported-by: Huang, Jiangyang +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 19 ++-------- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | 5 ++ + 2 files changed, 9 insertions(+), 15 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -980,7 +980,7 @@ static void brcmf_escan_prep(struct brcm + + eth_broadcast_addr(params_le->bssid); + params_le->bss_type = DOT11_BSSTYPE_ANY; +- params_le->scan_type = 0; ++ params_le->scan_type = BRCMF_SCANTYPE_ACTIVE; + params_le->channel_num = 0; + params_le->nprobes = cpu_to_le32(-1); + params_le->active_time = cpu_to_le32(-1); +@@ -988,12 +988,9 @@ static void brcmf_escan_prep(struct brcm + params_le->home_time = cpu_to_le32(-1); + memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le)); + +- /* if request is null exit so it will be all channel broadcast scan */ +- if (!request) +- return; +- + n_ssids = request->n_ssids; + n_channels = request->n_channels; ++ + /* Copy channel array if applicable */ + brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n", + n_channels); +@@ -1030,16 +1027,8 @@ static void brcmf_escan_prep(struct brcm + ptr += sizeof(ssid_le); + } + } else { +- brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids); +- if ((request->ssids) && request->ssids->ssid_len) { +- brcmf_dbg(SCAN, "SSID %s len=%d\n", +- params_le->ssid_le.SSID, +- request->ssids->ssid_len); +- params_le->ssid_le.SSID_len = +- cpu_to_le32(request->ssids->ssid_len); +- memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid, +- request->ssids->ssid_len); +- } ++ brcmf_dbg(SCAN, "Performing passive scan\n"); ++ params_le->scan_type = BRCMF_SCANTYPE_PASSIVE; + } + /* Adding mask to channel numbers */ + params_le->channel_num = +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -45,6 +45,11 @@ + #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff + #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 + ++/* scan type definitions */ ++#define BRCMF_SCANTYPE_DEFAULT 0xFF ++#define BRCMF_SCANTYPE_ACTIVE 0 ++#define BRCMF_SCANTYPE_PASSIVE 1 ++ + #define BRCMF_WSEC_MAX_PSK_LEN 32 + #define BRCMF_WSEC_PASSPHRASE BIT(0) + diff --git a/queue-4.13/bsg-lib-fix-use-after-free-under-memory-pressure.patch b/queue-4.13/bsg-lib-fix-use-after-free-under-memory-pressure.patch new file mode 100644 index 00000000000..dfa2159e894 --- /dev/null +++ b/queue-4.13/bsg-lib-fix-use-after-free-under-memory-pressure.patch @@ -0,0 +1,105 @@ +From eab40cf336065e8d765e006b81ff48c5c114b365 Mon Sep 17 00:00:00 2001 +From: Benjamin Block +Date: Tue, 3 Oct 2017 12:48:37 +0200 +Subject: bsg-lib: fix use-after-free under memory-pressure + +From: Benjamin Block + +commit eab40cf336065e8d765e006b81ff48c5c114b365 upstream. + +When under memory-pressure it is possible that the mempool which backs +the 'struct request_queue' will make use of up to BLKDEV_MIN_RQ count +emergency buffers - in case it can't get a regular allocation. These +buffers are preallocated and once they are also used, they are +re-supplied with old finished requests from the same request_queue (see +mempool_free()). + +The bug is, when re-supplying the emergency pool, the old requests are +not again ran through the callback mempool_t->alloc(), and thus also not +through the callback bsg_init_rq(). Thus we skip initialization, and +while the sense-buffer still should be good, scsi_request->cmd might +have become to be an invalid pointer in the meantime. When the request +is initialized in bsg.c, and the user's CDB is larger than BLK_MAX_CDB, +bsg will replace it with a custom allocated buffer, which is freed when +the user's command is finished, thus it dangles afterwards. When next a +command is sent by the user that has a smaller/similar CDB as +BLK_MAX_CDB, bsg will assume that scsi_request->cmd is backed by +scsi_request->__cmd, will not make a custom allocation, and write into +undefined memory. + +Fix this by splitting bsg_init_rq() into two functions: + - bsg_init_rq() is changed to only do the allocation of the + sense-buffer, which is used to back the bsg job's reply buffer. This + pointer should never change during the lifetime of a scsi_request, so + it doesn't need re-initialization. + - bsg_initialize_rq() is a new function that makes use of + 'struct request_queue's initialize_rq_fn callback (which was + introduced in v4.12). This is always called before the request is + given out via blk_get_request(). This function does the remaining + initialization that was previously done in bsg_init_rq(), and will + also do it when the request is taken from the emergency-pool of the + backing mempool. + +Fixes: 50b4d485528d ("bsg-lib: fix kernel panic resulting from missing allocation of reply-buffer") +Reviewed-by: Hannes Reinecke +Reviewed-by: Johannes Thumshirn +Reviewed-by: Christoph Hellwig +Signed-off-by: Benjamin Block +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/bsg-lib.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +--- a/block/bsg-lib.c ++++ b/block/bsg-lib.c +@@ -207,20 +207,34 @@ static int bsg_init_rq(struct request_qu + struct bsg_job *job = blk_mq_rq_to_pdu(req); + struct scsi_request *sreq = &job->sreq; + ++ /* called right after the request is allocated for the request_queue */ ++ ++ sreq->sense = kzalloc(SCSI_SENSE_BUFFERSIZE, gfp); ++ if (!sreq->sense) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static void bsg_initialize_rq(struct request *req) ++{ ++ struct bsg_job *job = blk_mq_rq_to_pdu(req); ++ struct scsi_request *sreq = &job->sreq; ++ void *sense = sreq->sense; ++ ++ /* called right before the request is given to the request_queue user */ ++ + memset(job, 0, sizeof(*job)); + + scsi_req_init(sreq); ++ ++ sreq->sense = sense; + sreq->sense_len = SCSI_SENSE_BUFFERSIZE; +- sreq->sense = kzalloc(sreq->sense_len, gfp); +- if (!sreq->sense) +- return -ENOMEM; + + job->req = req; +- job->reply = sreq->sense; ++ job->reply = sense; + job->reply_len = sreq->sense_len; + job->dd_data = job + 1; +- +- return 0; + } + + static void bsg_exit_rq(struct request_queue *q, struct request *req) +@@ -250,6 +264,7 @@ struct request_queue *bsg_setup_queue(st + q->cmd_size = sizeof(struct bsg_job) + dd_job_size; + q->init_rq_fn = bsg_init_rq; + q->exit_rq_fn = bsg_exit_rq; ++ q->initialize_rq_fn = bsg_initialize_rq; + q->request_fn = bsg_request_fn; + + ret = blk_init_allocated_queue(q); diff --git a/queue-4.13/clk-samsung-exynos4-enable-vpll-and-epll-clocks-for-suspend-resume-cycle.patch b/queue-4.13/clk-samsung-exynos4-enable-vpll-and-epll-clocks-for-suspend-resume-cycle.patch new file mode 100644 index 00000000000..bd7a919151e --- /dev/null +++ b/queue-4.13/clk-samsung-exynos4-enable-vpll-and-epll-clocks-for-suspend-resume-cycle.patch @@ -0,0 +1,61 @@ +From 5dcbeca615ef12047a5f4097b91030cbf995b1d2 Mon Sep 17 00:00:00 2001 +From: Marek Szyprowski +Date: Tue, 19 Sep 2017 12:01:08 +0200 +Subject: clk: samsung: exynos4: Enable VPLL and EPLL clocks for suspend/resume cycle + +From: Marek Szyprowski + +commit 5dcbeca615ef12047a5f4097b91030cbf995b1d2 upstream. + +Commit 6edfa11cb396 ("clk: samsung: Add enable/disable operation for +PLL36XX clocks") added enable/disable operations to PLL clocks. Prior that +VPLL and EPPL clocks were always enabled because the enable bit was never +touched. Those clocks have to be enabled during suspend/resume cycle, +because otherwise board fails to enter sleep mode. This patch enables them +unconditionally before entering system suspend state. System restore +function will set them to the previous state saved in the register cache +done before that unconditional enable. + +Fixes: 6edfa11cb396 ("clk: samsung: Add enable/disable operation for PLL36XX clocks") +Signed-off-by: Marek Szyprowski +Reviewed-by: Chanwoo Choi +Reviewed-by: Krzysztof Kozlowski +Acked-by: Sylwester Nawrocki +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/samsung/clk-exynos4.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/clk/samsung/clk-exynos4.c ++++ b/drivers/clk/samsung/clk-exynos4.c +@@ -294,6 +294,18 @@ static const struct samsung_clk_reg_dump + #define PLL_ENABLED (1 << 31) + #define PLL_LOCKED (1 << 29) + ++static void exynos4_clk_enable_pll(u32 reg) ++{ ++ u32 pll_con = readl(reg_base + reg); ++ pll_con |= PLL_ENABLED; ++ writel(pll_con, reg_base + reg); ++ ++ while (!(pll_con & PLL_LOCKED)) { ++ cpu_relax(); ++ pll_con = readl(reg_base + reg); ++ } ++} ++ + static void exynos4_clk_wait_for_pll(u32 reg) + { + u32 pll_con; +@@ -315,6 +327,9 @@ static int exynos4_clk_suspend(void) + samsung_clk_save(reg_base, exynos4_save_pll, + ARRAY_SIZE(exynos4_clk_pll_regs)); + ++ exynos4_clk_enable_pll(EPLL_CON0); ++ exynos4_clk_enable_pll(VPLL_CON0); ++ + if (exynos4_soc == EXYNOS4210) { + samsung_clk_save(reg_base, exynos4_save_soc, + ARRAY_SIZE(exynos4210_clk_save)); diff --git a/queue-4.13/drm-i915-always-update-eld-connector-type-after-get-modes.patch b/queue-4.13/drm-i915-always-update-eld-connector-type-after-get-modes.patch new file mode 100644 index 00000000000..fa2a9c87b85 --- /dev/null +++ b/queue-4.13/drm-i915-always-update-eld-connector-type-after-get-modes.patch @@ -0,0 +1,89 @@ +From 2d8f63297b9f0b430c96329893667c0bfdcbd47e Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 19 Sep 2017 18:38:13 +0300 +Subject: drm/i915: always update ELD connector type after get modes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jani Nikula + +commit 2d8f63297b9f0b430c96329893667c0bfdcbd47e upstream. + +drm_edid_to_eld() initializes the connector ELD to zero, overwriting the +ELD connector type initialized in intel_audio_codec_enable(). If +userspace does getconnector and thus get_modes after modeset, a +subsequent audio component i915_audio_component_get_eld() call will +receive an ELD without the connector type properly set. It's fine for +HDMI, but screws up audio for DP. + +Always set the ELD connector type at intel_connector_update_modes() +based on the connector type. We can drop the connector type update from +intel_audio_codec_enable(). + +Credits to Joseph Nuzman for figuring this out. + +Cc: Ville Syrjälä +Cc: Joseph Nuzman +Reported-by: Joseph Nuzman +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101583 +Reviewed-by: Ville Syrjälä +Tested-by: Joseph Nuzman +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20170919153813.29808-1-jani.nikula@intel.com +(cherry picked from commit d81fb7fd9436e81fda67e5bc8ed0713aa28d3db2) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_audio.c | 5 ----- + drivers/gpu/drm/i915/intel_modes.c | 17 +++++++++++++++++ + 2 files changed, 17 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_audio.c ++++ b/drivers/gpu/drm/i915/intel_audio.c +@@ -606,11 +606,6 @@ void intel_audio_codec_enable(struct int + connector->encoder->base.id, + connector->encoder->name); + +- /* ELD Conn_Type */ +- connector->eld[5] &= ~(3 << 2); +- if (intel_crtc_has_dp_encoder(crtc_state)) +- connector->eld[5] |= (1 << 2); +- + connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; + + if (dev_priv->display.audio_codec_enable) +--- a/drivers/gpu/drm/i915/intel_modes.c ++++ b/drivers/gpu/drm/i915/intel_modes.c +@@ -30,6 +30,21 @@ + #include "intel_drv.h" + #include "i915_drv.h" + ++static void intel_connector_update_eld_conn_type(struct drm_connector *connector) ++{ ++ u8 conn_type; ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || ++ connector->connector_type == DRM_MODE_CONNECTOR_eDP) { ++ conn_type = DRM_ELD_CONN_TYPE_DP; ++ } else { ++ conn_type = DRM_ELD_CONN_TYPE_HDMI; ++ } ++ ++ connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] &= ~DRM_ELD_CONN_TYPE_MASK; ++ connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= conn_type; ++} ++ + /** + * intel_connector_update_modes - update connector from edid + * @connector: DRM connector device to use +@@ -44,6 +59,8 @@ int intel_connector_update_modes(struct + ret = drm_add_edid_modes(connector, edid); + drm_edid_to_eld(connector, edid); + ++ intel_connector_update_eld_conn_type(connector); ++ + return ret; + } + diff --git a/queue-4.13/drm-i915-bios-ignore-hdmi-on-port-a.patch b/queue-4.13/drm-i915-bios-ignore-hdmi-on-port-a.patch new file mode 100644 index 00000000000..f54624663de --- /dev/null +++ b/queue-4.13/drm-i915-bios-ignore-hdmi-on-port-a.patch @@ -0,0 +1,48 @@ +From 2ba7d7e0437127314864238f8bfcb8369d81075c Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Thu, 21 Sep 2017 17:19:20 +0300 +Subject: drm/i915/bios: ignore HDMI on port A +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jani Nikula + +commit 2ba7d7e0437127314864238f8bfcb8369d81075c upstream. + +The hardware state readout oopses after several warnings when trying to +use HDMI on port A, if such a combination is configured in VBT. Filter +the combo out already at the VBT parsing phase. + +v2: also ignore DVI (Ville) + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102889 +Cc: Imre Deak +Reviewed-by: Ville Syrjälä +Tested-by: Daniel Drake +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20170921141920.18172-1-jani.nikula@intel.com +(cherry picked from commit d27ffc1d00327c29b3aa97f941b42f0949f9e99f) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_bios.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_bios.c ++++ b/drivers/gpu/drm/i915/intel_bios.c +@@ -1163,6 +1163,13 @@ static void parse_ddi_port(struct drm_i9 + is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0; + is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR); + ++ if (port == PORT_A && is_dvi) { ++ DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n", ++ is_hdmi ? "/HDMI" : ""); ++ is_dvi = false; ++ is_hdmi = false; ++ } ++ + info->supports_dvi = is_dvi; + info->supports_hdmi = is_hdmi; + info->supports_dp = is_dp; diff --git a/queue-4.13/mmc-core-add-driver-strength-selection-when-selecting-hs400es.patch b/queue-4.13/mmc-core-add-driver-strength-selection-when-selecting-hs400es.patch new file mode 100644 index 00000000000..ea78d521bca --- /dev/null +++ b/queue-4.13/mmc-core-add-driver-strength-selection-when-selecting-hs400es.patch @@ -0,0 +1,83 @@ +From fb458864d9a78cc433fec7979acbe4078c82d7a8 Mon Sep 17 00:00:00 2001 +From: Chanho Min +Date: Tue, 26 Sep 2017 09:03:40 +0900 +Subject: mmc: core: add driver strength selection when selecting hs400es + +From: Chanho Min + +commit fb458864d9a78cc433fec7979acbe4078c82d7a8 upstream. + +The driver strength selection is missed and required when selecting +hs400es. So, It is added here. + +Fixes: 81ac2af65793ecf ("mmc: core: implement enhanced strobe support") +Signed-off-by: Hankyung Yu +Signed-off-by: Chanho Min +Reviewed-by: Adrian Hunter +Reviewed-by: Shawn Lin +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/core/mmc.c | 36 +++++++++++++++++++----------------- + 1 file changed, 19 insertions(+), 17 deletions(-) + +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -1286,6 +1286,23 @@ out_err: + return err; + } + ++static void mmc_select_driver_type(struct mmc_card *card) ++{ ++ int card_drv_type, drive_strength, drv_type; ++ ++ card_drv_type = card->ext_csd.raw_driver_strength | ++ mmc_driver_type_mask(0); ++ ++ drive_strength = mmc_select_drive_strength(card, ++ card->ext_csd.hs200_max_dtr, ++ card_drv_type, &drv_type); ++ ++ card->drive_strength = drive_strength; ++ ++ if (drv_type) ++ mmc_set_driver_type(card->host, drv_type); ++} ++ + static int mmc_select_hs400es(struct mmc_card *card) + { + struct mmc_host *host = card->host; +@@ -1341,6 +1358,8 @@ static int mmc_select_hs400es(struct mmc + goto out_err; + } + ++ mmc_select_driver_type(card); ++ + /* Switch card to HS400 */ + val = EXT_CSD_TIMING_HS400 | + card->drive_strength << EXT_CSD_DRV_STR_SHIFT; +@@ -1374,23 +1393,6 @@ out_err: + return err; + } + +-static void mmc_select_driver_type(struct mmc_card *card) +-{ +- int card_drv_type, drive_strength, drv_type; +- +- card_drv_type = card->ext_csd.raw_driver_strength | +- mmc_driver_type_mask(0); +- +- drive_strength = mmc_select_drive_strength(card, +- card->ext_csd.hs200_max_dtr, +- card_drv_type, &drv_type); +- +- card->drive_strength = drive_strength; +- +- if (drv_type) +- mmc_set_driver_type(card->host, drv_type); +-} +- + /* + * For device supporting HS200 mode, the following sequence + * should be done before executing the tuning process. diff --git a/queue-4.13/nl80211-define-policy-for-packet-pattern-attributes.patch b/queue-4.13/nl80211-define-policy-for-packet-pattern-attributes.patch new file mode 100644 index 00000000000..4fda7b252bf --- /dev/null +++ b/queue-4.13/nl80211-define-policy-for-packet-pattern-attributes.patch @@ -0,0 +1,69 @@ +From ad670233c9e1d5feb365d870e30083ef1b889177 Mon Sep 17 00:00:00 2001 +From: Peng Xu +Date: Tue, 3 Oct 2017 23:21:51 +0300 +Subject: nl80211: Define policy for packet pattern attributes + +From: Peng Xu + +commit ad670233c9e1d5feb365d870e30083ef1b889177 upstream. + +Define a policy for packet pattern attributes in order to fix a +potential read over the end of the buffer during nla_get_u32() +of the NL80211_PKTPAT_OFFSET attribute. + +Note that the data there can always be read due to SKB allocation +(with alignment and struct skb_shared_info at the end), but the +data might be uninitialized. This could be used to leak some data +from uninitialized vmalloc() memory, but most drivers don't allow +an offset (so you'd just get -EINVAL if the data is non-zero) or +just allow it with a fixed value - 100 or 128 bytes, so anything +above that would get -EINVAL. With brcmfmac the limit is 1500 so +(at least) one byte could be obtained. + +Signed-off-by: Peng Xu +Signed-off-by: Jouni Malinen +[rewrite description based on SKB allocation knowledge] +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/nl80211.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -549,6 +549,14 @@ nl80211_nan_srf_policy[NL80211_NAN_SRF_A + [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED }, + }; + ++/* policy for packet pattern attributes */ ++static const struct nla_policy ++nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { ++ [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, ++}; ++ + static int nl80211_prepare_wdev_dump(struct sk_buff *skb, + struct netlink_callback *cb, + struct cfg80211_registered_device **rdev, +@@ -10529,7 +10537,8 @@ static int nl80211_set_wowlan(struct sk_ + u8 *mask_pat; + + nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, +- NULL, info->extack); ++ nl80211_packet_pattern_policy, ++ info->extack); + err = -EINVAL; + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) +@@ -10778,7 +10787,8 @@ static int nl80211_parse_coalesce_rule(s + rem) { + u8 *mask_pat; + +- nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, NULL, NULL); ++ nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, ++ nl80211_packet_pattern_policy, NULL); + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) + return -EINVAL; diff --git a/queue-4.13/nvme-pci-use-pci-bus-address-for-data-queues-in-cmb.patch b/queue-4.13/nvme-pci-use-pci-bus-address-for-data-queues-in-cmb.patch new file mode 100644 index 00000000000..f85c8323c82 --- /dev/null +++ b/queue-4.13/nvme-pci-use-pci-bus-address-for-data-queues-in-cmb.patch @@ -0,0 +1,86 @@ +From 8969f1f8291762c13147c1ba89d46238af01675b Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Sun, 1 Oct 2017 09:37:35 +0200 +Subject: nvme-pci: Use PCI bus address for data/queues in CMB + +From: Christoph Hellwig + +commit 8969f1f8291762c13147c1ba89d46238af01675b upstream. + +Currently, NVMe PCI host driver is programming CMB dma address as +I/O SQs addresses. This results in failures on systems where 1:1 +outbound mapping is not used (example Broadcom iProc SOCs) because +CMB BAR will be progammed with PCI bus address but NVMe PCI EP will +try to access CMB using dma address. + +To have CMB working on systems without 1:1 outbound mapping, we +program PCI bus address for I/O SQs instead of dma address. This +approach will work on systems with/without 1:1 outbound mapping. + +Based on a report and previous patch from Abhishek Shah. + +Fixes: 8ffaadf7 ("NVMe: Use CMB for the IO SQes if available") +Reported-by: Abhishek Shah +Tested-by: Abhishek Shah +Reviewed-by: Keith Busch +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nvme/host/pci.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -93,7 +93,7 @@ struct nvme_dev { + struct mutex shutdown_lock; + bool subsystem; + void __iomem *cmb; +- dma_addr_t cmb_dma_addr; ++ pci_bus_addr_t cmb_bus_addr; + u64 cmb_size; + u32 cmbsz; + u32 cmbloc; +@@ -1218,7 +1218,7 @@ static int nvme_alloc_sq_cmds(struct nvm + if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) { + unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth), + dev->ctrl.page_size); +- nvmeq->sq_dma_addr = dev->cmb_dma_addr + offset; ++ nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset; + nvmeq->sq_cmds_io = dev->cmb + offset; + } else { + nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), +@@ -1517,7 +1517,7 @@ static void __iomem *nvme_map_cmb(struct + resource_size_t bar_size; + struct pci_dev *pdev = to_pci_dev(dev->dev); + void __iomem *cmb; +- dma_addr_t dma_addr; ++ int bar; + + dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ); + if (!(NVME_CMB_SZ(dev->cmbsz))) +@@ -1530,7 +1530,8 @@ static void __iomem *nvme_map_cmb(struct + szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz)); + size = szu * NVME_CMB_SZ(dev->cmbsz); + offset = szu * NVME_CMB_OFST(dev->cmbloc); +- bar_size = pci_resource_len(pdev, NVME_CMB_BIR(dev->cmbloc)); ++ bar = NVME_CMB_BIR(dev->cmbloc); ++ bar_size = pci_resource_len(pdev, bar); + + if (offset > bar_size) + return NULL; +@@ -1543,12 +1544,11 @@ static void __iomem *nvme_map_cmb(struct + if (size > bar_size - offset) + size = bar_size - offset; + +- dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(dev->cmbloc)) + offset; +- cmb = ioremap_wc(dma_addr, size); ++ cmb = ioremap_wc(pci_resource_start(pdev, bar) + offset, size); + if (!cmb) + return NULL; + +- dev->cmb_dma_addr = dma_addr; ++ dev->cmb_bus_addr = pci_bus_address(pdev, bar) + offset; + dev->cmb_size = size; + return cmb; + } diff --git a/queue-4.13/series b/queue-4.13/series index cc7880b4858..448f8dbcaf4 100644 --- a/queue-4.13/series +++ b/queue-4.13/series @@ -146,3 +146,14 @@ kvm-x86-avoid-async-pf-preempting-the-kernel-incorrectly.patch iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch scsi-sd-implement-blacklist-option-for-write-same-w-unmap.patch scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch +brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch +brcmfmac-setup-passive-scan-if-requested-by-user-space.patch +drm-i915-always-update-eld-connector-type-after-get-modes.patch +drm-i915-bios-ignore-hdmi-on-port-a.patch +bsg-lib-fix-use-after-free-under-memory-pressure.patch +nvme-pci-use-pci-bus-address-for-data-queues-in-cmb.patch +mmc-core-add-driver-strength-selection-when-selecting-hs400es.patch +nl80211-define-policy-for-packet-pattern-attributes.patch +clk-samsung-exynos4-enable-vpll-and-epll-clocks-for-suspend-resume-cycle.patch +udp-perform-source-validation-for-mcast-early-demux.patch +udp-fix-bcast-packet-reception.patch diff --git a/queue-4.13/udp-fix-bcast-packet-reception.patch b/queue-4.13/udp-fix-bcast-packet-reception.patch new file mode 100644 index 00000000000..1794cdab0bb --- /dev/null +++ b/queue-4.13/udp-fix-bcast-packet-reception.patch @@ -0,0 +1,59 @@ +From 996b44fcef8f216ea0b6b6e74468c5a77b5e341f Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Mon, 9 Oct 2017 14:52:10 +0200 +Subject: udp: fix bcast packet reception + +From: Paolo Abeni + +commit 996b44fcef8f216ea0b6b6e74468c5a77b5e341f upstream. + +The commit bc044e8db796 ("udp: perform source validation for +mcast early demux") does not take into account that broadcast packets +lands in the same code path and they need different checks for the +source address - notably, zero source address are valid for bcast +and invalid for mcast. + +As a result, 2nd and later broadcast packets with 0 source address +landing to the same socket are dropped. This breaks dhcp servers. + +Since we don't have stringent performance requirements for ingress +broadcast traffic, fix it by disabling UDP early demux such traffic. + +Reported-by: Hannes Frederic Sowa +Fixes: bc044e8db796 ("udp: perform source validation for mcast early demux") +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/udp.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2235,20 +2235,16 @@ int udp_v4_early_demux(struct sk_buff *s + iph = ip_hdr(skb); + uh = udp_hdr(skb); + +- if (skb->pkt_type == PACKET_BROADCAST || +- skb->pkt_type == PACKET_MULTICAST) { ++ if (skb->pkt_type == PACKET_MULTICAST) { + in_dev = __in_dev_get_rcu(skb->dev); + + if (!in_dev) + return 0; + +- /* we are supposed to accept bcast packets */ +- if (skb->pkt_type == PACKET_MULTICAST) { +- ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, +- iph->protocol); +- if (!ours) +- return 0; +- } ++ ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, ++ iph->protocol); ++ if (!ours) ++ return 0; + + sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, + uh->source, iph->saddr, dif); diff --git a/queue-4.13/udp-perform-source-validation-for-mcast-early-demux.patch b/queue-4.13/udp-perform-source-validation-for-mcast-early-demux.patch new file mode 100644 index 00000000000..cfee690523f --- /dev/null +++ b/queue-4.13/udp-perform-source-validation-for-mcast-early-demux.patch @@ -0,0 +1,191 @@ +From foo@baz Mon Oct 9 09:32:35 CEST 2017 +From: Paolo Abeni +Date: Thu, 28 Sep 2017 15:51:37 +0200 +Subject: udp: perform source validation for mcast early demux + +From: Paolo Abeni + + +[ Upstream commit bc044e8db7962e727a75b591b9851ff2ac5cf846 ] + +The UDP early demux can leverate the rx dst cache even for +multicast unconnected sockets. + +In such scenario the ipv4 source address is validated only on +the first packet in the given flow. After that, when we fetch +the dst entry from the socket rx cache, we stop enforcing +the rp_filter and we even start accepting any kind of martian +addresses. + +Disabling the dst cache for unconnected multicast socket will +cause large performace regression, nearly reducing by half the +max ingress tput. + +Instead we factor out a route helper to completely validate an +skb source address for multicast packets and we call it from +the UDP early demux for mcast packets landing on unconnected +sockets, after successful fetching the related cached dst entry. + +This still gives a measurable, but limited performance +regression: + + rp_filter = 0 rp_filter = 1 +edmux disabled: 1182 Kpps 1127 Kpps +edmux before: 2238 Kpps 2238 Kpps +edmux after: 2037 Kpps 2019 Kpps + +The above figures are on top of current net tree. +Applying the net-next commit 6e617de84e87 ("net: avoid a full +fib lookup when rp_filter is disabled.") the delta with +rp_filter == 0 will decrease even more. + +Fixes: 421b3885bf6d ("udp: ipv4: Add udp early demux") +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/route.h | 4 +++- + net/ipv4/route.c | 46 ++++++++++++++++++++++++++-------------------- + net/ipv4/udp.c | 13 ++++++++++++- + 3 files changed, 41 insertions(+), 22 deletions(-) + +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -175,7 +175,9 @@ static inline struct rtable *ip_route_ou + fl4->fl4_gre_key = gre_key; + return ip_route_output_key(net, fl4); + } +- ++int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr, ++ u8 tos, struct net_device *dev, ++ struct in_device *in_dev, u32 *itag); + int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src, + u8 tos, struct net_device *devin); + int ip_route_input_rcu(struct sk_buff *skb, __be32 dst, __be32 src, +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1520,43 +1520,56 @@ struct rtable *rt_dst_alloc(struct net_d + EXPORT_SYMBOL(rt_dst_alloc); + + /* called in rcu_read_lock() section */ +-static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, +- u8 tos, struct net_device *dev, int our) ++int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr, ++ u8 tos, struct net_device *dev, ++ struct in_device *in_dev, u32 *itag) + { +- struct rtable *rth; +- struct in_device *in_dev = __in_dev_get_rcu(dev); +- unsigned int flags = RTCF_MULTICAST; +- u32 itag = 0; + int err; + + /* Primary sanity checks. */ +- + if (!in_dev) + return -EINVAL; + + if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || + skb->protocol != htons(ETH_P_IP)) +- goto e_inval; ++ return -EINVAL; + + if (ipv4_is_loopback(saddr) && !IN_DEV_ROUTE_LOCALNET(in_dev)) +- goto e_inval; ++ return -EINVAL; + + if (ipv4_is_zeronet(saddr)) { + if (!ipv4_is_local_multicast(daddr)) +- goto e_inval; ++ return -EINVAL; + } else { + err = fib_validate_source(skb, saddr, 0, tos, 0, dev, +- in_dev, &itag); ++ in_dev, itag); + if (err < 0) +- goto e_err; ++ return err; + } ++ return 0; ++} ++ ++/* called in rcu_read_lock() section */ ++static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, ++ u8 tos, struct net_device *dev, int our) ++{ ++ struct in_device *in_dev = __in_dev_get_rcu(dev); ++ unsigned int flags = RTCF_MULTICAST; ++ struct rtable *rth; ++ u32 itag = 0; ++ int err; ++ ++ err = ip_mc_validate_source(skb, daddr, saddr, tos, dev, in_dev, &itag); ++ if (err) ++ return err; ++ + if (our) + flags |= RTCF_LOCAL; + + rth = rt_dst_alloc(dev_net(dev)->loopback_dev, flags, RTN_MULTICAST, + IN_DEV_CONF_GET(in_dev, NOPOLICY), false, false); + if (!rth) +- goto e_nobufs; ++ return -ENOBUFS; + + #ifdef CONFIG_IP_ROUTE_CLASSID + rth->dst.tclassid = itag; +@@ -1572,13 +1585,6 @@ static int ip_route_input_mc(struct sk_b + + skb_dst_set(skb, &rth->dst); + return 0; +- +-e_nobufs: +- return -ENOBUFS; +-e_inval: +- return -EINVAL; +-e_err: +- return err; + } + + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2220,6 +2220,7 @@ static struct sock *__udp4_lib_demux_loo + int udp_v4_early_demux(struct sk_buff *skb) + { + struct net *net = dev_net(skb->dev); ++ struct in_device *in_dev = NULL; + const struct iphdr *iph; + const struct udphdr *uh; + struct sock *sk = NULL; +@@ -2236,7 +2237,7 @@ int udp_v4_early_demux(struct sk_buff *s + + if (skb->pkt_type == PACKET_BROADCAST || + skb->pkt_type == PACKET_MULTICAST) { +- struct in_device *in_dev = __in_dev_get_rcu(skb->dev); ++ in_dev = __in_dev_get_rcu(skb->dev); + + if (!in_dev) + return 0; +@@ -2266,11 +2267,21 @@ int udp_v4_early_demux(struct sk_buff *s + if (dst) + dst = dst_check(dst, 0); + if (dst) { ++ u32 itag = 0; ++ + /* set noref for now. + * any place which wants to hold dst has to call + * dst_hold_safe() + */ + skb_dst_set_noref(skb, dst); ++ ++ /* for unconnected multicast sockets we need to validate ++ * the source on each packet ++ */ ++ if (!inet_sk(sk)->inet_daddr && in_dev) ++ return ip_mc_validate_source(skb, iph->daddr, ++ iph->saddr, iph->tos, ++ skb->dev, in_dev, &itag); + } + return 0; + }