From f6b7f87b9ea22570317ecb9f259e98765fb9748e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Aug 2013 10:47:10 +0800 Subject: [PATCH] 3.10-stable patches added patches: acpi-battery-fix-parsing-_bix-return-value.patch mwifiex-add-missing-endian-conversion.patch mwifiex-check-for-bss_role-instead-of-bss_mode-for-sta-operations.patch mwifiex-fix-wrong-data-rates-in-p2p-client.patch rt2x00-fix-stop-queue.patch svcrpc-fix-gss-proxy-xdr-decoding-oops.patch svcrpc-fix-gss_rpc_upcall-create-error.patch svcrpc-fix-kfree-oops-in-gss-proxy-code.patch zram-avoid-access-beyond-the-zram-device.patch zram-avoid-double-free-in-function-zram_bvec_write.patch zram-avoid-invalid-memory-access-in-zram_exit.patch zram-destroy-all-devices-on-error-recovery-path-in-zram_init.patch zram-protect-sysfs-handler-from-invalid-memory-access.patch zram-use-zram-lock-to-protect-zram_free_page-in-swap-free-notify-path.patch --- ...attery-fix-parsing-_bix-return-value.patch | 49 ++++++++++++ ...wifiex-add-missing-endian-conversion.patch | 34 +++++++++ ...stead-of-bss_mode-for-sta-operations.patch | 57 ++++++++++++++ ...x-fix-wrong-data-rates-in-p2p-client.patch | 34 +++++++++ queue-3.10/rt2x00-fix-stop-queue.patch | 74 +++++++++++++++++++ queue-3.10/series | 14 ++++ ...crpc-fix-gss-proxy-xdr-decoding-oops.patch | 49 ++++++++++++ ...crpc-fix-gss_rpc_upcall-create-error.patch | 27 +++++++ ...rpc-fix-kfree-oops-in-gss-proxy-code.patch | 28 +++++++ ...-avoid-access-beyond-the-zram-device.patch | 50 +++++++++++++ ...ble-free-in-function-zram_bvec_write.patch | 31 ++++++++ ...d-invalid-memory-access-in-zram_exit.patch | 40 ++++++++++ ...-on-error-recovery-path-in-zram_init.patch | 73 ++++++++++++++++++ ...s-handler-from-invalid-memory-access.patch | 40 ++++++++++ ...m_free_page-in-swap-free-notify-path.patch | 56 ++++++++++++++ 15 files changed, 656 insertions(+) create mode 100644 queue-3.10/acpi-battery-fix-parsing-_bix-return-value.patch create mode 100644 queue-3.10/mwifiex-add-missing-endian-conversion.patch create mode 100644 queue-3.10/mwifiex-check-for-bss_role-instead-of-bss_mode-for-sta-operations.patch create mode 100644 queue-3.10/mwifiex-fix-wrong-data-rates-in-p2p-client.patch create mode 100644 queue-3.10/rt2x00-fix-stop-queue.patch create mode 100644 queue-3.10/svcrpc-fix-gss-proxy-xdr-decoding-oops.patch create mode 100644 queue-3.10/svcrpc-fix-gss_rpc_upcall-create-error.patch create mode 100644 queue-3.10/svcrpc-fix-kfree-oops-in-gss-proxy-code.patch create mode 100644 queue-3.10/zram-avoid-access-beyond-the-zram-device.patch create mode 100644 queue-3.10/zram-avoid-double-free-in-function-zram_bvec_write.patch create mode 100644 queue-3.10/zram-avoid-invalid-memory-access-in-zram_exit.patch create mode 100644 queue-3.10/zram-destroy-all-devices-on-error-recovery-path-in-zram_init.patch create mode 100644 queue-3.10/zram-protect-sysfs-handler-from-invalid-memory-access.patch create mode 100644 queue-3.10/zram-use-zram-lock-to-protect-zram_free_page-in-swap-free-notify-path.patch diff --git a/queue-3.10/acpi-battery-fix-parsing-_bix-return-value.patch b/queue-3.10/acpi-battery-fix-parsing-_bix-return-value.patch new file mode 100644 index 00000000000..06e413163e2 --- /dev/null +++ b/queue-3.10/acpi-battery-fix-parsing-_bix-return-value.patch @@ -0,0 +1,49 @@ +From 016d5baad04269e8559332df05f89bd95b52d6ad Mon Sep 17 00:00:00 2001 +From: Lan Tianyu +Date: Tue, 30 Jul 2013 14:00:42 +0200 +Subject: ACPI / battery: Fix parsing _BIX return value + +From: Lan Tianyu + +commit 016d5baad04269e8559332df05f89bd95b52d6ad upstream. + +The _BIX method returns extended battery info as a package. +According the ACPI spec (ACPI 5, Section 10.2.2.2), the first member +of that package should be "Revision". However, the current ACPI +battery driver treats the first member as "Power Unit" which should +be the second member. This causes the result of _BIX return data +parsing to be incorrect. + +Fix this by adding a new member called 'revision' to struct +acpi_battery and adding the offsetof() information on it to +extended_info_offsets[] as the first row. + +[rjw: Changelog] +Reported-and-tested-by: Jan Hoffmann +References: http://bugzilla.kernel.org/show_bug.cgi?id=60519 +Signed-off-by: Lan Tianyu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/battery.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -117,6 +117,7 @@ struct acpi_battery { + struct acpi_device *device; + struct notifier_block pm_nb; + unsigned long update_time; ++ int revision; + int rate_now; + int capacity_now; + int voltage_now; +@@ -359,6 +360,7 @@ static struct acpi_offsets info_offsets[ + }; + + static struct acpi_offsets extended_info_offsets[] = { ++ {offsetof(struct acpi_battery, revision), 0}, + {offsetof(struct acpi_battery, power_unit), 0}, + {offsetof(struct acpi_battery, design_capacity), 0}, + {offsetof(struct acpi_battery, full_charge_capacity), 0}, diff --git a/queue-3.10/mwifiex-add-missing-endian-conversion.patch b/queue-3.10/mwifiex-add-missing-endian-conversion.patch new file mode 100644 index 00000000000..3e5585b0169 --- /dev/null +++ b/queue-3.10/mwifiex-add-missing-endian-conversion.patch @@ -0,0 +1,34 @@ +From 83e612f632c3897be29ef02e0472f6d63e258378 Mon Sep 17 00:00:00 2001 +From: Tomasz Moń +Date: Tue, 23 Jul 2013 07:42:49 +0200 +Subject: mwifiex: Add missing endian conversion. + +From: Tomasz Moń + +commit 83e612f632c3897be29ef02e0472f6d63e258378 upstream. + +Both type and pkt_len variables are in host endian and these should be in +Little Endian in the payload. + +Signed-off-by: Tomasz Moń +Acked-by: Bing Zhao +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mwifiex/sdio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/mwifiex/sdio.c ++++ b/drivers/net/wireless/mwifiex/sdio.c +@@ -1441,8 +1441,8 @@ static int mwifiex_sdio_host_to_card(str + /* Allocate buffer and copy payload */ + blk_size = MWIFIEX_SDIO_BLOCK_SIZE; + buf_block_len = (pkt_len + blk_size - 1) / blk_size; +- *(u16 *) &payload[0] = (u16) pkt_len; +- *(u16 *) &payload[2] = type; ++ *(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len); ++ *(__le16 *)&payload[2] = cpu_to_le16(type); + + /* + * This is SDIO specific header diff --git a/queue-3.10/mwifiex-check-for-bss_role-instead-of-bss_mode-for-sta-operations.patch b/queue-3.10/mwifiex-check-for-bss_role-instead-of-bss_mode-for-sta-operations.patch new file mode 100644 index 00000000000..ee4179c8676 --- /dev/null +++ b/queue-3.10/mwifiex-check-for-bss_role-instead-of-bss_mode-for-sta-operations.patch @@ -0,0 +1,57 @@ +From 953b3539ef9301b8ef73f4b6e2fd824b86aae65a Mon Sep 17 00:00:00 2001 +From: Avinash Patil +Date: Mon, 29 Jul 2013 16:32:37 -0700 +Subject: mwifiex: check for bss_role instead of bss_mode for STA operations + +From: Avinash Patil + +commit 953b3539ef9301b8ef73f4b6e2fd824b86aae65a upstream. + +This patch fixes an issue wherein association would fail on P2P +interfaces. This happened because we are checking priv->mode +against NL80211_IFTYPE_STATION. While this check is correct for +infrastructure stations, it would fail P2P clients for which mode +is NL80211_IFTYPE_P2P_CLIENT. + +Better check would be bss_role which has only 2 values: STA/AP. + +Signed-off-by: Avinash Patil +Signed-off-by: Stone Piao +Signed-off-by: Bing Zhao +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mwifiex/cfg80211.c | 4 ++-- + drivers/net/wireless/mwifiex/join.c | 6 ++++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/mwifiex/cfg80211.c +@@ -1668,9 +1668,9 @@ mwifiex_cfg80211_connect(struct wiphy *w + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + int ret; + +- if (priv->bss_mode != NL80211_IFTYPE_STATION) { ++ if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) { + wiphy_err(wiphy, +- "%s: reject infra assoc request in non-STA mode\n", ++ "%s: reject infra assoc request in non-STA role\n", + dev->name); + return -EINVAL; + } +--- a/drivers/net/wireless/mwifiex/join.c ++++ b/drivers/net/wireless/mwifiex/join.c +@@ -1290,8 +1290,10 @@ int mwifiex_associate(struct mwifiex_pri + { + u8 current_bssid[ETH_ALEN]; + +- /* Return error if the adapter or table entry is not marked as infra */ +- if ((priv->bss_mode != NL80211_IFTYPE_STATION) || ++ /* Return error if the adapter is not STA role or table entry ++ * is not marked as infra. ++ */ ++ if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) || + (bss_desc->bss_mode != NL80211_IFTYPE_STATION)) + return -1; + diff --git a/queue-3.10/mwifiex-fix-wrong-data-rates-in-p2p-client.patch b/queue-3.10/mwifiex-fix-wrong-data-rates-in-p2p-client.patch new file mode 100644 index 00000000000..4bc26425ed3 --- /dev/null +++ b/queue-3.10/mwifiex-fix-wrong-data-rates-in-p2p-client.patch @@ -0,0 +1,34 @@ +From 237b2ac8ac89a6b0120decdd05c7bf4637deb98a Mon Sep 17 00:00:00 2001 +From: Avinash Patil +Date: Mon, 29 Jul 2013 16:32:38 -0700 +Subject: mwifiex: fix wrong data rates in P2P client + +From: Avinash Patil + +commit 237b2ac8ac89a6b0120decdd05c7bf4637deb98a upstream. + +This patch fixes an issue wherein adhoc rates were being copied +into association request from P2P client. + +Signed-off-by: Avinash Patil +Signed-off-by: Stone Piao +Signed-off-by: Bing Zhao +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mwifiex/cfp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/mwifiex/cfp.c ++++ b/drivers/net/wireless/mwifiex/cfp.c +@@ -415,7 +415,8 @@ u32 mwifiex_get_supported_rates(struct m + u32 k = 0; + struct mwifiex_adapter *adapter = priv->adapter; + +- if (priv->bss_mode == NL80211_IFTYPE_STATION) { ++ if (priv->bss_mode == NL80211_IFTYPE_STATION || ++ priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) { + switch (adapter->config_bands) { + case BAND_B: + dev_dbg(adapter->dev, "info: infra band=%d " diff --git a/queue-3.10/rt2x00-fix-stop-queue.patch b/queue-3.10/rt2x00-fix-stop-queue.patch new file mode 100644 index 00000000000..6b3d6690c96 --- /dev/null +++ b/queue-3.10/rt2x00-fix-stop-queue.patch @@ -0,0 +1,74 @@ +From e2288b66fe7ff0288382b2af671b4da558b44472 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sun, 28 Jul 2013 13:17:22 +0200 +Subject: rt2x00: fix stop queue + +From: Stanislaw Gruszka + +commit e2288b66fe7ff0288382b2af671b4da558b44472 upstream. + +Since we clear QUEUE_STARTED in rt2x00queue_stop_queue(), following +call to rt2x00queue_pause_queue() reduce to noop, i.e we do not +stop queue in mac80211. + +To fix that introduce rt2x00queue_pause_queue_nocheck() function, +which will stop queue in mac80211 directly. + +Note that rt2x00_start_queue() explicitly set QUEUE_PAUSED bit. + +Note also that reordering operations i.e. first call to +rt2x00queue_pause_queue() and then clear QUEUE_STARTED bit, will race +with rt2x00queue_unpause_queue(), so calling ieee80211_stop_queue() +directly is the only available solution to fix the problem without +major rework. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rt2x00/rt2x00queue.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c +@@ -936,13 +936,8 @@ void rt2x00queue_index_inc(struct queue_ + spin_unlock_irqrestore(&queue->index_lock, irqflags); + } + +-void rt2x00queue_pause_queue(struct data_queue *queue) ++void rt2x00queue_pause_queue_nocheck(struct data_queue *queue) + { +- if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || +- !test_bit(QUEUE_STARTED, &queue->flags) || +- test_and_set_bit(QUEUE_PAUSED, &queue->flags)) +- return; +- + switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: +@@ -958,6 +953,15 @@ void rt2x00queue_pause_queue(struct data + break; + } + } ++void rt2x00queue_pause_queue(struct data_queue *queue) ++{ ++ if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || ++ !test_bit(QUEUE_STARTED, &queue->flags) || ++ test_and_set_bit(QUEUE_PAUSED, &queue->flags)) ++ return; ++ ++ rt2x00queue_pause_queue_nocheck(queue); ++} + EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); + + void rt2x00queue_unpause_queue(struct data_queue *queue) +@@ -1019,7 +1023,7 @@ void rt2x00queue_stop_queue(struct data_ + return; + } + +- rt2x00queue_pause_queue(queue); ++ rt2x00queue_pause_queue_nocheck(queue); + + queue->rt2x00dev->ops->lib->stop_queue(queue); + diff --git a/queue-3.10/series b/queue-3.10/series index ee6d81eb371..90b71d798d4 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -52,3 +52,17 @@ bluetooth-add-support-for-atheros.patch bluetooth-add-support-for-atheros_2.patch bluetooth-add-support-for-mediatek-bluetooth-device.patch bluetooth-fix-wrong-use-of-ptr_err-in-btusb.patch +svcrpc-fix-gss-proxy-xdr-decoding-oops.patch +svcrpc-fix-gss_rpc_upcall-create-error.patch +svcrpc-fix-kfree-oops-in-gss-proxy-code.patch +rt2x00-fix-stop-queue.patch +mwifiex-add-missing-endian-conversion.patch +mwifiex-check-for-bss_role-instead-of-bss_mode-for-sta-operations.patch +mwifiex-fix-wrong-data-rates-in-p2p-client.patch +zram-avoid-invalid-memory-access-in-zram_exit.patch +zram-use-zram-lock-to-protect-zram_free_page-in-swap-free-notify-path.patch +zram-destroy-all-devices-on-error-recovery-path-in-zram_init.patch +zram-avoid-double-free-in-function-zram_bvec_write.patch +zram-avoid-access-beyond-the-zram-device.patch +zram-protect-sysfs-handler-from-invalid-memory-access.patch +acpi-battery-fix-parsing-_bix-return-value.patch diff --git a/queue-3.10/svcrpc-fix-gss-proxy-xdr-decoding-oops.patch b/queue-3.10/svcrpc-fix-gss-proxy-xdr-decoding-oops.patch new file mode 100644 index 00000000000..eaa5500b14a --- /dev/null +++ b/queue-3.10/svcrpc-fix-gss-proxy-xdr-decoding-oops.patch @@ -0,0 +1,49 @@ +From dc43376c26cef74226174a2394f37f2a3f8a8639 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Fri, 7 Jun 2013 10:11:19 -0400 +Subject: svcrpc: fix gss-proxy xdr decoding oops + +From: "J. Bruce Fields" + +commit dc43376c26cef74226174a2394f37f2a3f8a8639 upstream. + +Uninitialized stack data was being used as the destination for memcpy's. + +Longer term we'll just delete some of this code; all we're doing is +skipping over xdr that we don't care about. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/auth_gss/gss_rpc_xdr.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c ++++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c +@@ -430,7 +430,7 @@ static int dummy_enc_nameattr_array(stru + static int dummy_dec_nameattr_array(struct xdr_stream *xdr, + struct gssx_name_attr_array *naa) + { +- struct gssx_name_attr dummy; ++ struct gssx_name_attr dummy = { .attr = {.len = 0} }; + u32 count, i; + __be32 *p; + +@@ -493,12 +493,13 @@ static int gssx_enc_name(struct xdr_stre + return err; + } + ++ + static int gssx_dec_name(struct xdr_stream *xdr, + struct gssx_name *name) + { +- struct xdr_netobj dummy_netobj; +- struct gssx_name_attr_array dummy_name_attr_array; +- struct gssx_option_array dummy_option_array; ++ struct xdr_netobj dummy_netobj = { .len = 0 }; ++ struct gssx_name_attr_array dummy_name_attr_array = { .count = 0 }; ++ struct gssx_option_array dummy_option_array = { .count = 0 }; + int err; + + /* name->display_name */ diff --git a/queue-3.10/svcrpc-fix-gss_rpc_upcall-create-error.patch b/queue-3.10/svcrpc-fix-gss_rpc_upcall-create-error.patch new file mode 100644 index 00000000000..cd360fb751f --- /dev/null +++ b/queue-3.10/svcrpc-fix-gss_rpc_upcall-create-error.patch @@ -0,0 +1,27 @@ +From 9f96392b0ae6aefc02a9b900c3f4889dfafc8402 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Mon, 10 Jun 2013 16:06:44 -0400 +Subject: svcrpc: fix gss_rpc_upcall create error + +From: "J. Bruce Fields" + +commit 9f96392b0ae6aefc02a9b900c3f4889dfafc8402 upstream. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/auth_gss/gss_rpc_upcall.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sunrpc/auth_gss/gss_rpc_upcall.c ++++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c +@@ -120,7 +120,7 @@ static int gssp_rpc_create(struct net *n + if (IS_ERR(clnt)) { + dprintk("RPC: failed to create AF_LOCAL gssproxy " + "client (errno %ld).\n", PTR_ERR(clnt)); +- result = -PTR_ERR(clnt); ++ result = PTR_ERR(clnt); + *_clnt = NULL; + goto out; + } diff --git a/queue-3.10/svcrpc-fix-kfree-oops-in-gss-proxy-code.patch b/queue-3.10/svcrpc-fix-kfree-oops-in-gss-proxy-code.patch new file mode 100644 index 00000000000..391377d1d19 --- /dev/null +++ b/queue-3.10/svcrpc-fix-kfree-oops-in-gss-proxy-code.patch @@ -0,0 +1,28 @@ +From 743e217129f69aab074abe520a464fd0c6b1cca1 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Wed, 31 Jul 2013 14:11:14 -0400 +Subject: svcrpc: fix kfree oops in gss-proxy code + +From: "J. Bruce Fields" + +commit 743e217129f69aab074abe520a464fd0c6b1cca1 upstream. + +mech_oid.data is an array, not kmalloc()'d memory. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/auth_gss/gss_rpc_upcall.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/sunrpc/auth_gss/gss_rpc_upcall.c ++++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c +@@ -328,7 +328,6 @@ void gssp_free_upcall_data(struct gssp_u + kfree(data->in_handle.data); + kfree(data->out_handle.data); + kfree(data->out_token.data); +- kfree(data->mech_oid.data); + free_svc_cred(&data->creds); + } + diff --git a/queue-3.10/zram-avoid-access-beyond-the-zram-device.patch b/queue-3.10/zram-avoid-access-beyond-the-zram-device.patch new file mode 100644 index 00000000000..1a481640ff1 --- /dev/null +++ b/queue-3.10/zram-avoid-access-beyond-the-zram-device.patch @@ -0,0 +1,50 @@ +From 12a7ad3b810e77137d0caf97a6dd97591e075b30 Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 7 Jun 2013 00:07:26 +0800 +Subject: zram: avoid access beyond the zram device + +From: Jiang Liu + +commit 12a7ad3b810e77137d0caf97a6dd97591e075b30 upstream. + +Function valid_io_request() should verify the entire request are within +the zram device address range. Otherwise it may cause invalid memory +access when accessing/modifying zram->meta->table[index] because the +'index' is out of range. Then it may access non-exist memory, randomly +modify memory belong to other subsystems, which is hard to track down. + +Signed-off-by: Jiang Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/zram/zram_drv.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -420,13 +420,20 @@ out: + */ + static inline int valid_io_request(struct zram *zram, struct bio *bio) + { +- if (unlikely( +- (bio->bi_sector >= (zram->disksize >> SECTOR_SHIFT)) || +- (bio->bi_sector & (ZRAM_SECTOR_PER_LOGICAL_BLOCK - 1)) || +- (bio->bi_size & (ZRAM_LOGICAL_BLOCK_SIZE - 1)))) { ++ u64 start, end, bound; ++ ++ /* unaligned request */ ++ if (unlikely(bio->bi_sector & (ZRAM_SECTOR_PER_LOGICAL_BLOCK - 1))) ++ return 0; ++ if (unlikely(bio->bi_size & (ZRAM_LOGICAL_BLOCK_SIZE - 1))) ++ return 0; + ++ start = bio->bi_sector; ++ end = start + (bio->bi_size >> SECTOR_SHIFT); ++ bound = zram->disksize >> SECTOR_SHIFT; ++ /* out of range range */ ++ if (unlikely(start >= bound || end >= bound || start > end)) + return 0; +- } + + /* I/O request is valid */ + return 1; diff --git a/queue-3.10/zram-avoid-double-free-in-function-zram_bvec_write.patch b/queue-3.10/zram-avoid-double-free-in-function-zram_bvec_write.patch new file mode 100644 index 00000000000..3336f08226d --- /dev/null +++ b/queue-3.10/zram-avoid-double-free-in-function-zram_bvec_write.patch @@ -0,0 +1,31 @@ +From 65c484609a3b25c35e4edcd5f2c38f98f5226093 Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 7 Jun 2013 00:07:25 +0800 +Subject: zram: avoid double free in function zram_bvec_write() + +From: Jiang Liu + +commit 65c484609a3b25c35e4edcd5f2c38f98f5226093 upstream. + +When doing a patial write and the whole page is filled with zero, +zram_bvec_write() will free uncmem twice. + +Signed-off-by: Jiang Liu +Acked-by: Minchan Kim +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/zram/zram_drv.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -272,8 +272,6 @@ static int zram_bvec_write(struct zram * + + if (page_zero_filled(uncmem)) { + kunmap_atomic(user_mem); +- if (is_partial_io(bvec)) +- kfree(uncmem); + zram->stats.pages_zero++; + zram_set_flag(meta, index, ZRAM_ZERO); + ret = 0; diff --git a/queue-3.10/zram-avoid-invalid-memory-access-in-zram_exit.patch b/queue-3.10/zram-avoid-invalid-memory-access-in-zram_exit.patch new file mode 100644 index 00000000000..972bec46843 --- /dev/null +++ b/queue-3.10/zram-avoid-invalid-memory-access-in-zram_exit.patch @@ -0,0 +1,40 @@ +From 6030ea9b35971a4200062f010341ab832e878ac9 Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 7 Jun 2013 00:07:22 +0800 +Subject: zram: avoid invalid memory access in zram_exit() + +From: Jiang Liu + +commit 6030ea9b35971a4200062f010341ab832e878ac9 upstream. + +Memory for zram->disk object may have already been freed after returning +from destroy_device(zram), then it's unsafe for zram_reset_device(zram) +to access zram->disk again. + +We can't solve this bug by flipping the order of destroy_device(zram) +and zram_reset_device(zram), that will cause deadlock issues to the +zram sysfs handler. + +So fix it by holding an extra reference to zram->disk before calling +destroy_device(zram). + +Signed-off-by: Jiang Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/zram/zram_drv.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -727,8 +727,10 @@ static void __exit zram_exit(void) + for (i = 0; i < num_devices; i++) { + zram = &zram_devices[i]; + ++ get_disk(zram->disk); + destroy_device(zram); + zram_reset_device(zram); ++ put_disk(zram->disk); + } + + unregister_blkdev(zram_major, "zram"); diff --git a/queue-3.10/zram-destroy-all-devices-on-error-recovery-path-in-zram_init.patch b/queue-3.10/zram-destroy-all-devices-on-error-recovery-path-in-zram_init.patch new file mode 100644 index 00000000000..80fb7d7a5f7 --- /dev/null +++ b/queue-3.10/zram-destroy-all-devices-on-error-recovery-path-in-zram_init.patch @@ -0,0 +1,73 @@ +From 39a9b8ac9333e4268ecff7da6c9d1ab3823ff243 Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 7 Jun 2013 00:07:24 +0800 +Subject: zram: destroy all devices on error recovery path in zram_init() + +From: Jiang Liu + +commit 39a9b8ac9333e4268ecff7da6c9d1ab3823ff243 upstream. + +On error recovery path of zram_init(), it leaks the zram device object +causing the failure. So change create_device() to free allocated +resources on error path. + +Signed-off-by: Jiang Liu +Acked-by: Minchan Kim +Acked-by: Jerome Marchand +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/zram/zram_drv.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -595,7 +595,7 @@ static const struct block_device_operati + + static int create_device(struct zram *zram, int device_id) + { +- int ret = 0; ++ int ret = -ENOMEM; + + init_rwsem(&zram->lock); + init_rwsem(&zram->init_lock); +@@ -605,7 +605,6 @@ static int create_device(struct zram *zr + if (!zram->queue) { + pr_err("Error allocating disk queue for device %d\n", + device_id); +- ret = -ENOMEM; + goto out; + } + +@@ -615,11 +614,9 @@ static int create_device(struct zram *zr + /* gendisk structure */ + zram->disk = alloc_disk(1); + if (!zram->disk) { +- blk_cleanup_queue(zram->queue); + pr_warn("Error allocating disk structure for device %d\n", + device_id); +- ret = -ENOMEM; +- goto out; ++ goto out_free_queue; + } + + zram->disk->major = zram_major; +@@ -648,11 +645,17 @@ static int create_device(struct zram *zr + &zram_disk_attr_group); + if (ret < 0) { + pr_warn("Error creating sysfs group"); +- goto out; ++ goto out_free_disk; + } + + zram->init_done = 0; ++ return 0; + ++out_free_disk: ++ del_gendisk(zram->disk); ++ put_disk(zram->disk); ++out_free_queue: ++ blk_cleanup_queue(zram->queue); + out: + return ret; + } diff --git a/queue-3.10/zram-protect-sysfs-handler-from-invalid-memory-access.patch b/queue-3.10/zram-protect-sysfs-handler-from-invalid-memory-access.patch new file mode 100644 index 00000000000..39bb6158e6d --- /dev/null +++ b/queue-3.10/zram-protect-sysfs-handler-from-invalid-memory-access.patch @@ -0,0 +1,40 @@ +From 5863e10b441e7ea4b492f930f1be180a97d026f3 Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 7 Jun 2013 00:07:27 +0800 +Subject: zram: protect sysfs handler from invalid memory access + +From: Jiang Liu + +commit 5863e10b441e7ea4b492f930f1be180a97d026f3 upstream. + +Use zram->init_lock to protect access to zram->meta, otherwise it +may cause invalid memory access if zram->meta has been freed by +zram_reset_device(). + +This issue may be triggered by: +Thread 1: +while true; do cat mem_used_total; done +Thread 2: +while true; do echo 8M > disksize; echo 1 > reset; done + +Signed-off-by: Jiang Liu +Acked-by: Minchan Kim +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/zram/zram_sysfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/staging/zram/zram_sysfs.c ++++ b/drivers/staging/zram/zram_sysfs.c +@@ -188,8 +188,10 @@ static ssize_t mem_used_total_show(struc + struct zram *zram = dev_to_zram(dev); + struct zram_meta *meta = zram->meta; + ++ down_read(&zram->init_lock); + if (zram->init_done) + val = zs_get_total_size_bytes(meta->mem_pool); ++ up_read(&zram->init_lock); + + return sprintf(buf, "%llu\n", val); + } diff --git a/queue-3.10/zram-use-zram-lock-to-protect-zram_free_page-in-swap-free-notify-path.patch b/queue-3.10/zram-use-zram-lock-to-protect-zram_free_page-in-swap-free-notify-path.patch new file mode 100644 index 00000000000..94dc5223f41 --- /dev/null +++ b/queue-3.10/zram-use-zram-lock-to-protect-zram_free_page-in-swap-free-notify-path.patch @@ -0,0 +1,56 @@ +From 57ab048532c0d975538cebd4456491b5c34248f4 Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 7 Jun 2013 00:07:23 +0800 +Subject: zram: use zram->lock to protect zram_free_page() in swap free notify path + +From: Jiang Liu + +commit 57ab048532c0d975538cebd4456491b5c34248f4 upstream. + +zram_slot_free_notify() is free-running without any protection from +concurrent operations. So there are race conditions between +zram_bvec_read()/zram_bvec_write() and zram_slot_free_notify(), +and possible consequences include: +1) Trigger BUG_ON(!handle) on zram_bvec_write() side. +2) Access to freed pages on zram_bvec_read() side. +3) Break some fields (bad_compress, good_compress, pages_stored) + in zram->stats if the swap layer makes concurrently call to + zram_slot_free_notify(). + +So enhance zram_slot_free_notify() to acquire writer lock on zram->lock +before calling zram_free_page(). + +Signed-off-by: Jiang Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/zram/zram_drv.c | 2 ++ + drivers/staging/zram/zram_drv.h | 5 +++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -582,7 +582,9 @@ static void zram_slot_free_notify(struct + struct zram *zram; + + zram = bdev->bd_disk->private_data; ++ down_write(&zram->lock); + zram_free_page(zram, index); ++ up_write(&zram->lock); + zram_stat64_inc(zram, &zram->stats.notify_free); + } + +--- a/drivers/staging/zram/zram_drv.h ++++ b/drivers/staging/zram/zram_drv.h +@@ -93,8 +93,9 @@ struct zram_meta { + struct zram { + struct zram_meta *meta; + spinlock_t stat64_lock; /* protect 64-bit stats */ +- struct rw_semaphore lock; /* protect compression buffers and table +- * against concurrent read and writes */ ++ struct rw_semaphore lock; /* protect compression buffers, table, ++ * 32bit stat counters against concurrent ++ * notifications, reads and writes */ + struct request_queue *queue; + struct gendisk *disk; + int init_done; -- 2.47.3