Re: Linus GIT - kernel BUG at include/linux/scatterlist.h:115! CPU: 1 PID: 1203 Comm: apparmor_parser Not tainted 3.12.0-rc1+

2013-09-22 Thread John Johansen
On 09/22/2013 07:30 PM, Miles Lane wrote:

yep, thanks for the report. I have a patch for this one, attached
below but is also being sent up to the security tree.

---

apparmor: Use shash crypto API interface for profile hashes

Use the shash interface, rather than the hash interface, when hashing
AppArmor profiles. The shash interface does not use scatterlists and it
is a better fit for what AppArmor needs.

This fixes a kernel paging BUG when aa_calc_profile_hash() is passed a
buffer from vmalloc(). The hash interface requires callers to handle
vmalloc() buffers differently than what AppArmor was doing. Due to
vmalloc() memory not being physically contiguous, each individual page
behind the buffer must be assigned to a scatterlist with sg_set_page()
and then the scatterlist passed to crypto_hash_update().

The shash interface does not have that limitation and allows vmalloc()
and kmalloc() buffers to be handled in the same manner.

https://launchpad.net/bugs/1216294/

Signed-off-by: Tyler Hicks 
Acked-by: John Johansen 
---

I've tested this patch by comparing aafs/policy/profiles/*/sha1 between a
patched i386 VM (i386 is where the BUG is easily reproduced) and an unpatched
amd64 VM. Then I did `service apparmor restart` to trigger a profile
replacement and compared the sha1 files in aafs again. I put all of that into a
loop and let it run for a while.

Tyler

 security/apparmor/crypto.c | 34 --
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c
index d6222ba..532471d 100644
--- a/security/apparmor/crypto.c
+++ b/security/apparmor/crypto.c
@@ -15,14 +15,14 @@
  * it should be.
  */
 
-#include 
+#include 
 
 #include "include/apparmor.h"
 #include "include/crypto.h"
 
 static unsigned int apparmor_hash_size;
 
-static struct crypto_hash *apparmor_tfm;
+static struct crypto_shash *apparmor_tfm;
 
 unsigned int aa_hash_size(void)
 {
@@ -32,35 +32,33 @@ unsigned int aa_hash_size(void)
 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
 size_t len)
 {
-   struct scatterlist sg[2];
-   struct hash_desc desc = {
-   .tfm = apparmor_tfm,
-   .flags = 0
-   };
+   struct {
+   struct shash_desc shash;
+   char ctx[crypto_shash_descsize(apparmor_tfm)];
+   } desc;
int error = -ENOMEM;
u32 le32_version = cpu_to_le32(version);
 
if (!apparmor_tfm)
return 0;
 
-   sg_init_table(sg, 2);
-   sg_set_buf([0], _version, 4);
-   sg_set_buf([1], (u8 *) start, len);
-
profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
if (!profile->hash)
goto fail;
 
-   error = crypto_hash_init();
+   desc.shash.tfm = apparmor_tfm;
+   desc.shash.flags = 0;
+
+   error = crypto_shash_init();
if (error)
goto fail;
-   error = crypto_hash_update(, [0], 4);
+   error = crypto_shash_update(, (u8 *) _version, 4);
if (error)
goto fail;
-   error = crypto_hash_update(, [1], len);
+   error = crypto_shash_update(, (u8 *) start, len);
if (error)
goto fail;
-   error = crypto_hash_final(, profile->hash);
+   error = crypto_shash_final(, profile->hash);
if (error)
goto fail;
 
@@ -75,19 +73,19 @@ fail:
 
 static int __init init_profile_hash(void)
 {
-   struct crypto_hash *tfm;
+   struct crypto_shash *tfm;
 
if (!apparmor_initialized)
return 0;
 
-   tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
+   tfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
int error = PTR_ERR(tfm);
AA_ERROR("failed to setup profile sha1 hashing: %d\n", error);
return error;
}
apparmor_tfm = tfm;
-   apparmor_hash_size = crypto_hash_digestsize(apparmor_tfm);
+   apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm);
 
aa_info_message("AppArmor sha1 policy hashing enabled");
 
-- 
1.8.3.2


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Linus GIT - kernel BUG at include/linux/scatterlist.h:115! CPU: 1 PID: 1203 Comm: apparmor_parser Not tainted 3.12.0-rc1+

2013-09-22 Thread Miles Lane
[   27.190017] kernel BUG at include/linux/scatterlist.h:115!
[   27.190017] invalid opcode:  [#1] PREEMPT SMP DEBUG_PAGEALLOC
[   27.190017] Modules linked in: mxm_wmi iwldvm mac80211 iwlwifi
cfg80211 snd_hda_intel(+) snd_hda_codec snd_hwdep snd_pcm_oss
snd_mixer_oss hwmon snd_pcm ttm snd_seq_dummy snd_page_alloc
snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_timer
i915(+) snd i2c_algo_bit drm_kms_helper wmi ac drm soundcore evdev
mac_hid i2c_core battery acpi_cpufreq ehci_pci(+) ehci_hcd asus_laptop
rfkill intel_agp intel_gtt agpgart processor sr_mod cdrom atl1c
uhci_hcd thermal
[   27.190017] CPU: 1 PID: 1203 Comm: apparmor_parser Not tainted 3.12.0-rc1+ #8
[   27.190017] Hardware name: ASUSTeK Computer Inc. UL50VT
 /UL50VT, BIOS 217 03/01/2010
[   27.190017] task: 8800bd99ea80 ti: 8800baf5a000 task.ti:
8800baf5a000
[   27.190017] RIP: 0010:[]  []
sg_set_buf+0x20/0x7e
[   27.190017] RSP: 0018:8800baf5bcf8  EFLAGS: 00010246
[   27.190017] RAX:  RBX: 8800baf5bd70 RCX: 0024
[   27.190017] RDX: 0410 RSI: c900108ca010 RDI: 4100108ca010
[   27.190017] RBP: 8800baf5bd18 R08: 880138eec290 R09: 
[   27.190017] R10: 880138ee2148 R11: 0e12 R12: c900108ca010
[   27.190017] R13: 8649 R14: c900108ca010 R15: 880138ee
[   27.190017] FS:  7f96aaf6c740() GS:88013f30()
knlGS:
[   27.190017] CS:  0010 DS:  ES:  CR0: 80050033
[   27.190017] CR2: 7f96aaf5d00f CR3: b9e7a000 CR4: 000407e0
[   27.190017] Stack:
[   27.190017]  8800b9d55520 8800baf5bd70 8649
c900108ca010
[   27.190017]  8800baf5bdb8 811f9f50 811f3eef
000538ee8000
[   27.190017]  880138c42000 8800 87654321
ea0002ebd6c0
[   27.190017] Call Trace:
[   27.190017]  [] aa_calc_profile_hash+0x75/0x11d
[   27.190017]  [] ? __aa_kvmalloc+0x39/0x51
[   27.190017]  [] aa_unpack+0x929/0x969
[   27.190017]  [] aa_replace_profiles+0x38/0x57c
[   27.190017]  [] profile_replace+0x35/0x4c
[   27.190017]  [] vfs_write+0xad/0x113
[   27.190017]  [] SyS_write+0x44/0x7a
[   27.190017]  [] system_call_fastpath+0x16/0x1b
[   27.190017] Code: 66 89 45 fc e8 6a fc ff ff c9 c3 55 48 89 e5 41
56 41 55 41 89 d5 41 54 49 89 f4 53 48 89 fb 48 89 f7 e8 1b 9e e3 ff
84 c0 75 02 <0f> 0b 4c 89 e7 45 89 e6 e8 96 9e e3 ff 48 8b 53 08 41 81
e6 ff
[   27.190017] RIP  [] sg_set_buf+0x20/0x7e
[   27.190017]  RSP 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Linus GIT - kernel BUG at include/linux/scatterlist.h:115! CPU: 1 PID: 1203 Comm: apparmor_parser Not tainted 3.12.0-rc1+

2013-09-22 Thread Miles Lane
[   27.190017] kernel BUG at include/linux/scatterlist.h:115!
[   27.190017] invalid opcode:  [#1] PREEMPT SMP DEBUG_PAGEALLOC
[   27.190017] Modules linked in: mxm_wmi iwldvm mac80211 iwlwifi
cfg80211 snd_hda_intel(+) snd_hda_codec snd_hwdep snd_pcm_oss
snd_mixer_oss hwmon snd_pcm ttm snd_seq_dummy snd_page_alloc
snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_timer
i915(+) snd i2c_algo_bit drm_kms_helper wmi ac drm soundcore evdev
mac_hid i2c_core battery acpi_cpufreq ehci_pci(+) ehci_hcd asus_laptop
rfkill intel_agp intel_gtt agpgart processor sr_mod cdrom atl1c
uhci_hcd thermal
[   27.190017] CPU: 1 PID: 1203 Comm: apparmor_parser Not tainted 3.12.0-rc1+ #8
[   27.190017] Hardware name: ASUSTeK Computer Inc. UL50VT
 /UL50VT, BIOS 217 03/01/2010
[   27.190017] task: 8800bd99ea80 ti: 8800baf5a000 task.ti:
8800baf5a000
[   27.190017] RIP: 0010:[811f9e71]  [811f9e71]
sg_set_buf+0x20/0x7e
[   27.190017] RSP: 0018:8800baf5bcf8  EFLAGS: 00010246
[   27.190017] RAX:  RBX: 8800baf5bd70 RCX: 0024
[   27.190017] RDX: 0410 RSI: c900108ca010 RDI: 4100108ca010
[   27.190017] RBP: 8800baf5bd18 R08: 880138eec290 R09: 
[   27.190017] R10: 880138ee2148 R11: 0e12 R12: c900108ca010
[   27.190017] R13: 8649 R14: c900108ca010 R15: 880138ee
[   27.190017] FS:  7f96aaf6c740() GS:88013f30()
knlGS:
[   27.190017] CS:  0010 DS:  ES:  CR0: 80050033
[   27.190017] CR2: 7f96aaf5d00f CR3: b9e7a000 CR4: 000407e0
[   27.190017] Stack:
[   27.190017]  8800b9d55520 8800baf5bd70 8649
c900108ca010
[   27.190017]  8800baf5bdb8 811f9f50 811f3eef
000538ee8000
[   27.190017]  880138c42000 8800 87654321
ea0002ebd6c0
[   27.190017] Call Trace:
[   27.190017]  [811f9f50] aa_calc_profile_hash+0x75/0x11d
[   27.190017]  [811f3eef] ? __aa_kvmalloc+0x39/0x51
[   27.190017]  [811f7e34] aa_unpack+0x929/0x969
[   27.190017]  [811f6a21] aa_replace_profiles+0x38/0x57c
[   27.190017]  [811f249b] profile_replace+0x35/0x4c
[   27.190017]  [81121477] vfs_write+0xad/0x113
[   27.190017]  [81121add] SyS_write+0x44/0x7a
[   27.190017]  [8145f3e2] system_call_fastpath+0x16/0x1b
[   27.190017] Code: 66 89 45 fc e8 6a fc ff ff c9 c3 55 48 89 e5 41
56 41 55 41 89 d5 41 54 49 89 f4 53 48 89 fb 48 89 f7 e8 1b 9e e3 ff
84 c0 75 02 0f 0b 4c 89 e7 45 89 e6 e8 96 9e e3 ff 48 8b 53 08 41 81
e6 ff
[   27.190017] RIP  [811f9e71] sg_set_buf+0x20/0x7e
[   27.190017]  RSP 8800baf5bcf8
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Linus GIT - kernel BUG at include/linux/scatterlist.h:115! CPU: 1 PID: 1203 Comm: apparmor_parser Not tainted 3.12.0-rc1+

2013-09-22 Thread John Johansen
On 09/22/2013 07:30 PM, Miles Lane wrote:

yep, thanks for the report. I have a patch for this one, attached
below but is also being sent up to the security tree.

---

apparmor: Use shash crypto API interface for profile hashes

Use the shash interface, rather than the hash interface, when hashing
AppArmor profiles. The shash interface does not use scatterlists and it
is a better fit for what AppArmor needs.

This fixes a kernel paging BUG when aa_calc_profile_hash() is passed a
buffer from vmalloc(). The hash interface requires callers to handle
vmalloc() buffers differently than what AppArmor was doing. Due to
vmalloc() memory not being physically contiguous, each individual page
behind the buffer must be assigned to a scatterlist with sg_set_page()
and then the scatterlist passed to crypto_hash_update().

The shash interface does not have that limitation and allows vmalloc()
and kmalloc() buffers to be handled in the same manner.

https://launchpad.net/bugs/1216294/

Signed-off-by: Tyler Hicks tyhi...@canonical.com
Acked-by: John Johansen john.johan...@canonical.com
---

I've tested this patch by comparing aafs/policy/profiles/*/sha1 between a
patched i386 VM (i386 is where the BUG is easily reproduced) and an unpatched
amd64 VM. Then I did `service apparmor restart` to trigger a profile
replacement and compared the sha1 files in aafs again. I put all of that into a
loop and let it run for a while.

Tyler

 security/apparmor/crypto.c | 34 --
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c
index d6222ba..532471d 100644
--- a/security/apparmor/crypto.c
+++ b/security/apparmor/crypto.c
@@ -15,14 +15,14 @@
  * it should be.
  */
 
-#include linux/crypto.h
+#include crypto/hash.h
 
 #include include/apparmor.h
 #include include/crypto.h
 
 static unsigned int apparmor_hash_size;
 
-static struct crypto_hash *apparmor_tfm;
+static struct crypto_shash *apparmor_tfm;
 
 unsigned int aa_hash_size(void)
 {
@@ -32,35 +32,33 @@ unsigned int aa_hash_size(void)
 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
 size_t len)
 {
-   struct scatterlist sg[2];
-   struct hash_desc desc = {
-   .tfm = apparmor_tfm,
-   .flags = 0
-   };
+   struct {
+   struct shash_desc shash;
+   char ctx[crypto_shash_descsize(apparmor_tfm)];
+   } desc;
int error = -ENOMEM;
u32 le32_version = cpu_to_le32(version);
 
if (!apparmor_tfm)
return 0;
 
-   sg_init_table(sg, 2);
-   sg_set_buf(sg[0], le32_version, 4);
-   sg_set_buf(sg[1], (u8 *) start, len);
-
profile-hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
if (!profile-hash)
goto fail;
 
-   error = crypto_hash_init(desc);
+   desc.shash.tfm = apparmor_tfm;
+   desc.shash.flags = 0;
+
+   error = crypto_shash_init(desc.shash);
if (error)
goto fail;
-   error = crypto_hash_update(desc, sg[0], 4);
+   error = crypto_shash_update(desc.shash, (u8 *) le32_version, 4);
if (error)
goto fail;
-   error = crypto_hash_update(desc, sg[1], len);
+   error = crypto_shash_update(desc.shash, (u8 *) start, len);
if (error)
goto fail;
-   error = crypto_hash_final(desc, profile-hash);
+   error = crypto_shash_final(desc.shash, profile-hash);
if (error)
goto fail;
 
@@ -75,19 +73,19 @@ fail:
 
 static int __init init_profile_hash(void)
 {
-   struct crypto_hash *tfm;
+   struct crypto_shash *tfm;
 
if (!apparmor_initialized)
return 0;
 
-   tfm = crypto_alloc_hash(sha1, 0, CRYPTO_ALG_ASYNC);
+   tfm = crypto_alloc_shash(sha1, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
int error = PTR_ERR(tfm);
AA_ERROR(failed to setup profile sha1 hashing: %d\n, error);
return error;
}
apparmor_tfm = tfm;
-   apparmor_hash_size = crypto_hash_digestsize(apparmor_tfm);
+   apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm);
 
aa_info_message(AppArmor sha1 policy hashing enabled);
 
-- 
1.8.3.2


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/