While reviewing the struct proto_ops connect() and bind() callback
implementations, I noticed that there doesn't appear to be any
validation that AF_PPPOX sockaddr structures actually have sa_family set
to AF_PPPOX. The pppol2tp_sockaddr_get_info() checks only look at the
sizes.
I don't see any way that this might actually cause problems as specific
info fields are being populated, for which the existing size checks are
correct, but it stood out as a missing address family check.
Add the check and return -EAFNOSUPPORT on mismatch.
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: James Chapman <jchapman@katalix.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Cc: <redacted>
---
net/l2tp/l2tp_ppp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index fc5c2fd8f34c..767b393cbb78 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -545,6 +545,13 @@ struct l2tp_connect_info {
static int pppol2tp_sockaddr_get_info(const void *sa, int sa_len,
struct l2tp_connect_info *info)
{
+ const struct sockaddr_unspec *sockaddr = sa;
+
+ if (sa_len < offsetofend(struct sockaddr, sa_family))
+ return -EINVAL;
+ if (sockaddr->sa_family != AF_PPPOX)
+ return -EAFNOSUPPORT;
+
switch (sa_len) {
case sizeof(struct sockaddr_pppol2tp):
{--
2.34.1