diff --git a/src/add-ons/kernel/network/stack/datalink.cpp b/src/add-ons/kernel/network/stack/datalink.cpp index a89ae232b6..ef779f7e59 100644 --- a/src/add-ons/kernel/network/stack/datalink.cpp +++ b/src/add-ons/kernel/network/stack/datalink.cpp @@ -309,12 +309,15 @@ datalink_control(net_domain* _domain, int32 option, void* value, default: { - if (*_length < sizeof(struct ifreq)) + // We also accept partial ifreqs as long as the name is complete. + if (*_length < IF_NAMESIZE) return B_BAD_VALUE; + size_t length = min_c(sizeof(struct ifreq), *_length); + // try to pass the request to an existing interface struct ifreq request; - if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) + if (user_memcpy(&request, value, length) != B_OK) return B_BAD_ADDRESS; Interface* interface = get_interface(domain, request.ifr_name); diff --git a/src/add-ons/kernel/network/stack/interfaces.cpp b/src/add-ons/kernel/network/stack/interfaces.cpp index 5932188f6c..bd55c0f3a6 100644 --- a/src/add-ons/kernel/network/stack/interfaces.cpp +++ b/src/add-ons/kernel/network/stack/interfaces.cpp @@ -649,6 +649,9 @@ Interface::Control(net_domain* domain, int32 option, ifreq& request, switch (option) { case SIOCSIFFLAGS: { + if (length != sizeof(ifreq)) + return B_BAD_VALUE; + uint32 requestFlags = request.ifr_flags; uint32 oldFlags = flags; status_t status = B_OK; @@ -677,6 +680,9 @@ Interface::Control(net_domain* domain, int32 option, ifreq& request, case B_SOCKET_SET_ALIAS: { + if (length != sizeof(ifaliasreq)) + return B_BAD_VALUE; + RecursiveLocker locker(fLock); ifaliasreq aliasRequest; @@ -726,6 +732,9 @@ Interface::Control(net_domain* domain, int32 option, ifreq& request, case SIOCSIFDSTADDR: case SIOCDIFADDR: { + if (length != sizeof(ifreq)) + return B_BAD_VALUE; + RecursiveLocker locker(fLock); InterfaceAddress* address = NULL;