ids.origDest = dest;
ids.hopLocal = dest;
ids.protocol = dnsdist::Protocol::DoUDP;
- ids.xskPacketHeader = packet.cloneHeadertoPacketBuffer();
+ ids.xskPacketHeader = packet.cloneHeaderToPacketBuffer();
try {
bool expectProxyProtocol = false;
fuzz_targets_programs = \
fuzz_target_dnsdistcache
+if HAVE_XSK
+fuzz_targets_programs += \
+ fuzz_target_xsk
+endif
+
fuzz_targets: $(ARC4RANDOM_LIBS) $(fuzz_targets_programs)
bin_PROGRAMS += \
fuzz_target_dnsdistcache_LDFLAGS = $(fuzz_targets_ldflags)
fuzz_target_dnsdistcache_LDADD = $(fuzz_targets_libs)
-endif
+if HAVE_XSK
+fuzz_target_xsk_SOURCES = \
+ dnslabeltext.cc \
+ dnsname.cc dnsname.hh \
+ fuzz_xsk.cc \
+ gettime.cc gettime.hh \
+ iputils.cc iputils.hh \
+ misc.cc misc.hh \
+ xsk.cc xsk.hh
+fuzz_target_xsk_DEPENDENCIES = $(fuzz_targets_deps)
+fuzz_target_xsk_LDFLAGS = $(fuzz_targets_ldflags)
+fuzz_target_xsk_LDADD = $(fuzz_targets_libs) -lbpf -lxdp
+endif # HAVE_XSK
+
+endif # FUZZ_TARGETS
MANPAGES=dnsdist.1
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "xsk.hh"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+#ifdef HAVE_XSK
+ if (size > XskSocket::getFrameSize()) {
+ return 0;
+ }
+
+ try {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast): packet data is usually mutable
+ XskPacket packet(const_cast<uint8_t*>(data), size, size);
+ if (packet.parse(false)) {
+ const auto& dest = packet.getToAddr();
+ const auto& orig = packet.getFromAddr();
+ const auto* payload = packet.getPayloadData();
+ auto capacity = packet.getCapacity();
+ auto length = packet.getDataLen();
+ auto frameLen = packet.getFrameLen();
+ auto header = packet.cloneHeaderToPacketBuffer();
+ auto buffer = packet.clonePacketBuffer();
+ (void) dest;
+ (void) orig;
+ (void) payload;
+ (void) capacity;
+ (void) length;
+ (void) frameLen;
+ }
+ }
+ catch (const std::exception& e) {
+ }
+#endif /* HAVE_XSK */
+ return 0;
+}
uniqueEmptyFrameOffset.reserve(frameNum);
{
- for (uint64_t i = 0; i < frameNum; i++) {
- uniqueEmptyFrameOffset.push_back(i * frameSize + XDP_PACKET_HEADROOM);
+ for (uint64_t idx = 0; idx < frameNum; idx++) {
+ uniqueEmptyFrameOffset.push_back(idx * frameSize + XDP_PACKET_HEADROOM);
#ifdef DEBUG_UMEM
{
auto umems = s_umems.lock();
- (*umems)[i * frameSize + XDP_PACKET_HEADROOM] = UmemEntryStatus();
+ (*umems)[idx * frameSize + XDP_PACKET_HEADROOM] = UmemEntryStatus();
}
#endif /* DEBUG_UMEM */
}
}
bpf_xdp_query_opts info{};
info.sz = sizeof(info);
- int ret = bpf_xdp_query(itfIdx, 0, &info);
+ int ret = bpf_xdp_query(static_cast<int>(itfIdx), 0, &info);
if (ret != 0) {
return {};
}
[[nodiscard]] iphdr XskPacket::getIPv4Header() const noexcept
{
iphdr ipv4Header{};
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
assert(frameLength >= (sizeof(ethhdr) + sizeof(ipv4Header)));
assert(!v6);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
void XskPacket::setIPv4Header(const iphdr& ipv4Header) noexcept
{
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
assert(frameLength >= (sizeof(ethhdr) + sizeof(iphdr)));
assert(!v6);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
[[nodiscard]] ipv6hdr XskPacket::getIPv6Header() const noexcept
{
ipv6hdr ipv6Header{};
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
assert(frameLength >= (sizeof(ethhdr) + sizeof(ipv6Header)));
assert(v6);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
void XskPacket::setIPv6Header(const ipv6hdr& ipv6Header) noexcept
{
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
assert(frameLength >= (sizeof(ethhdr) + sizeof(ipv6Header)));
assert(v6);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
[[nodiscard]] udphdr XskPacket::getUDPHeader() const noexcept
{
udphdr udpHeader{};
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
assert(frameLength >= (sizeof(ethhdr) + (v6 ? sizeof(ipv6hdr) : sizeof(iphdr)) + sizeof(udpHeader)));
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
memcpy(&udpHeader, frame + getL4HeaderOffset(), sizeof(udpHeader));
{
const auto size = getDataSize();
PacketBuffer tmp(size);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- memcpy(tmp.data(), frame + getDataOffset(), size);
+ if (size > 0) {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+ memcpy(tmp.data(), frame + getDataOffset(), size);
+ }
return tmp;
}
-void XskPacket::cloneIntoPacketBuffer(PacketBuffer& buffer) const
-{
- const auto size = getDataSize();
- buffer.resize(size);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- memcpy(buffer.data(), frame + getDataOffset(), size);
-}
-
bool XskPacket::setPayload(const PacketBuffer& buf)
{
const auto bufSize = buf.size();
}
}
-PacketBuffer XskPacket::cloneHeadertoPacketBuffer() const
+PacketBuffer XskPacket::cloneHeaderToPacketBuffer() const
{
const auto size = getFrameLen() - getDataSize();
PacketBuffer tmp(size);
*/
#pragma once
+#include "config.h"
#ifdef HAVE_XSK
#include <array>
class XskWorker;
class XskSocket;
+#ifdef HAVE_XSK
using MACAddr = std::array<uint8_t, 6>;
-#ifdef HAVE_XSK
using XskPacketPtr = std::unique_ptr<XskPacket>;
// We use an XskSocket to manage an AF_XDP Socket corresponding to a NIC queue.
[[nodiscard]] uint32_t getDataLen() const noexcept;
[[nodiscard]] uint32_t getFrameLen() const noexcept;
[[nodiscard]] PacketBuffer clonePacketBuffer() const;
- void cloneIntoPacketBuffer(PacketBuffer& buffer) const;
- [[nodiscard]] PacketBuffer cloneHeadertoPacketBuffer() const;
+ [[nodiscard]] PacketBuffer cloneHeaderToPacketBuffer() const;
void setAddr(const ComboAddress& from_, MACAddr fromMAC, const ComboAddress& to_, MACAddr toMAC) noexcept;
bool setPayload(const PacketBuffer& buf);
void rewrite() noexcept;