From: Greg Kroah-Hartman Date: Mon, 11 Mar 2013 21:21:48 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.8.3~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66c0c0d113a79794630d7d745e4866cbd0dc3046;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: crypto-user-fix-info-leaks-in-report-api.patch xen-pat-disable-pat-using-pat_enabled-value.patch --- diff --git a/queue-3.4/crypto-user-fix-info-leaks-in-report-api.patch b/queue-3.4/crypto-user-fix-info-leaks-in-report-api.patch new file mode 100644 index 00000000000..2cb0f20b355 --- /dev/null +++ b/queue-3.4/crypto-user-fix-info-leaks-in-report-api.patch @@ -0,0 +1,209 @@ +From 9a5467bf7b6e9e02ec9c3da4e23747c05faeaac6 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Tue, 5 Feb 2013 18:19:13 +0100 +Subject: crypto: user - fix info leaks in report API + +From: Mathias Krause + +commit 9a5467bf7b6e9e02ec9c3da4e23747c05faeaac6 upstream. + +Three errors resulting in kernel memory disclosure: + +1/ The structures used for the netlink based crypto algorithm report API +are located on the stack. As snprintf() does not fill the remainder of +the buffer with null bytes, those stack bytes will be disclosed to users +of the API. Switch to strncpy() to fix this. + +2/ crypto_report_one() does not initialize all field of struct +crypto_user_alg. Fix this to fix the heap info leak. + +3/ For the module name we should copy only as many bytes as +module_name() returns -- not as much as the destination buffer could +hold. But the current code does not and therefore copies random data +from behind the end of the module name, as the module name is always +shorter than CRYPTO_MAX_ALG_NAME. + +Also switch to use strncpy() to copy the algorithm's name and +driver_name. They are strings, after all. + +Signed-off-by: Mathias Krause +Cc: Steffen Klassert +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/ablkcipher.c | 12 ++++++------ + crypto/aead.c | 9 ++++----- + crypto/ahash.c | 2 +- + crypto/blkcipher.c | 6 +++--- + crypto/crypto_user.c | 20 ++++++++++---------- + crypto/pcompress.c | 3 +-- + crypto/rng.c | 2 +- + crypto/shash.c | 3 ++- + 8 files changed, 28 insertions(+), 29 deletions(-) + +--- a/crypto/ablkcipher.c ++++ b/crypto/ablkcipher.c +@@ -388,9 +388,9 @@ static int crypto_ablkcipher_report(stru + { + struct crypto_report_blkcipher rblkcipher; + +- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher"); +- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s", +- alg->cra_ablkcipher.geniv ?: ""); ++ strncpy(rblkcipher.type, "ablkcipher", sizeof(rblkcipher.type)); ++ strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "", ++ sizeof(rblkcipher.geniv)); + + rblkcipher.blocksize = alg->cra_blocksize; + rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize; +@@ -469,9 +469,9 @@ static int crypto_givcipher_report(struc + { + struct crypto_report_blkcipher rblkcipher; + +- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher"); +- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s", +- alg->cra_ablkcipher.geniv ?: ""); ++ strncpy(rblkcipher.type, "givcipher", sizeof(rblkcipher.type)); ++ strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "", ++ sizeof(rblkcipher.geniv)); + + rblkcipher.blocksize = alg->cra_blocksize; + rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize; +--- a/crypto/aead.c ++++ b/crypto/aead.c +@@ -117,9 +117,8 @@ static int crypto_aead_report(struct sk_ + struct crypto_report_aead raead; + struct aead_alg *aead = &alg->cra_aead; + +- snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead"); +- snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", +- aead->geniv ?: ""); ++ strncpy(raead.type, "aead", sizeof(raead.type)); ++ strncpy(raead.geniv, aead->geniv ?: "", sizeof(raead.geniv)); + + raead.blocksize = alg->cra_blocksize; + raead.maxauthsize = aead->maxauthsize; +@@ -203,8 +202,8 @@ static int crypto_nivaead_report(struct + struct crypto_report_aead raead; + struct aead_alg *aead = &alg->cra_aead; + +- snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead"); +- snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv); ++ strncpy(raead.type, "nivaead", sizeof(raead.type)); ++ strncpy(raead.geniv, aead->geniv, sizeof(raead.geniv)); + + raead.blocksize = alg->cra_blocksize; + raead.maxauthsize = aead->maxauthsize; +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -404,7 +404,7 @@ static int crypto_ahash_report(struct sk + { + struct crypto_report_hash rhash; + +- snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash"); ++ strncpy(rhash.type, "ahash", sizeof(rhash.type)); + + rhash.blocksize = alg->cra_blocksize; + rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize; +--- a/crypto/blkcipher.c ++++ b/crypto/blkcipher.c +@@ -499,9 +499,9 @@ static int crypto_blkcipher_report(struc + { + struct crypto_report_blkcipher rblkcipher; + +- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher"); +- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s", +- alg->cra_blkcipher.geniv ?: ""); ++ strncpy(rblkcipher.type, "blkcipher", sizeof(rblkcipher.type)); ++ strncpy(rblkcipher.geniv, alg->cra_blkcipher.geniv ?: "", ++ sizeof(rblkcipher.geniv)); + + rblkcipher.blocksize = alg->cra_blocksize; + rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize; +--- a/crypto/crypto_user.c ++++ b/crypto/crypto_user.c +@@ -75,7 +75,7 @@ static int crypto_report_cipher(struct s + { + struct crypto_report_cipher rcipher; + +- snprintf(rcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "cipher"); ++ strncpy(rcipher.type, "cipher", sizeof(rcipher.type)); + + rcipher.blocksize = alg->cra_blocksize; + rcipher.min_keysize = alg->cra_cipher.cia_min_keysize; +@@ -94,8 +94,7 @@ static int crypto_report_comp(struct sk_ + { + struct crypto_report_comp rcomp; + +- snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression"); +- ++ strncpy(rcomp.type, "compression", sizeof(rcomp.type)); + NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS, + sizeof(struct crypto_report_comp), &rcomp); + +@@ -108,12 +107,14 @@ nla_put_failure: + static int crypto_report_one(struct crypto_alg *alg, + struct crypto_user_alg *ualg, struct sk_buff *skb) + { +- memcpy(&ualg->cru_name, &alg->cra_name, sizeof(ualg->cru_name)); +- memcpy(&ualg->cru_driver_name, &alg->cra_driver_name, +- sizeof(ualg->cru_driver_name)); +- memcpy(&ualg->cru_module_name, module_name(alg->cra_module), +- CRYPTO_MAX_ALG_NAME); ++ strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name)); ++ strncpy(ualg->cru_driver_name, alg->cra_driver_name, ++ sizeof(ualg->cru_driver_name)); ++ strncpy(ualg->cru_module_name, module_name(alg->cra_module), ++ sizeof(ualg->cru_module_name)); + ++ ualg->cru_type = 0; ++ ualg->cru_mask = 0; + ualg->cru_flags = alg->cra_flags; + ualg->cru_refcnt = atomic_read(&alg->cra_refcnt); + +@@ -122,8 +123,7 @@ static int crypto_report_one(struct cryp + if (alg->cra_flags & CRYPTO_ALG_LARVAL) { + struct crypto_report_larval rl; + +- snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval"); +- ++ strncpy(rl.type, "larval", sizeof(rl.type)); + NLA_PUT(skb, CRYPTOCFGA_REPORT_LARVAL, + sizeof(struct crypto_report_larval), &rl); + +--- a/crypto/pcompress.c ++++ b/crypto/pcompress.c +@@ -53,8 +53,7 @@ static int crypto_pcomp_report(struct sk + { + struct crypto_report_comp rpcomp; + +- snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp"); +- ++ strncpy(rpcomp.type, "pcomp", sizeof(rpcomp.type)); + NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS, + sizeof(struct crypto_report_comp), &rpcomp); + +--- a/crypto/rng.c ++++ b/crypto/rng.c +@@ -65,7 +65,7 @@ static int crypto_rng_report(struct sk_b + { + struct crypto_report_rng rrng; + +- snprintf(rrng.type, CRYPTO_MAX_ALG_NAME, "%s", "rng"); ++ strncpy(rrng.type, "rng", sizeof(rrng.type)); + + rrng.seedsize = alg->cra_rng.seedsize; + +--- a/crypto/shash.c ++++ b/crypto/shash.c +@@ -530,7 +530,8 @@ static int crypto_shash_report(struct sk + struct crypto_report_hash rhash; + struct shash_alg *salg = __crypto_shash_alg(alg); + +- snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash"); ++ strncpy(rhash.type, "shash", sizeof(rhash.type)); ++ + rhash.blocksize = alg->cra_blocksize; + rhash.digestsize = salg->digestsize; + diff --git a/queue-3.4/series b/queue-3.4/series index f74c36f3bf9..2e4918d2f83 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -25,3 +25,5 @@ alsa-ice1712-initialize-card-private_data-properly.patch alsa-vmaster-fix-slave-change-notification.patch e1000e-fix-pci-device-enable-counter-balance.patch hid-logitech-dj-do-not-directly-call-hid_output_raw_report-during-probe.patch +xen-pat-disable-pat-using-pat_enabled-value.patch +crypto-user-fix-info-leaks-in-report-api.patch diff --git a/queue-3.4/xen-pat-disable-pat-using-pat_enabled-value.patch b/queue-3.4/xen-pat-disable-pat-using-pat_enabled-value.patch new file mode 100644 index 00000000000..8b8238805aa --- /dev/null +++ b/queue-3.4/xen-pat-disable-pat-using-pat_enabled-value.patch @@ -0,0 +1,121 @@ +From c79c49826270b8b0061b2fca840fc3f013c8a78a Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Tue, 26 Feb 2013 12:51:27 -0500 +Subject: xen/pat: Disable PAT using pat_enabled value. + +From: Konrad Rzeszutek Wilk + +commit c79c49826270b8b0061b2fca840fc3f013c8a78a upstream. + +The git commit 8eaffa67b43e99ae581622c5133e20b0f48bcef1 +(xen/pat: Disable PAT support for now) explains in details why +we want to disable PAT for right now. However that +change was not enough and we should have also disabled +the pat_enabled value. Otherwise we end up with: + +mmap-example:3481 map pfn expected mapping type write-back for +[mem 0x00010000-0x00010fff], got uncached-minus + ------------[ cut here ]------------ +WARNING: at /build/buildd/linux-3.8.0/arch/x86/mm/pat.c:774 untrack_pfn+0xb8/0xd0() +mem 0x00010000-0x00010fff], got uncached-minus +------------[ cut here ]------------ +WARNING: at /build/buildd/linux-3.8.0/arch/x86/mm/pat.c:774 +untrack_pfn+0xb8/0xd0() +... +Pid: 3481, comm: mmap-example Tainted: GF 3.8.0-6-generic #13-Ubuntu +Call Trace: + [] warn_slowpath_common+0x7f/0xc0 + [] warn_slowpath_null+0x1a/0x20 + [] untrack_pfn+0xb8/0xd0 + [] unmap_single_vma+0xac/0x100 + [] unmap_vmas+0x49/0x90 + [] exit_mmap+0x98/0x170 + [] mmput+0x64/0x100 + [] dup_mm+0x445/0x660 + [] copy_process.part.22+0xa5f/0x1510 + [] do_fork+0x91/0x350 + [] sys_clone+0x16/0x20 + [] stub_clone+0x69/0x90 + [] ? system_call_fastpath+0x1a/0x1f +---[ end trace 4918cdd0a4c9fea4 ]--- + +(a similar message shows up if you end up launching 'mcelog') + +The call chain is (as analyzed by Liu, Jinsong): +do_fork + --> copy_process + --> dup_mm + --> dup_mmap + --> copy_page_range + --> track_pfn_copy + --> reserve_pfn_range + --> line 624: flags != want_flags +It comes from different memory types of page table (_PAGE_CACHE_WB) and MTRR +(_PAGE_CACHE_UC_MINUS). + +Stefan Bader dug in this deep and found out that: +"That makes it clearer as this will do + +reserve_memtype(...) +--> pat_x_mtrr_type + --> mtrr_type_lookup + --> __mtrr_type_lookup + +And that can return -1/0xff in case of MTRR not being enabled/initialized. Which +is not the case (given there are no messages for it in dmesg). This is not equal +to MTRR_TYPE_WRBACK and thus becomes _PAGE_CACHE_UC_MINUS. + +It looks like the problem starts early in reserve_memtype: + + if (!pat_enabled) { + /* This is identical to page table setting without PAT */ + if (new_type) { + if (req_type == _PAGE_CACHE_WC) + *new_type = _PAGE_CACHE_UC_MINUS; + else + *new_type = req_type & _PAGE_CACHE_MASK; + } + return 0; + } + +This would be what we want, that is clearing the PWT and PCD flags from the +supported flags - if pat_enabled is disabled." + +This patch does that - disabling PAT. + +Reported-by: Sander Eikelenboom +Reported-and-Tested-by: Konrad Rzeszutek Wilk +Reported-and-Tested-by: Stefan Bader +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/enlighten.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -64,6 +64,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_ACPI + #include +@@ -1355,7 +1356,14 @@ asmlinkage void __init xen_start_kernel( + */ + acpi_numa = -1; + #endif +- ++#ifdef CONFIG_X86_PAT ++ /* ++ * For right now disable the PAT. We should remove this once ++ * git commit 8eaffa67b43e99ae581622c5133e20b0f48bcef1 ++ * (xen/pat: Disable PAT support for now) is reverted. ++ */ ++ pat_enabled = 0; ++#endif + pgd = (pgd_t *)xen_start_info->pt_base; + + /* Don't do the full vcpu_info placement stuff until we have a