db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: Drop supplementary groups when changing to non-root

Summary: When running HHVM as a non-root user, UID and GID are updated correctly but supplementary groups are not dropped properly. This runs initgroups inside main thread and lightprocess threads to reset groups to those of the specified non-root user.

Reviewed By: @markw65

Differential Revision: D1193229
CVE: CVE-2014-2209
CWE: CWE-264
Vulnerability description: Facebook HipHop Virtual Machine (HHVM) before 3.1.0 does not drop supplemental group memberships within hphp/util/capability.cpp and hphp/util/light-process.cpp, which allows remote attackers to bypass intended access restrictions by leveraging group permissions for a file or directory.

Project: hhvm
File: capability.cpp

bool Capability::ChangeUnixUser(uid_t uid) {
  if (setInitialCapabilities()) {
    struct passwd *pw;

    if ((pw = getpwuid(uid)) == nullptr) {
      Logger::Error("unable to getpwuid(%d): %s", uid,
                    folly::errnoStr(errno).c_str());
      return false;
    }

    if (pw->pw_gid == 0 || setgid(pw->pw_gid) < 0) {
      Logger::Error("unable to drop gid privs: %s",
                    folly::errnoStr(errno).c_str());
      return false;
    }

    if (uid == 0 || setuid(uid) < 0) {
      Logger::Error("unable to drop uid privs: %s",
                    folly::errnoStr(errno).c_str());
      return false;
    }

    if (!setMinimalCapabilities()) {
      Logger::Error("unable to set minimal server capabiltiies");
      return false;
    }
    return true;
  }
  return false;
}

Project: hhvm
File: light-process.cpp

static void do_change_user(FILE *fin, FILE *fout) {
  std::string uname;
  lwp_read(fin, uname);
  if (uname.length() > 0) {
    struct passwd *pw = getpwnam(uname.c_str());
    if (pw) {
      if (pw->pw_gid) {
        setgid(pw->pw_gid);
      }
      if (pw->pw_uid) {
        setuid(pw->pw_uid);
      }
    }
  }
}
Commit message: CVE-2019-3557: Fix OOB read in readRecord on BZ2Files/OutputFiles

Summary:
These File subclasses return -1 on read errors which is not what is
expected for readImpl--this made File::readRecord behave unusually if the read
fails, causing it to read (size_t)(-1) bytes from its stream buffer; which,
unsurprisingly produces a out-of-bounds heap read.

Reviewed By: leikahing, jjgriego

Differential Revision: D13659395

fbshipit-source-id: 359ed6e3ff9f9cf49b752b666f51c4e0b3ce4b8a
CVE: CVE-2019-3557
CWE: CWE-125
Vulnerability description: The implementations of streams for bz2 and php://output improperly implemented their readImpl functions, returning -1 consistently. This behavior caused some stream functions, such as stream_get_line, to trigger an out-of-bounds read when operating on such malformed streams. The implementations were updated to return valid values consistently. This affects all supported versions of HHVM (3.30 and 3.27.4 and below).

Project: hhvm
File: output-file.cpp

int64_t OutputFile::readImpl(char* /*buffer*/, int64_t /*length*/) {
  raise_warning("cannot read from a php://output stream");
  return -1;
}

Project: hhvm
File: bz2-file.cpp

int64_t BZ2File::readImpl(char * buf, int64_t length) {
  if (length == 0) {
    return 0;
  }
  assertx(m_bzFile);
  int len = BZ2_bzread(m_bzFile, buf, length);
  /* Sometimes libbz2 will return fewer bytes than requested, and set bzerror
   * to BZ_STREAM_END, but it's not actually EOF, and you can keep reading from
   * the file - so, only set EOF after a failed read. This matches PHP5.
   */
  if (len <= 0) {
    setEof(true);
    if (len < 0) {
      return -1;
    }
  }
  return len;
}
Commit message: Use case-insensitive switch comparisons
CVE: CVE-2018-1000118
CWE: CWE-200
Vulnerability description: Github Electron version Electron 1.8.2-beta.4 and earlier contains a Command Injection vulnerability in Protocol Handler that can result in command execute. This attack appear to be exploitable via the victim opening an electron protocol handler in their browser. This vulnerability appears to have been fixed in Electron 1.8.2-beta.5. This issue is due to an incomplete fix for CVE-2018-1000006, specifically the black list used was not case insensitive allowing an attacker to potentially bypass it.

