rxrpc: Reuse SKCIPHER_REQUEST_ON_STACK buffer
Subsystems (3)
PATCH 1/1 rxrpc: Reuse SKCIPHER_REQUEST_ON_STACK buffer
The use of SKCIPHER_REQUEST_ON_STACK() will trigger FRAME_WARN warnings (when less than 2048) once the VLA is no longer hidden from the check:
net/rxrpc/rxkad.c:398:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=] net/rxrpc/rxkad.c:242:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]
This passes the initial SKCIPHER_REQUEST_ON_STACK allocation to the leaf functions for reuse. Two requests allocated on the stack are not needed when only one is used at a time.
--- net/rxrpc/rxkad.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
net/rxrpc/rxkad.c +13 -12
@@ -146,10 +146,10 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn)static int rxkad_secure_packet_auth (const struct rxrpc_call *call,struct sk_buff *skb,u32 data_size, -void *sechdr) +void *sechdr, +struct skcipher_request *req) {struct rxrpc_skb_priv *sp =rxrpc_skb (skb); -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxkad_level1_hdr hdr;struct rxrpc_crypt iv;struct scatterlist sg;
@@ -183,12 +183,12 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,static int rxkad_secure_packet_encrypt (const struct rxrpc_call *call,struct sk_buff *skb,u32 data_size, -void *sechdr) +void *sechdr, +struct skcipher_request *req) {const struct rxrpc_key_token *token;struct rxkad_level2_hdr rxkhdr;struct rxrpc_skb_priv *sp; -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxrpc_crypt iv;struct scatterlist sg[16 ];struct sk_buff *trailer;
@@ -296,11 +296,12 @@ static int rxkad_secure_packet(struct rxrpc_call *call, ret =0 ;break ;case RXRPC_SECURITY_AUTH : - ret =rxkad_secure_packet_auth (call, skb, data_size, sechdr); + ret =rxkad_secure_packet_auth (call, skb, data_size, sechdr, + req);break ;case RXRPC_SECURITY_ENCRYPT : ret =rxkad_secure_packet_encrypt (call, skb, data_size, - sechdr); + sechdr, req);break ;default : ret = -EPERM ;
@@ -316,10 +317,10 @@ static int rxkad_secure_packet(struct rxrpc_call *call,*/ static int rxkad_verify_packet_1 (struct rxrpc_call *call,struct sk_buff *skb,unsigned int offset,unsigned int len, -rxrpc_seq_t seq) +rxrpc_seq_t seq, +struct skcipher_request *req) {struct rxkad_level1_hdr sechdr; -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxrpc_crypt iv;struct scatterlist sg[16 ];struct sk_buff *trailer;
@@ -402,11 +403,11 @@ static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,*/ static int rxkad_verify_packet_2 (struct rxrpc_call *call,struct sk_buff *skb,unsigned int offset,unsigned int len, -rxrpc_seq_t seq) +rxrpc_seq_t seq, +struct skcipher_request *req) {const struct rxrpc_key_token *token;struct rxkad_level2_hdr sechdr; -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxrpc_crypt iv;struct scatterlist _sg[4 ], *sg;struct sk_buff *trailer;
@@ -549,9 +550,9 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,case RXRPC_SECURITY_PLAIN :return 0 ;case RXRPC_SECURITY_AUTH : -return rxkad_verify_packet_1 (call, skb, offset, len, seq); +return rxkad_verify_packet_1 (call, skb, offset, len, seq, req);case RXRPC_SECURITY_ENCRYPT : -return rxkad_verify_packet_2 (call, skb, offset, len, seq); +return rxkad_verify_packet_2 (call, skb, offset, len, seq, req);default :return -ENOANO ; }
Signature · 6 lines
2.17.1 -- Kees Cook Pixel Security
Quoted 11 lines · Kees Cook
The use of
SKCIPHER_REQUEST_ON_STACK()will triggerFRAME_WARNwarnings (when less than 2048) once the VLA is no longer hidden from the check:
net/rxrpc/rxkad.c:398:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]net/rxrpc/rxkad.c:242:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]This passes the initial
SKCIPHER_REQUEST_ON_STACKallocation to the leaf functions for reuse. Two requests allocated on the stack are not needed when only one is used at a time.Signed-off-by Kees Cook <[email protected]>
This looks like a very nice solution to the problem.
Since the large stack usage could already cause problems in older kernels, should this be backported to stable kernels as well?
Arnd
Quoted 11 lines · Arnd Bergmann
Quoted 10 lines · Kees Cook
The use of
SKCIPHER_REQUEST_ON_STACK()will triggerFRAME_WARNwarnings (when less than 2048) once the VLA is no longer hidden from the check:
net/rxrpc/rxkad.c:398:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]net/rxrpc/rxkad.c:242:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]This passes the initial
SKCIPHER_REQUEST_ON_STACKallocation to the leaf functions for reuse. Two requests allocated on the stack are not needed when only one is used at a time.
Quoted 8 lines
Quoted 1 line
Signed-off-by Kees Cook <[email protected]>This looks like a very nice solution to the problem.
Acked-by Arnd Bergmann <[email protected]>Since the large stack usage could already cause problems in older kernels, should this be backported to stable kernels as well?
I don't think this hits the bar for doing a -stable patch, but if you think I should, I can do it.
-Kees
Signature · 2 lines
Kees Cook Pixel Security
Quoted 103 lines · Kees Cook
The use of
SKCIPHER_REQUEST_ON_STACK()will triggerFRAME_WARNwarnings (when less than 2048) once the VLA is no longer hidden from the check:
net/rxrpc/rxkad.c:398:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]net/rxrpc/rxkad.c:242:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]This passes the initial
SKCIPHER_REQUEST_ON_STACKallocation to the leaf functions for reuse. Two requests allocated on the stack are not needed when only one is used at a time.Signed-off-by Kees Cook <[email protected]>--- net/rxrpc/rxkad.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)net/rxrpc/rxkad.c +13
-12@@ -146,10 +146,10 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn)static int rxkad_secure_packet_auth (const struct rxrpc_call *call,struct sk_buff *skb,u32 data_size, -void *sechdr) +void *sechdr, +struct skcipher_request *req) {struct rxrpc_skb_priv *sp =rxrpc_skb (skb); -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxkad_level1_hdr hdr;struct rxrpc_crypt iv;struct scatterlist sg;@@ -183,12 +183,12 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,static int rxkad_secure_packet_encrypt (const struct rxrpc_call *call,struct sk_buff *skb,u32 data_size, -void *sechdr) +void *sechdr, +struct skcipher_request *req) {const struct rxrpc_key_token *token;struct rxkad_level2_hdr rxkhdr;struct rxrpc_skb_priv *sp; -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxrpc_crypt iv;struct scatterlist sg[16 ];struct sk_buff *trailer;@@ -296,11 +296,12 @@ static int rxkad_secure_packet(struct rxrpc_call *call, ret =0 ;break ;case RXRPC_SECURITY_AUTH : - ret =rxkad_secure_packet_auth (call, skb, data_size, sechdr); + ret =rxkad_secure_packet_auth (call, skb, data_size, sechdr, + req);break ;case RXRPC_SECURITY_ENCRYPT : ret =rxkad_secure_packet_encrypt (call, skb, data_size, - sechdr); + sechdr, req);break ;default : ret = -EPERM ;@@ -316,10 +317,10 @@ static int rxkad_secure_packet(struct rxrpc_call *call,*/ static int rxkad_verify_packet_1 (struct rxrpc_call *call,struct sk_buff *skb,unsigned int offset,unsigned int len, -rxrpc_seq_t seq) +rxrpc_seq_t seq, +struct skcipher_request *req) {struct rxkad_level1_hdr sechdr; -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxrpc_crypt iv;struct scatterlist sg[16 ];struct sk_buff *trailer;@@ -402,11 +403,11 @@ static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,*/ static int rxkad_verify_packet_2 (struct rxrpc_call *call,struct sk_buff *skb,unsigned int offset,unsigned int len, -rxrpc_seq_t seq) +rxrpc_seq_t seq, +struct skcipher_request *req) {const struct rxrpc_key_token *token;struct rxkad_level2_hdr sechdr; -SKCIPHER_REQUEST_ON_STACK (req, call->conn->cipher);struct rxrpc_crypt iv;struct scatterlist _sg[4 ], *sg;struct sk_buff *trailer;@@ -549,9 +550,9 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,case RXRPC_SECURITY_PLAIN :return 0 ;case RXRPC_SECURITY_AUTH : -return rxkad_verify_packet_1 (call, skb, offset, len, seq); +return rxkad_verify_packet_1 (call, skb, offset, len, seq, req);case RXRPC_SECURITY_ENCRYPT : -return rxkad_verify_packet_2 (call, skb, offset, len, seq); +return rxkad_verify_packet_2 (call, skb, offset, len, seq, req);default :return -ENOANO ; }Signature · 1 line
2.17.1
How about doing the 'skcipher_request_set_tfm(req, call->conn->cipher)' and 'skcipher_request_zero(req);' just once, in the top-level function rxkad_verify_packet(), instead of before/after every time the request is used?
- Eric
Quoted 11 lines · Eric Biggers
Quoted 10 lines · Kees Cook
The use of
SKCIPHER_REQUEST_ON_STACK()will triggerFRAME_WARNwarnings (when less than 2048) once the VLA is no longer hidden from the check:
net/rxrpc/rxkad.c:398:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]net/rxrpc/rxkad.c:242:1: warning: the frame size of 1152 bytes is larger than 1024 bytes [-Wframe-larger-than=]This passes the initial
SKCIPHER_REQUEST_ON_STACKallocation to the leaf functions for reuse. Two requests allocated on the stack are not needed when only one is used at a time.
Quoted 8 lines
Quoted 5 lines
Signed-off-by Kees Cook <[email protected]>--- net/rxrpc/rxkad.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)[...]
How about doing the '
skcipher_request_set_tfm(req, call->conn->cipher)' and 'skcipher_request_zero(req);' just once, in the top-level functionrxkad_verify_packet(), instead of before/after every time the request is used?
Hm. While that does sound reasonable, I like having it be operationally unchanged. And changing this makes the caller function a bit more weird. Right now it's doing direct returns, and we'd need to cover error paths, etc. Having the "zero" _right_ after the encrypt/decrypt seems more robust to me.
-Kees
Signature · 2 lines
Kees Cook Pixel Security