Fix compat with Linux programs that use longer namelen for sockets

Linux is less strict than NetBSD and permits namelen to be larger
than valid struct sockaddr_in*.  If this is the case, truncate the value
to the correct size, so that NetBSD networking does not return an error.

Reviewed by kamil
This commit is contained in:
mgorny 2020-10-24 09:01:56 +00:00
parent 13d43c5eec
commit 62a92db07d
1 changed files with 17 additions and 2 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_socket.c,v 1.150 2020/07/16 15:02:08 msaitoh Exp $ */
/* $NetBSD: linux_socket.c,v 1.151 2020/10/24 09:01:56 mgorny Exp $ */
/*-
* Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.150 2020/07/16 15:02:08 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.151 2020/10/24 09:01:56 mgorny Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@ -1612,6 +1612,21 @@ linux_get_sa(struct lwp *l, int s, struct sockaddr_big *sb,
sin6->sin6_scope_id = 0;
}
/*
* Linux is less strict than NetBSD and permits namelen to be larger
* than valid struct sockaddr_in*. If this is the case, truncate
* the value to the correct size, so that NetBSD networking does not
* return an error.
*/
switch (bdom) {
case AF_INET:
namelen = MIN(namelen, sizeof(struct sockaddr_in));
break;
case AF_INET6:
namelen = MIN(namelen, sizeof(struct sockaddr_in6));
break;
}
sb->sb_family = bdom;
sb->sb_len = namelen;
ktrkuser("mbsoname", sb, namelen);