Project: electron
File: command_line_args.cc

bool IsBlacklistedArg(const base::CommandLine::CharType* arg) {
#if defined(OS_WIN)
  const auto converted = base::WideToUTF8(arg);
  const char* a = converted.c_str();
#else
  const char* a = arg;
#endif

  static const char* prefixes[] = {"--", "-", "/"};

  int prefix_length = 0;
  for (auto& prefix : prefixes) {
    if (base::StartsWith(a, prefix, base::CompareCase::SENSITIVE)) {
      prefix_length = strlen(prefix);
      break;
    }
  }

  if (prefix_length > 0) {
    a += prefix_length;
    std::string switch_name(a, strcspn(a, "="));
    auto* iter = std::lower_bound(std::begin(kBlacklist), std::end(kBlacklist),
                                  switch_name);
    if (iter != std::end(kBlacklist) && switch_name == *iter) {
      return true;
    }
  }

  return false;
}
Commit message: Do not let lanlink connections stay open for long without authenticating

If there's no information received, close the socket to try again.

Thanks Matthias Gerstner <mgerstner@suse.de> for reporting this.
CVE: CVE-2020-26164
CWE: CWE-703
Vulnerability description: In kdeconnect-kde (aka KDE Connect) before 20.08.2, an attacker on the local network could send crafted packets that trigger use of large amounts of CPU, memory, or network connection slots, aka a Denial of Service attack.

Project: kdeconnect-kde
File: lanlinkprovider.cpp

void LanLinkProvider::newConnection()
{
    qCDebug(KDECONNECT_CORE) << "LanLinkProvider newConnection";

    while (m_server->hasPendingConnections()) {
        QSslSocket* socket = m_server->nextPendingConnection();
        configureSocket(socket);
        //This socket is still managed by us (and child of the QTcpServer), if
        //it disconnects before we manage to pass it to a LanDeviceLink, it's
        //our responsibility to delete it. We do so with this connection.
        connect(socket, &QAbstractSocket::disconnected,
                socket, &QObject::deleteLater);
        connect(socket, &QIODevice::readyRead,
                this, &LanLinkProvider::dataReceived);

    }
}
Commit message: fix #55 : check too big code point value for single byte value in next_state_val()
CVE: CVE-2017-9226
CWE: CWE-787
Vulnerability description: An issue was discovered in Oniguruma 6.2.0, as used in Oniguruma-mod in Ruby through 2.4.1 and mbstring in PHP through 7.1.5. A heap out-of-bounds write or read occurs in next_state_val() during regular expression compilation. Octal numbers larger than 0xff are not handled correctly in fetch_token() and fetch_token_in_cc(). A malformed regular expression containing an octal number in the form of '\700' would produce an invalid code point value larger than 0xff in next_state_val(), resulting in an out-of-bounds write memory corruption.

Project: oniguruma
File: regparse.c

next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v,
	       int* vs_israw, int v_israw,
	       enum CCVALTYPE intype, enum CCVALTYPE* type,
	       enum CCSTATE* state, ScanEnv* env)
{
  int r;

  switch (*state) {
  case CCS_VALUE:
    if (*type == CCV_SB) {
      BITSET_SET_BIT(cc->bs, (int )(*vs));
    }
    else if (*type == CCV_CODE_POINT) {
      r = add_code_range(&(cc->mbuf), env, *vs, *vs);
      if (r < 0) return r;
    }
    break;

  case CCS_RANGE:
    if (intype == *type) {
      if (intype == CCV_SB) {
        if (*vs > 0xff || v > 0xff)
          return ONIGERR_INVALID_CODE_POINT_VALUE;

        if (*vs > v) {
          if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
            goto ccs_range_end;
          else
            return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
        }
        bitset_set_range(cc->bs, (int )*vs, (int )v);
      }
      else {
        r = add_code_range(&(cc->mbuf), env, *vs, v);
        if (r < 0) return r;
      }
    }
    else {
#if 0
      if (intype == CCV_CODE_POINT && *type == CCV_SB) {
#endif
        if (*vs > v) {
          if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
            goto ccs_range_end;
          else
            return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
        }
        bitset_set_range(cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
        r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*vs, v);
        if (r < 0) return r;
#if 0
      }
      else
        return ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE;
#endif
    }
  ccs_range_end:
    *state = CCS_COMPLETE;
    break;

  case CCS_COMPLETE:
  case CCS_START:
    *state = CCS_VALUE;
    break;

  default:
    break;
  }

