Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'ovpn-net-20250716' of https://github.com/OpenVPN/ovpn-net-next

Antonio Quartulli says:

====================
This bugfix batch includes the following changes:
* properly propagate sk mark to skb->mark field
* reject unexpected incoming netlink attributes
* reset GSO state when moving skb from transport to tunnel layer

* tag 'ovpn-net-20250716' of https://github.com/OpenVPN/ovpn-net-next:
ovpn: reset GSO metadata after decapsulation
ovpn: reject unexpected netlink attributes
ovpn: propagate socket mark to skb in UDP
====================

Link: https://patch.msgid.link/20250716115443.16763-1-antonio@openvpn.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+259 -20
+147 -6
Documentation/netlink/specs/ovpn.yaml
··· 161 161 type: uint 162 162 doc: Number of packets transmitted at the transport level 163 163 - 164 + name: peer-new-input 165 + subset-of: peer 166 + attributes: 167 + - 168 + name: id 169 + - 170 + name: remote-ipv4 171 + - 172 + name: remote-ipv6 173 + - 174 + name: remote-ipv6-scope-id 175 + - 176 + name: remote-port 177 + - 178 + name: socket 179 + - 180 + name: vpn-ipv4 181 + - 182 + name: vpn-ipv6 183 + - 184 + name: local-ipv4 185 + - 186 + name: local-ipv6 187 + - 188 + name: keepalive-interval 189 + - 190 + name: keepalive-timeout 191 + - 192 + name: peer-set-input 193 + subset-of: peer 194 + attributes: 195 + - 196 + name: id 197 + - 198 + name: remote-ipv4 199 + - 200 + name: remote-ipv6 201 + - 202 + name: remote-ipv6-scope-id 203 + - 204 + name: remote-port 205 + - 206 + name: vpn-ipv4 207 + - 208 + name: vpn-ipv6 209 + - 210 + name: local-ipv4 211 + - 212 + name: local-ipv6 213 + - 214 + name: keepalive-interval 215 + - 216 + name: keepalive-timeout 217 + - 218 + name: peer-del-input 219 + subset-of: peer 220 + attributes: 221 + - 222 + name: id 223 + - 164 224 name: keyconf 165 225 attributes: 166 226 - ··· 276 216 obtain the actual cipher IV 277 217 checks: 278 218 exact-len: nonce-tail-size 219 + 220 + - 221 + name: keyconf-get 222 + subset-of: keyconf 223 + attributes: 224 + - 225 + name: peer-id 226 + - 227 + name: slot 228 + - 229 + name: key-id 230 + - 231 + name: cipher-alg 232 + - 233 + name: keyconf-swap-input 234 + subset-of: keyconf 235 + attributes: 236 + - 237 + name: peer-id 238 + - 239 + name: keyconf-del-input 240 + subset-of: keyconf 241 + attributes: 242 + - 243 + name: peer-id 244 + - 245 + name: slot 279 246 - 280 247 name: ovpn 281 248 attributes: ··· 322 235 type: nest 323 236 doc: Peer specific cipher configuration 324 237 nested-attributes: keyconf 238 + - 239 + name: ovpn-peer-new-input 240 + subset-of: ovpn 241 + attributes: 242 + - 243 + name: ifindex 244 + - 245 + name: peer 246 + nested-attributes: peer-new-input 247 + - 248 + name: ovpn-peer-set-input 249 + subset-of: ovpn 250 + attributes: 251 + - 252 + name: ifindex 253 + - 254 + name: peer 255 + nested-attributes: peer-set-input 256 + - 257 + name: ovpn-peer-del-input 258 + subset-of: ovpn 259 + attributes: 260 + - 261 + name: ifindex 262 + - 263 + name: peer 264 + nested-attributes: peer-del-input 265 + - 266 + name: ovpn-keyconf-get 267 + subset-of: ovpn 268 + attributes: 269 + - 270 + name: ifindex 271 + - 272 + name: keyconf 273 + nested-attributes: keyconf-get 274 + - 275 + name: ovpn-keyconf-swap-input 276 + subset-of: ovpn 277 + attributes: 278 + - 279 + name: ifindex 280 + - 281 + name: keyconf 282 + nested-attributes: keyconf-swap-input 283 + - 284 + name: ovpn-keyconf-del-input 285 + subset-of: ovpn 286 + attributes: 287 + - 288 + name: ifindex 289 + - 290 + name: keyconf 291 + nested-attributes: keyconf-del-input 325 292 326 293 operations: 327 294 list: 328 295 - 329 296 name: peer-new 330 - attribute-set: ovpn 297 + attribute-set: ovpn-peer-new-input 331 298 flags: [ admin-perm ] 332 299 doc: Add a remote peer 333 300 do: ··· 393 252 - peer 394 253 - 395 254 name: peer-set 396 - attribute-set: ovpn 255 + attribute-set: ovpn-peer-set-input 397 256 flags: [ admin-perm ] 398 257 doc: modify a remote peer 399 258 do: ··· 427 286 - peer 428 287 - 429 288 name: peer-del 430 - attribute-set: ovpn 289 + attribute-set: ovpn-peer-del-input 431 290 flags: [ admin-perm ] 432 291 doc: Delete existing remote peer 433 292 do: ··· 457 316 - keyconf 458 317 - 459 318 name: key-get 460 - attribute-set: ovpn 319 + attribute-set: ovpn-keyconf-get 461 320 flags: [ admin-perm ] 462 321 doc: Retrieve non-sensitive data about peer key and cipher 463 322 do: ··· 472 331 - keyconf 473 332 - 474 333 name: key-swap 475 - attribute-set: ovpn 334 + attribute-set: ovpn-keyconf-swap-input 476 335 flags: [ admin-perm ] 477 336 doc: Swap primary and secondary session keys for a specific peer 478 337 do: ··· 491 350 mcgrp: peers 492 351 - 493 352 name: key-del 494 - attribute-set: ovpn 353 + attribute-set: ovpn-keyconf-del-input 495 354 flags: [ admin-perm ] 496 355 doc: Delete cipher key for a specific peer 497 356 do:
+7
drivers/net/ovpn/io.c
··· 62 62 unsigned int pkt_len; 63 63 int ret; 64 64 65 + /* 66 + * GSO state from the transport layer is not valid for the tunnel/data 67 + * path. Reset all GSO fields to prevent any further GSO processing 68 + * from entering an inconsistent state. 69 + */ 70 + skb_gso_reset(skb); 71 + 65 72 /* we can't guarantee the packet wasn't corrupted before entering the 66 73 * VPN, therefore we give other layers a chance to check that 67 74 */
+43 -8
drivers/net/ovpn/netlink.c
··· 352 352 return -EINVAL; 353 353 354 354 ret = nla_parse_nested(attrs, OVPN_A_PEER_MAX, info->attrs[OVPN_A_PEER], 355 - ovpn_peer_nl_policy, info->extack); 355 + ovpn_peer_new_input_nl_policy, info->extack); 356 356 if (ret) 357 357 return ret; 358 358 ··· 476 476 return -EINVAL; 477 477 478 478 ret = nla_parse_nested(attrs, OVPN_A_PEER_MAX, info->attrs[OVPN_A_PEER], 479 - ovpn_peer_nl_policy, info->extack); 479 + ovpn_peer_set_input_nl_policy, info->extack); 480 480 if (ret) 481 481 return ret; 482 482 ··· 654 654 struct ovpn_peer *peer; 655 655 struct sk_buff *msg; 656 656 u32 peer_id; 657 - int ret; 657 + int ret, i; 658 658 659 659 if (GENL_REQ_ATTR_CHECK(info, OVPN_A_PEER)) 660 660 return -EINVAL; ··· 667 667 if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_PEER], attrs, 668 668 OVPN_A_PEER_ID)) 669 669 return -EINVAL; 670 + 671 + /* OVPN_CMD_PEER_GET expects only the PEER_ID, therefore 672 + * ensure that the user hasn't specified any other attribute. 673 + * 674 + * Unfortunately this check cannot be performed via netlink 675 + * spec/policy and must be open-coded. 676 + */ 677 + for (i = 0; i < OVPN_A_PEER_MAX + 1; i++) { 678 + if (i == OVPN_A_PEER_ID) 679 + continue; 680 + 681 + if (attrs[i]) { 682 + NL_SET_ERR_MSG_FMT_MOD(info->extack, 683 + "unexpected attribute %u", i); 684 + return -EINVAL; 685 + } 686 + } 670 687 671 688 peer_id = nla_get_u32(attrs[OVPN_A_PEER_ID]); 672 689 peer = ovpn_peer_get_by_id(ovpn, peer_id); ··· 785 768 return -EINVAL; 786 769 787 770 ret = nla_parse_nested(attrs, OVPN_A_PEER_MAX, info->attrs[OVPN_A_PEER], 788 - ovpn_peer_nl_policy, info->extack); 771 + ovpn_peer_del_input_nl_policy, info->extack); 789 772 if (ret) 790 773 return ret; 791 774 ··· 986 969 struct ovpn_peer *peer; 987 970 struct sk_buff *msg; 988 971 u32 peer_id; 989 - int ret; 972 + int ret, i; 990 973 991 974 if (GENL_REQ_ATTR_CHECK(info, OVPN_A_KEYCONF)) 992 975 return -EINVAL; 993 976 994 977 ret = nla_parse_nested(attrs, OVPN_A_KEYCONF_MAX, 995 978 info->attrs[OVPN_A_KEYCONF], 996 - ovpn_keyconf_nl_policy, info->extack); 979 + ovpn_keyconf_get_nl_policy, info->extack); 997 980 if (ret) 998 981 return ret; 999 982 ··· 1004 987 if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_KEYCONF], attrs, 1005 988 OVPN_A_KEYCONF_SLOT)) 1006 989 return -EINVAL; 990 + 991 + /* OVPN_CMD_KEY_GET expects only the PEER_ID and the SLOT, therefore 992 + * ensure that the user hasn't specified any other attribute. 993 + * 994 + * Unfortunately this check cannot be performed via netlink 995 + * spec/policy and must be open-coded. 996 + */ 997 + for (i = 0; i < OVPN_A_KEYCONF_MAX + 1; i++) { 998 + if (i == OVPN_A_KEYCONF_PEER_ID || 999 + i == OVPN_A_KEYCONF_SLOT) 1000 + continue; 1001 + 1002 + if (attrs[i]) { 1003 + NL_SET_ERR_MSG_FMT_MOD(info->extack, 1004 + "unexpected attribute %u", i); 1005 + return -EINVAL; 1006 + } 1007 + } 1007 1008 1008 1009 peer_id = nla_get_u32(attrs[OVPN_A_KEYCONF_PEER_ID]); 1009 1010 peer = ovpn_peer_get_by_id(ovpn, peer_id); ··· 1072 1037 1073 1038 ret = nla_parse_nested(attrs, OVPN_A_KEYCONF_MAX, 1074 1039 info->attrs[OVPN_A_KEYCONF], 1075 - ovpn_keyconf_nl_policy, info->extack); 1040 + ovpn_keyconf_swap_input_nl_policy, info->extack); 1076 1041 if (ret) 1077 1042 return ret; 1078 1043 ··· 1109 1074 1110 1075 ret = nla_parse_nested(attrs, OVPN_A_KEYCONF_MAX, 1111 1076 info->attrs[OVPN_A_KEYCONF], 1112 - ovpn_keyconf_nl_policy, info->extack); 1077 + ovpn_keyconf_del_input_nl_policy, info->extack); 1113 1078 if (ret) 1114 1079 return ret; 1115 1080
+1
drivers/net/ovpn/udp.c
··· 344 344 int ret; 345 345 346 346 skb->dev = peer->ovpn->dev; 347 + skb->mark = READ_ONCE(sk->sk_mark); 347 348 /* no checksum performed at this layer */ 348 349 skb->ip_summed = CHECKSUM_NONE; 349 350