Skip to content

Commit e86212b

Browse files
rleonklassert
authored andcommitted
xfrm: validate assignment of maximal possible SEQ number
Users can set any seq/seq_hi/oseq/oseq_hi values. The XFRM core code doesn't prevent from them to set even 0xFFFFFFFF, however this value will cause for traffic drop. Is is happening because SEQ numbers here mean that packet with such number was processed and next number should be sent on the wire. In this case, the next number will be 0, and it means overflow which causes to (expected) packet drops. While it can be considered as misconfiguration and handled by XFRM datapath in the same manner as any other SEQ number, let's add validation to easy for packet offloads implementations which need to configure HW with next SEQ to send and not with current SEQ like it is done in core code. Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 86e530c commit e86212b

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

net/xfrm/xfrm_user.c

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,27 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
178178
"Replay seq and seq_hi should be 0 for output SA");
179179
return -EINVAL;
180180
}
181-
if (rs->oseq_hi && !(p->flags & XFRM_STATE_ESN)) {
182-
NL_SET_ERR_MSG(
183-
extack,
184-
"Replay oseq_hi should be 0 in non-ESN mode for output SA");
185-
return -EINVAL;
181+
182+
if (!(p->flags & XFRM_STATE_ESN)) {
183+
if (rs->oseq_hi) {
184+
NL_SET_ERR_MSG(
185+
extack,
186+
"Replay oseq_hi should be 0 in non-ESN mode for output SA");
187+
return -EINVAL;
188+
}
189+
if (rs->oseq == U32_MAX) {
190+
NL_SET_ERR_MSG(
191+
extack,
192+
"Replay oseq should be less than 0xFFFFFFFF in non-ESN mode for output SA");
193+
return -EINVAL;
194+
}
195+
} else {
196+
if (rs->oseq == U32_MAX && rs->oseq_hi == U32_MAX) {
197+
NL_SET_ERR_MSG(
198+
extack,
199+
"Replay oseq and oseq_hi should be less than 0xFFFFFFFF for output SA");
200+
return -EINVAL;
201+
}
186202
}
187203
if (rs->bmp_len) {
188204
NL_SET_ERR_MSG(extack, "Replay bmp_len should 0 for output SA");
@@ -196,11 +212,27 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
196212
"Replay oseq and oseq_hi should be 0 for input SA");
197213
return -EINVAL;
198214
}
199-
if (rs->seq_hi && !(p->flags & XFRM_STATE_ESN)) {
200-
NL_SET_ERR_MSG(
201-
extack,
202-
"Replay seq_hi should be 0 in non-ESN mode for input SA");
203-
return -EINVAL;
215+
if (!(p->flags & XFRM_STATE_ESN)) {
216+
if (rs->seq_hi) {
217+
NL_SET_ERR_MSG(
218+
extack,
219+
"Replay seq_hi should be 0 in non-ESN mode for input SA");
220+
return -EINVAL;
221+
}
222+
223+
if (rs->seq == U32_MAX) {
224+
NL_SET_ERR_MSG(
225+
extack,
226+
"Replay seq should be less than 0xFFFFFFFF in non-ESN mode for input SA");
227+
return -EINVAL;
228+
}
229+
} else {
230+
if (rs->seq == U32_MAX && rs->seq_hi == U32_MAX) {
231+
NL_SET_ERR_MSG(
232+
extack,
233+
"Replay seq and seq_hi should be less than 0xFFFFFFFF for input SA");
234+
return -EINVAL;
235+
}
204236
}
205237
}
206238

0 commit comments

Comments
 (0)