  *vs_israw = v_israw;
  *vs       = v;
  *type     = intype;
  return 0;
}
Commit message: BUG/MAJOR: htx: fix missing header name length check in htx_add_header/trailer

Ori Hollander of JFrog Security reported that htx_add_header() and
htx_add_trailer() were missing a length check on the header name. While
this does not allow to overwrite any memory area, it results in bits of
the header name length to slip into the header value length and may
result in forging certain header names on the input. The sad thing here
is that a FIXME comment was present suggesting to add the required length
checks :-(

The injected headers are visible to the HTTP internals and to the config
rules, so haproxy will generally stay synchronized with the server. But
there is one exception which is the content-length header field, because
it is already deduplicated on the input, but before being indexed. As
such, injecting a content-length header after the deduplication stage
may be abused to present a different, shorter one on the other side and
help build a request smuggling attack, or even maybe a response splitting
attack. CVE-2021-40346 was assigned to this problem.

As a mitigation measure, it is sufficient to verify that no more than
one such header is present in any message, which is normally the case
thanks to the duplicate checks:

   http-request  deny if { req.hdr_cnt(content-length) gt 1 }
   http-response deny if { res.hdr_cnt(content-length) gt 1 }

This must be backported to all HTX-enabled versions, hence as far as 2.0.
In 2.3 and earlier, the functions are in src/htx.c instead.

Many thanks to Ori for his work and his responsible report!
CVE: CVE-2021-40346
CWE: CWE-190
Vulnerability description: An integer overflow exists in HAProxy 2.0 through 2.5 in htx_add_header that can be exploited to perform an HTTP request smuggling attack, allowing an attacker to bypass all configured http-request HAProxy ACLs and possibly other ACLs.

Project: haproxy
File: htx.h

static inline struct htx_blk *htx_add_header(struct htx *htx, const struct ist name,
					     const struct ist value)
{
	struct htx_blk *blk;

	/* FIXME: check name.len (< 256B) and value.len (< 1MB) */
	blk = htx_add_blk(htx, HTX_BLK_HDR, name.len + value.len);
	if (!blk)
		return NULL;

	blk->info += (value.len << 8) + name.len;
	ist2bin_lc(htx_get_blk_ptr(htx, blk), name);
	memcpy(htx_get_blk_ptr(htx, blk)  + name.len, value.ptr, value.len);
	return blk;
}
Commit message: Prevent an OOB read in `expand_dims.cc`

The for loop that follows this check assumes that `axis` is between `0` and `input_dims.size`. If user supplied `axis` is negative, the if code before this check is supposed to bring it back to positive (similar to how in Python one can do `l[-3]` to mean `l[-3 + len(l)]`).

PiperOrigin-RevId: 387200206
Change-Id: I162f4feba12d547c3a4340833ae682016a2ebfab
CVE: CVE-2021-37685
CWE: CWE-125
Vulnerability description: TensorFlow is an end-to-end open source platform for machine learning. In affected versions TFLite's [`expand_dims.cc`](https://github.com/tensorflow/tensorflow/blob/149562d49faa709ea80df1d99fc41d005b81082a/tensorflow/lite/kernels/expand_dims.cc#L36-L50) contains a vulnerability which allows reading one element outside of bounds of heap allocated data. If `axis` is a large negative value (e.g., `-100000`), then after the first `if` it would still be negative. The check following the `if` statement will pass and the `for` loop would read one element before the start of `input_dims.data` (when `i = 0`). We have patched the issue in GitHub commit d94ffe08a65400f898241c0374e9edc6fa8ed257. The fix will be included in TensorFlow 2.6.0. We will also cherrypick this commit on TensorFlow 2.5.1, TensorFlow 2.4.3, and TensorFlow 2.3.4, as these are also affected and still in supported range.

Project: tensorflow
File: expand_dims.cc

TfLiteStatus ExpandTensorDim(TfLiteContext* context, const TfLiteTensor& input,
                             int axis, TfLiteTensor* output) {
  const TfLiteIntArray& input_dims = *input.dims;
  if (axis < 0) {
    axis = input_dims.size + 1 + axis;
  }
  TF_LITE_ENSURE(context, axis <= input_dims.size);

  TfLiteIntArray* output_dims = TfLiteIntArrayCreate(input_dims.size + 1);
  for (int i = 0; i < output_dims->size; ++i) {
    if (i < axis) {
      output_dims->data[i] = input_dims.data[i];
    } else if (i == axis) {
      output_dims->data[i] = 1;
    } else {
      output_dims->data[i] = input_dims.data[i - 1];
    }
  }

  return context->ResizeTensor(context, output, output_dims);
}
Commit message: Don't assume TDRC is an instance of TextIdentificationFrame (#831)

If TDRC is encrypted, FrameFactory::createFrame() returns UnknownFrame
which causes problems in rebuildAggregateFrames() when it is assumed
that TDRC is a TextIdentificationFrame
CVE: CVE-2017-12678
CWE: CWE-352
Vulnerability description: In TagLib 1.11.1, the rebuildAggregateFrames function in id3v2framefactory.cpp has a pointer to cast vulnerability, which allows remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted audio file.

Project: taglib
File: id3v2framefactory.cpp

void FrameFactory::rebuildAggregateFrames(ID3v2::Tag *tag) const
{
  if(tag->header()->majorVersion() < 4 &&
     tag->frameList("TDRC").size() == 1 &&
     tag->frameList("TDAT").size() == 1)
  {
    TextIdentificationFrame *tdrc =
      static_cast<TextIdentificationFrame *>(tag->frameList("TDRC").front());
    UnknownFrame *tdat = static_cast<UnknownFrame *>(tag->frameList("TDAT").front());

    if(tdrc->fieldList().size() == 1 &&
       tdrc->fieldList().front().size() == 4 &&
       tdat->data().size() >= 5)
    {
      String date(tdat->data().mid(1), String::Type(tdat->data()[0]));
      if(date.length() == 4) {
        tdrc->setText(tdrc->toString() + '-' + date.substr(2, 2) + '-' + date.substr(0, 2));
        if(tag->frameList("TIME").size() == 1) {
          UnknownFrame *timeframe = static_cast<UnknownFrame *>(tag->frameList("TIME").front());
          if(timeframe->data().size() >= 5) {
            String time(timeframe->data().mid(1), String::Type(timeframe->data()[0]));
            if(time.length() == 4) {
              tdrc->setText(tdrc->toString() + 'T' + time.substr(0, 2) + ':' + time.substr(2, 2));
            }
          }
        }
      }
    }
  }
}
Commit message: - COTP: fixed possible heap buffer overflow when handling message with invalid (zero) value in length field (#250)
CVE: CVE-2020-15158
CWE: CWE-122
Vulnerability description: In libIEC61850 before version 1.4.3, when a message with COTP message length field with value < 4 is received an integer underflow will happen leading to heap buffer overflow. This can cause an application crash or on some platforms even the execution of remote code. If your application is used in open networks or there are untrusted nodes in the network it is highly recommend to apply the patch. This was patched with commit 033ab5b. Users of version 1.4.x should upgrade to version 1.4.3 when available. As a workaround changes of commit 033ab5b can be applied to older versions.

Project: libiec61850
File: cotp.c

CotpConnection_readToTpktBuffer(CotpConnection* self)
{
    uint8_t* buffer = self->readBuffer->buffer;
    int bufferSize = self->readBuffer->maxSize;
    int bufPos = self->readBuffer->size;

    assert (bufferSize > 4);

    int readBytes;

    if (bufPos < 4) {

        readBytes = readFromSocket(self, buffer + bufPos, 4 - bufPos);

        if (readBytes < 0)
            goto exit_closed;

        if (DEBUG_COTP) {
            if (readBytes > 0)
                printf("TPKT: read %i bytes from socket\n", readBytes);
        }

        bufPos += readBytes;

        if (bufPos == 4) {
            if ((buffer[0] == 3) && (buffer[1] == 0)) {
                self->packetSize = (buffer[2] * 0x100) + buffer[3];

                if (DEBUG_COTP)
                    printf("TPKT: header complete (msg size = %i)\n", self->packetSize);

                if (self->packetSize > bufferSize) {
                    if (DEBUG_COTP) printf("TPKT: packet too large\n");
                    goto exit_error;
                }
            }
            else {
                if (DEBUG_COTP) printf("TPKT: failed to decode TPKT header.\n");
                goto exit_error;
            }
        }
        else
            goto exit_waiting;
    }

    readBytes = readFromSocket(self, buffer + bufPos, self->packetSize - bufPos);

    if (readBytes < 0)
        goto exit_closed;

    bufPos += readBytes;

    if (bufPos < self->packetSize)
       goto exit_waiting;

    if (DEBUG_COTP) printf("TPKT: message complete (size = %i)\n", self->packetSize);

    self->readBuffer->size = bufPos;
    return TPKT_PACKET_COMPLETE;

exit_closed:
    if (DEBUG_COTP) printf("TPKT: socket closed or socket error\n");
    return TPKT_ERROR;

exit_error:
    if (DEBUG_COTP) printf("TPKT: Error parsing message\n");
    return TPKT_ERROR;

exit_waiting:

    if (DEBUG_COTP)
        if (bufPos != 0)
            printf("TPKT: waiting (read %i of %i)\n", bufPos, self->packetSize);

    self->readBuffer->size = bufPos;
    return TPKT_WAITING;
}
Commit message: Prevent a null pointer exception in TFLite

PiperOrigin-RevId: 370800206
Change-Id: Idd437ebce4ff224120d8eefc1c14c062173b71d6
CVE: CVE-2021-29590
CWE: CWE-125
Vulnerability description: TensorFlow is an end-to-end open source platform for machine learning. The implementations of the `Minimum` and `Maximum` TFLite operators can be used to read data outside of bounds of heap allocated objects, if any of the two input tensor arguments are empty. This is because the broadcasting implementation(https://github.com/tensorflow/tensorflow/blob/0d45ea1ca641b21b73bcf9c00e0179cda284e7e7/tensorflow/lite/kernels/internal/reference/maximum_minimum.h#L52-L56) indexes in both tensors with the same index but does not validate that the index is within bounds. The fix will be included in TensorFlow 2.5.0. We will also cherrypick this commit on TensorFlow 2.4.2, TensorFlow 2.3.3, TensorFlow 2.2.3 and TensorFlow 2.1.4, as these are also affected and still in supported range.

Project: tensorflow
File: maximum_minimum.cc

TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) {
  OpContext op_context(context, node);

    switch (op_context.output->type) {
      case kTfLiteFloat32:
        TFLiteOperation<kernel_type, float, OpType>(context, node, op_context);
        break;
      case kTfLiteUInt8:
        TFLiteOperation<kernel_type, uint8_t, OpType>(context, node,
                                                      op_context);
        break;
      case kTfLiteInt8:
        TFLiteOperation<kernel_type, int8_t, OpType>(context, node, op_context);
        break;
      case kTfLiteInt32:
        TFLiteOperation<kernel_type, int32_t, OpType>(context, node,
                                                      op_context);
        break;
      case kTfLiteInt64:
        TFLiteOperation<kernel_type, int64_t, OpType>(context, node,
                                                      op_context);
        break;
      case kTfLiteInt16:
        TFLiteOperation<kernel_type, int16_t, OpType>(context, node,
                                                      op_context);
        break;
      default:
        context->ReportError(context,
                             "Type %d is currently not supported by Maximum.",
                             op_context.output->type);
        return kTfLiteError;
    }
  return kTfLiteOk;
}
Commit message: patch 8.2.4154: ml_get error when exchanging windows in Visual mode

Problem:    ml_get error when exchanging windows in Visual mode.
Solution:   Correct end of Visual area when entering another buffer.
CVE: CVE-2022-0319
CWE: CWE-703
Vulnerability description: Out-of-bounds Read in vim/vim prior to 8.2.

Project: vim
File: window.c

win_exchange(long Prenum)
{
    frame_T	*frp;
    frame_T	*frp2;
    win_T	*wp;
    win_T	*wp2;
    int		temp;

    if (ERROR_IF_ANY_POPUP_WINDOW)
	return;
    if (ONE_WINDOW)	    // just one window
    {
	beep_flush();
	return;
    }

#ifdef FEAT_GUI
    need_mouse_correct = TRUE;
#endif

    /*
     * find window to exchange with
     */
    if (Prenum)
    {
	frp = curwin->w_frame->fr_parent->fr_child;
	while (frp != NULL && --Prenum > 0)
	    frp = frp->fr_next;
    }
    else if (curwin->w_frame->fr_next != NULL)	// Swap with next
	frp = curwin->w_frame->fr_next;
    else    // Swap last window in row/col with previous
	frp = curwin->w_frame->fr_prev;

    // We can only exchange a window with another window, not with a frame
    // containing windows.
    if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin)
	return;
    wp = frp->fr_win;

/*
 * 1. remove curwin from the list. Remember after which window it was in wp2
 * 2. insert curwin before wp in the list
 * if wp != wp2
 *    3. remove wp from the list
 *    4. insert wp after wp2
 * 5. exchange the status line height and vsep width.
 */
    wp2 = curwin->w_prev;
    frp2 = curwin->w_frame->fr_prev;
    if (wp->w_prev != curwin)
    {
	win_remove(curwin, NULL);
	frame_remove(curwin->w_frame);
	win_append(wp->w_prev, curwin);
	frame_insert(frp, curwin->w_frame);
    }
    if (wp != wp2)
    {
	win_remove(wp, NULL);
	frame_remove(wp->w_frame);
	win_append(wp2, wp);
	if (frp2 == NULL)
	    frame_insert(wp->w_frame->fr_parent->fr_child, wp->w_frame);
	else
	    frame_append(frp2, wp->w_frame);
    }
    temp = curwin->w_status_height;
    curwin->w_status_height = wp->w_status_height;
    wp->w_status_height = temp;
    temp = curwin->w_vsep_width;
    curwin->w_vsep_width = wp->w_vsep_width;
    wp->w_vsep_width = temp;

    frame_fix_height(curwin);
    frame_fix_height(wp);
    frame_fix_width(curwin);
    frame_fix_width(wp);

    (void)win_comp_pos();		// recompute window positions

    win_enter(wp, TRUE);
    redraw_all_later(NOT_VALID);
}
Commit message: Check sockaddr size in inet_pton

PiperOrigin-RevId: 333821843
Change-Id: Ie0b694f1edd3f7a4a3de6df964d68566961accf6
CVE: CVE-2020-8941
CWE: CWE-125
Vulnerability description: An arbitrary memory read vulnerability in Asylo versions up to 0.6.0 allows an untrusted attacker to make a call to enc_untrusted_inet_pton using an attacker controlled klinux_addr_buffer parameter. The parameter size is unchecked allowing the attacker to read memory locations outside of the intended buffer size including memory addresses within the secure enclave. We recommend upgrading past commit 8fed5e334131abaf9c5e17307642fbf6ce4a57ec

Project: asylo
File: host_calls.cc

int enc_untrusted_inet_pton(int af, const char *src, void *dst) {
  if (!src || !dst) {
    return 0;
  }

  MessageWriter input;
  input.Push<int>(TokLinuxAfFamily(af));
  input.PushByReference(Extent{
      src, std::min(strlen(src) + 1, static_cast<size_t>(INET6_ADDRSTRLEN))});
  MessageReader output;

  const auto status = NonSystemCallDispatcher(
      ::asylo::host_call::kInetPtonHandler, &input, &output);
  CheckStatusAndParamCount(status, output, "enc_untrusted_inet_pton", 3);

  int result = output.next<int>();
  int klinux_errno = output.next<int>();
  if (result == -1) {
    errno = FromkLinuxErrorNumber(klinux_errno);
    return -1;
  }

  auto klinux_addr_buffer = output.next();
  size_t max_size = 0;
  if (af == AF_INET) {
    max_size = sizeof(struct in_addr);
  } else if (af == AF_INET6) {
    max_size = sizeof(struct in6_addr);
  }
  memcpy(dst, klinux_addr_buffer.data(),
         std::min(klinux_addr_buffer.size(), max_size));
  return result;
}