xfrm: Fix unaligned access to stats in copy_to_user_state()
Subsystems (3)
PATCH v2 1/1 xfrm: Fix unaligned access to stats in copy_to_user_state()
On sparc, deleting established SAs (e.g., by restarting ipsec) results in unaligned access messages via xfrm_del_sa -> km_state_notify -> xfrm_send_state_notify().
Even though struct xfrm_usersa_info is aligned on 8-byte boundaries, netlink attributes are fundamentally only 4 byte aligned, and this cannot be changed for nla_data() that is passed up to userspace. As a result, the put_unaligned() macro needs to be used to set up potentially unaligned fields such as the xfrm_stats in copy_to_user_state()
---
v2: review comment from thread: cannot use PTR_ALIGN as this would break
userspace assumptions about 4 byte alignment. Use *_unaligned() macros as needed, instead.
net/xfrm/xfrm_user.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
net/xfrm/xfrm_user.c +4 -1
@@ -31,6 +31,7 @@#if IS_ENABLED (CONFIG_IPV6 )#include <linux/in6.h> #endif +#include <asm/unaligned.h> static int verify_one_alg (struct nlattr **attrs,enum xfrm_attr_type_t type) {
@@ -728,7 +729,9 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)memcpy (&p->sel, &x->sel,sizeof (p->sel));memcpy (&p->lft, &x->lft,sizeof (p->lft));memcpy (&p->curlft, &x->curlft,sizeof (p->curlft)); -memcpy (&p->stats, &x->stats,sizeof (p->stats)); +put_unaligned (x->stats.replay_window, &p->stats.replay_window); +put_unaligned (x->stats.replay, &p->stats.replay); +put_unaligned (x->stats.integrity_failed, &p->stats.integrity_failed);memcpy (&p->saddr, &x->props.saddr,sizeof (p->saddr)); p->mode = x->props.mode; p->replay_window = x->props.replay_window;
Signature · 1 line
1.7.1
Steffen Klassert
maintainerQuoted 12 lines · Sowmini Varadhan
On sparc, deleting established SAs (e.g., by restarting ipsec) results in unaligned access messages via
xfrm_del_sa->km_state_notify->xfrm_send_state_notify().Even though struct
xfrm_usersa_infois aligned on 8-byte boundaries, netlink attributes are fundamentally only 4 byte aligned, and this cannot be changed fornla_data()that is passed up to userspace. As a result, theput_unaligned()macro needs to be used to set up potentially unaligned fields such as thexfrm_statsincopy_to_user_state()
Quoted 5 lines
Signed-off-by Sowmini Varadhan <[email protected]>---
v2: review comment from thread: cannot usePTR_ALIGNas this would break
userspace assumptions about 4 byte alignment. Use*_unaligned()macros as needed, instead.
This works on intel 32-bit and 64-bit as expected. Patch applied to ipsec-next, thanks!