Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Read fails when using large buffers (starting from around 4GB)

Đang mở
#1,182 3 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

  • #2587 của @afonsojanu — đã đóng, không merge

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
c
Lĩnh vực
backend, networking

Hướng nghiên cứu

Start by tracing libssh2_channel_read and the receive-window adjustment code mentioned in the report, then inspect the types used for buffer lengths and window values. Reproduce with the supplied example or a focused test using a buffer near 4GB. Done means oversized reads no longer trigger the reported overflow or server error; the issue does not name a test file.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

enhancement

Description
libssh2_channel_read starts misbehaving when using large buffers, around 4GB or more in size. It seems that the API accepts size_t buflen which is 64bit (on my machine), but that gets converted to uint32_t in the implementation causing various problems. One of the errors manifests when adjusting the receive window, e.g. Unable to send transfer-window adjustment packet, deferring, while the SSH server reports something like sshd[29804]: fatal: channel 0: adjust 4294967295 overflows remote window 2097152

Code To Reproduce

#include <libssh2.h>

#include <arpa/inet.h>
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Use your own SSH auth setup
static const char *username = "<username>";

int main(int argc, char *argv[]) {
  uint32_t hostaddr = inet_addr("127.0.0.1");
  libssh2_socket_t sock;
  struct sockaddr_in sin;
  int rc;
  LIBSSH2_SESSION *session = NULL;
  LIBSSH2_CHANNEL *channel = NULL;
  LIBSSH2_AGENT *agent = NULL;
  struct libssh2_agent_publickey *identity = NULL;

  rc = libssh2_init(0);
  if(rc) {
    fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
    return 1;
  }
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if(sock == LIBSSH2_INVALID_SOCKET) {
    fprintf(stderr, "failed to create socket!\n");
    goto shutdown;
  }
  sin.sin_family = AF_INET;
  sin.sin_port = htons(22);
  sin.sin_addr.s_addr = hostaddr;
  if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
    fprintf(stderr, "failed to connect!\n");
    goto shutdown;
  }
  session = libssh2_session_init();
  if(!session) {
    fprintf(stderr, "Could not initialize SSH session!\n");
    goto shutdown;
  }
  libssh2_session_set_blocking(session, 1);
  rc = libssh2_session_handshake(session, sock);
  if(rc) {
    fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
    goto shutdown;
  }
  agent = libssh2_agent_init(session);
  if(!agent) {
    fprintf(stderr, "Failure initializing ssh-agent support\n");
    rc = 1;
    goto shutdown;
  }
  if(libssh2_agent_connect(agent)) {
    fprintf(stderr, "Failure connecting to ssh-agent\n");
    rc = 1;
    goto shutdown;
  }
  if(libssh2_agent_list_identities(agent)) {
    fprintf(stderr, "Failure requesting identities to ssh-agent\n");
    rc = 1;
    goto shutdown;
  }
  rc = libssh2_agent_get_identity(agent, &identity, NULL);
  if(rc) {
    fprintf(stderr, "Failure obtaining identity from ssh-agent support %d\n", rc);
    goto shutdown;
  }
  if(libssh2_agent_userauth(agent, username, identity)) {
    fprintf(stderr, "Authentication with username %s and "
        "public key %s failed!\n",
        username, identity->comment);
  }
  channel = libssh2_channel_open_session(session);
  if(!channel) {
    fprintf(stderr, "Error\n");
    goto shutdown;
  }
  FILE *file = fopen("/tmp/large_data", "w");
  if (!file) {
    fprintf(stderr, "file open error\n");
    goto shutdown;
  }
  char buf[1024 * 1024 /* 1 MB */];
  memset(buf, 'a', sizeof(buf));
  for (int i = 0; i < 4 * 1024 /* GB */; ++i) {
    if(fwrite(buf, sizeof(buf[0]), sizeof(buf), file) < sizeof(buf)) {
      fprintf(stderr, "file write error\n");
      fclose(file);
      goto shutdown;
    }
  }
  fclose(file);
  rc = libssh2_channel_exec(channel, "cat /tmp/large_data");
  if(rc) {
    fprintf(stderr, "exec error\n");
    goto shutdown;
  }
  // 4GB - 1byte reliably causes an error on my machine.
  // You can play with different sizes and see when it fails for you, or if incomplete data is read. 
  size_t buflen = (2l << 31) - 1;
  fprintf(stderr, "sizeof(size_t): %ld, buflen: %ld\n", sizeof(size_t), buflen);
  char *buffer = malloc(buflen);
  ssize_t nread = libssh2_channel_read(channel, buffer, buflen);
  fprintf(stderr, "libssh2_channel_read returned: %ld\n", nread);
  if (nread < 0) {
    char *errmsg = NULL;
    libssh2_session_last_error(session, &errmsg, NULL, 0);
    fprintf(stderr, "%s\n", errmsg);
  }
  free(buffer);
shutdown:
  if(agent) {
    libssh2_agent_disconnect(agent);
    libssh2_agent_free(agent);
  }
  if(session) {
    libssh2_session_disconnect(session, "Normal Shutdown");
    libssh2_session_free(session);
  }
  if(sock != LIBSSH2_INVALID_SOCKET) {
    shutdown(sock, 2);
    close(sock);
  }
  fprintf(stderr, "all done\n");
  libssh2_exit();
  return 0;
}

Expected behavior
libssh2 should handle u32 overflows gracefully

Version (please complete the following information):

  • OS and version: 5.15.0-75-generic # 82-Ubuntu SMP Tue Jun 6 23:10:23 UTC 2023 x86_64 GNU/Linux
  • libssh2 version: 1.11.0
  • crypto backend and version: OpenSSL 3.0.9
Ngôn ngữ chính
C
Star
1.6k
Fork
646
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

  • Không có Dockerfile hay tệp Docker Compose
  • Có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của libssh2/libssh2

Tất cả issue của libssh2/libssh2

Issue tương tự

Thêm issue về C

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.