ppp_mppe: Don't put InterimKey on the stack
Subsystems (2)
PATCH 1/1 ppp_mppe: Don't put InterimKey on the stack
Hello,
The interrupt stack can be in the __START_KERNEL_map region in which virt_to_page will not work. This caused ppp_mppe to crash on CentOS 5 on x86_64
(http://bugs.centos.org/view.php?id 76).
The fix is to avoid copying the interim key. We can simply use it in its original place, which is kmalloc'd.
Michal
--- drivers/net/ppp_mppe.c | 14 ++++++-------- 1 files changed, 6 insertions(+), 8 deletions(-)
drivers/net/ppp_mppe.c +6 -8
@@ -136,7 +136,7 @@ struct ppp_mppe_state {* Key Derivation, from RFC 3078, RFC 3079. * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. */ -static void get_new_key_from_sha (struct ppp_mppe_state * state,unsigned char *InterimKey) +static void get_new_key_from_sha (struct ppp_mppe_state * state) {struct hash_desc desc;struct scatterlist sg[4 ];
@@ -153,8 +153,6 @@ static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *I desc.flags =0 ;crypto_hash_digest (&desc, sg, nbytes, state->sha1_digest); - -memcpy (InterimKey, state->sha1_digest, state->keylen); }/*
@@ -163,21 +161,21 @@ static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *I*/ static void mppe_rekey (struct ppp_mppe_state * state,int initial_key) { -unsigned char InterimKey[MPPE_MAX_KEY_LEN ];struct scatterlist sg_in[1 ], sg_out[1 ];struct blkcipher_desc desc = { .tfm = state->arc4 }; -get_new_key_from_sha (state, InterimKey); +get_new_key_from_sha (state);if (!initial_key) { -crypto_blkcipher_setkey (state->arc4, InterimKey, state->keylen); -setup_sg (sg_in, InterimKey, state->keylen); +crypto_blkcipher_setkey (state->arc4, state->sha1_digest, + state->keylen); +setup_sg (sg_in, state->sha1_digest, state->keylen);setup_sg (sg_out, state->session_key, state->keylen);if (crypto_blkcipher_encrypt (&desc, sg_out, sg_in, state->keylen) !=0 ) {printk (KERN_WARNING "mppe_rekey: cipher_encrypt failed\n" ); } }else { -memcpy (state->session_key, InterimKey, state->keylen); +memcpy (state->session_key, state->sha1_digest, state->keylen); }if (state->keylen =8 ) {/* See RFC 3078 */
Quoted 8 lines · Michal Schmidt
Hello,
The interrupt stack can be in the
__START_KERNEL_mapregion in whichvirt_to_pagewill not work. This causedppp_mppeto crash on CentOS 5 onx86_64
(http://bugs.centos.org/view.php?id 76).The fix is to avoid copying the interim key. We can simply use it in its original place, which is kmalloc'd.
Needs a Signed-off-by: line, but otherwise, looks good, and even saves some stack space. Thanks for tracking this down.
-Matt
Signature · 3 lines
Matt Domsch Linux Technology Strategist, Dell Office of the CTO linux.dell.com & www.dell.com/linux
Matt Domsch skrev:
Quoted 8 lines · Michal Schmidt
Quoted 7 lines
Hello,
The interrupt stack can be in the
__START_KERNEL_mapregion in whichvirt_to_pagewill not work. This causedppp_mppeto crash on CentOS 5 onx86_64
(http://bugs.centos.org/view.php?id 76).
Quoted 9 lines
Quoted 3 lines
The fix is to avoid copying the interim key. We can simply use it in its original place, which is kmalloc'd.
Needs a Signed-off-by: line, but otherwise, looks good, and even saves some stack space. Thanks for tracking this down.
-Matt
Sorry about the forgotten sign-off. Here it is.
Andrew, please apply.
--- drivers/net/ppp_mppe.c | 14 ++++++-------- 1 files changed, 6 insertions(+), 8 deletions(-)
drivers/net/ppp_mppe.c +6 -8
@@ -136,7 +136,7 @@ struct ppp_mppe_state {* Key Derivation, from RFC 3078, RFC 3079. * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. */ -static void get_new_key_from_sha (struct ppp_mppe_state * state,unsigned char *InterimKey) +static void get_new_key_from_sha (struct ppp_mppe_state * state) {struct hash_desc desc;struct scatterlist sg[4 ];
@@ -153,8 +153,6 @@ static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *I desc.flags =0 ;crypto_hash_digest (&desc, sg, nbytes, state->sha1_digest); - -memcpy (InterimKey, state->sha1_digest, state->keylen); }/*
@@ -163,21 +161,21 @@ static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *I*/ static void mppe_rekey (struct ppp_mppe_state * state,int initial_key) { -unsigned char InterimKey[MPPE_MAX_KEY_LEN ];struct scatterlist sg_in[1 ], sg_out[1 ];struct blkcipher_desc desc = { .tfm = state->arc4 }; -get_new_key_from_sha (state, InterimKey); +get_new_key_from_sha (state);if (!initial_key) { -crypto_blkcipher_setkey (state->arc4, InterimKey, state->keylen); -setup_sg (sg_in, InterimKey, state->keylen); +crypto_blkcipher_setkey (state->arc4, state->sha1_digest, + state->keylen); +setup_sg (sg_in, state->sha1_digest, state->keylen);setup_sg (sg_out, state->session_key, state->keylen);if (crypto_blkcipher_encrypt (&desc, sg_out, sg_in, state->keylen) !=0 ) {printk (KERN_WARNING "mppe_rekey: cipher_encrypt failed\n" ); } }else { -memcpy (state->session_key, InterimKey, state->keylen); +memcpy (state->session_key, state->sha1_digest, state->keylen); }if (state->keylen =8 ) {/* See RFC 3078 */