Commit efe5ebcc authored by David S. Miller's avatar David S. Miller

[IPV6]: Do not virt_to_page() on stack addresses, fixes OOPS.

parent 3d68e788
...@@ -175,6 +175,8 @@ struct inet6_dev ...@@ -175,6 +175,8 @@ struct inet6_dev
u8 entropy[8]; u8 entropy[8];
struct timer_list regen_timer; struct timer_list regen_timer;
struct inet6_ifaddr *tempaddr_list; struct inet6_ifaddr *tempaddr_list;
__u8 work_eui64[8];
__u8 work_digest[16];
#endif #endif
struct neigh_parms *nd_parms; struct neigh_parms *nd_parms;
......
...@@ -1109,24 +1109,22 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev) ...@@ -1109,24 +1109,22 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
static int __ipv6_regen_rndid(struct inet6_dev *idev) static int __ipv6_regen_rndid(struct inet6_dev *idev)
{ {
struct net_device *dev; struct net_device *dev;
u8 eui64[8];
u8 digest[16];
struct scatterlist sg[2]; struct scatterlist sg[2];
sg[0].page = virt_to_page(idev->entropy); sg[0].page = virt_to_page(idev->entropy);
sg[0].offset = offset_in_page(idev->entropy); sg[0].offset = offset_in_page(idev->entropy);
sg[0].length = 8; sg[0].length = 8;
sg[1].page = virt_to_page(eui64); sg[1].page = virt_to_page(idev->work_eui64);
sg[1].offset = offset_in_page(eui64); sg[1].offset = offset_in_page(idev->work_eui64);
sg[1].length = 8; sg[1].length = 8;
dev = idev->dev; dev = idev->dev;
if (ipv6_generate_eui64(eui64, dev)) { if (ipv6_generate_eui64(idev->work_eui64, dev)) {
printk(KERN_INFO printk(KERN_INFO
"__ipv6_regen_rndid(idev=%p): cannot get EUI64 identifier; use random bytes.\n", "__ipv6_regen_rndid(idev=%p): cannot get EUI64 identifier; use random bytes.\n",
idev); idev);
get_random_bytes(eui64, sizeof(eui64)); get_random_bytes(idev->work_eui64, sizeof(idev->work_eui64));
} }
regen: regen:
spin_lock(&md5_tfm_lock); spin_lock(&md5_tfm_lock);
...@@ -1136,12 +1134,12 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev) ...@@ -1136,12 +1134,12 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev)
} }
crypto_digest_init(md5_tfm); crypto_digest_init(md5_tfm);
crypto_digest_update(md5_tfm, sg, 2); crypto_digest_update(md5_tfm, sg, 2);
crypto_digest_final(md5_tfm, digest); crypto_digest_final(md5_tfm, idev->work_digest);
spin_unlock(&md5_tfm_lock); spin_unlock(&md5_tfm_lock);
memcpy(idev->rndid, &digest[0], 8); memcpy(idev->rndid, &idev->work_digest[0], 8);
idev->rndid[0] &= ~0x02; idev->rndid[0] &= ~0x02;
memcpy(idev->entropy, &digest[8], 8); memcpy(idev->entropy, &idev->work_digest[8], 8);
/* /*
* <draft-ietf-ipngwg-temp-addresses-v2-00.txt>: * <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment