Commit 26147eb4 authored by Pavol Žáčik's avatar Pavol Žáčik Committed by Jakub Jelen
Browse files

CVE-2026-59848 sftp: handle responses with unknown request IDs

This adds a new field to sftp_session_struct,
containing a list of outstanding request IDs.
An ID is added to the list when a request
is constructed and removed when the corresponding
request is received. If a client receives a response
with an unknown request ID, it reports an error.

Storing responses with unknown request IDs in
the response queue could be abused by a malicious
SFTP server which could deplete client memory
this way.

Signed-off-by: default avatarPavol Žáčik <pzacik@redhat.com>
Reviewed-by: default avatarJakub Jelen <jjelen@redhat.com>
parent 9aa69005
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ struct sftp_session_struct {
    sftp_ext ext;
    sftp_packet read_packet;
    sftp_limits_t limits;
    struct ssh_list *outstanding_ids;
};

struct sftp_packet_struct {
+10 −8
Original line number Diff line number Diff line
@@ -102,15 +102,17 @@ int sftp_recv_response_msg(sftp_session sftp,
                           bool blocking,
                           sftp_message *msg_ptr);

/*
 * Assigns a new SFTP ID for new requests and assures there is no collision
 * between them.
 * Returns a new ID ready to use in a request
/**
 * @brief Assigns a new SFTP ID for new requests and assures there is no
 *        collision between them.
 *
 * @param sftp           The sftp session handle.
 * @param id_out         Pointer to store the new ID.
 *
 * @returns SSH_OK on success with the new ID stored in *id
 * @returns SSH_ERROR on failure with the sftp and ssh errors set
 */
static inline uint32_t sftp_get_new_id(sftp_session session)
{
    return ++session->id_counter;
}
int sftp_get_new_id(sftp_session sftp, uint32_t *id_out);

sftp_status_message parse_status_msg(sftp_message msg);

+152 −51
Original line number Diff line number Diff line
@@ -149,6 +149,12 @@ sftp_session sftp_new(ssh_session session)
        goto error;
    }

    sftp->outstanding_ids = ssh_list_new();
    if (sftp->outstanding_ids == NULL) {
        ssh_set_error_oom(session);
        goto error;
    }

    /*
     * The following two calls shouldn't return SSH_AGAIN
     * as the code has validated above that the SSH session
@@ -172,6 +178,7 @@ error:
    if (sftp->channel != NULL) {
        ssh_channel_free(sftp->channel);
    }
    ssh_list_free(sftp->outstanding_ids);
    if (sftp->read_packet != NULL) {
        if (sftp->read_packet->payload != NULL) {
            SSH_BUFFER_FREE(sftp->read_packet->payload);
@@ -203,6 +210,12 @@ sftp_new_channel(ssh_session session, ssh_channel channel)
        goto error;
    }

    sftp->outstanding_ids = ssh_list_new();
    if (sftp->outstanding_ids == NULL) {
        ssh_set_error_oom(session);
        goto error;
    }

    sftp->read_packet = calloc(1, sizeof(struct sftp_packet_struct));
    if (sftp->read_packet == NULL) {
        ssh_set_error_oom(session);
@@ -224,6 +237,7 @@ error:
    if (sftp->ext != NULL) {
        sftp_ext_free(sftp->ext);
    }
    ssh_list_free(sftp->outstanding_ids);
    if (sftp->read_packet != NULL) {
        if (sftp->read_packet->payload != NULL) {
            SSH_BUFFER_FREE(sftp->read_packet->payload);
@@ -338,6 +352,7 @@ void sftp_server_free(sftp_session sftp)
void sftp_free(sftp_session sftp)
{
    sftp_request_queue ptr;
    struct ssh_iterator *id_it = NULL;

    if (sftp == NULL) {
        return;
@@ -364,6 +379,12 @@ void sftp_free(sftp_session sftp)
    sftp_ext_free(sftp->ext);
    sftp_limits_free(sftp->limits);

    id_it = ssh_list_get_iterator(sftp->outstanding_ids);
    for (; id_it != NULL; id_it = id_it->next) {
        free((uint32_t *)id_it->data);
    }
    ssh_list_free(sftp->outstanding_ids);

    SAFE_FREE(sftp);
}

@@ -703,6 +724,11 @@ sftp_dir sftp_opendir(sftp_session sftp, const char *path)
        return NULL;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    payload = ssh_buffer_new();
    if (payload == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -710,8 +736,6 @@ sftp_dir sftp_opendir(sftp_session sftp, const char *path)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(payload,
                         "ds",
                         id,
@@ -795,6 +819,11 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir)
    int rc;

    if (dir->buffer == NULL) {
        rc = sftp_get_new_id(sftp, &id);
        if (rc != SSH_OK) {
            return NULL;
        }

        payload = ssh_buffer_new();
        if (payload == NULL) {
            ssh_set_error_oom(sftp->session);
@@ -802,8 +831,6 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir)
            return NULL;
        }

        id = sftp_get_new_id(sftp);

        rc = ssh_buffer_pack(payload,
                             "dS",
                             id,
@@ -925,6 +952,11 @@ static int sftp_handle_close(sftp_session sftp, ssh_string handle)
    uint32_t id;
    int rc;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -932,8 +964,6 @@ static int sftp_handle_close(sftp_session sftp, ssh_string handle)
        return -1;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dS",
                         id,
@@ -1037,6 +1067,11 @@ sftp_file sftp_open(sftp_session sftp,
    uint32_t id;
    int rc;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -1065,7 +1100,6 @@ sftp_file sftp_open(sftp_session sftp,
    }
    SSH_LOG(SSH_LOG_PACKET, "Opening file %s with sftp flags %" PRIx32,
            file, sftp_flags);
    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dsd",
@@ -1191,14 +1225,17 @@ sftp_read(sftp_file handle, void *buf, size_t count)
     */
    read_len = (uint32_t)MIN(sftp->limits->max_read_length, count);

    rc = sftp_get_new_id(handle->sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
        return -1;
    }

    id = sftp_get_new_id(handle->sftp);

    rc = ssh_buffer_pack(buffer,
                         "dSqd",
                         id,
@@ -1299,6 +1336,11 @@ sftp_async_read_begin(sftp_file file, uint32_t len)
    uint32_t id;
    int rc;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -1306,8 +1348,6 @@ sftp_async_read_begin(sftp_file file, uint32_t len)
        return -1;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer, "dSqd", id, file->handle, file->offset, len);
    if (rc != SSH_OK) {
        ssh_set_error_oom(sftp->session);
@@ -1426,6 +1466,11 @@ sftp_write(sftp_file file, const void *buf, size_t count)
    }
    sftp = file->sftp;

    rc = sftp_get_new_id(file->sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -1433,8 +1478,6 @@ sftp_write(sftp_file file, const void *buf, size_t count)
        return -1;
    }

    id = sftp_get_new_id(file->sftp);

    /*
     * limit the writes to the maximum specified in Section 3 of
     * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02
@@ -1563,6 +1606,11 @@ int sftp_unlink(sftp_session sftp, const char *file) {
  uint32_t id;
  int rc;

  rc = sftp_get_new_id(sftp, &id);
  if (rc != SSH_OK) {
    return -1;
  }

  buffer = ssh_buffer_new();
  if (buffer == NULL) {
    ssh_set_error_oom(sftp->session);
@@ -1570,8 +1618,6 @@ int sftp_unlink(sftp_session sftp, const char *file) {
    return -1;
  }

  id = sftp_get_new_id(sftp);

  rc = ssh_buffer_pack(buffer,
                       "ds",
                       id,
@@ -1636,6 +1682,11 @@ int sftp_rmdir(sftp_session sftp, const char *directory) {
  uint32_t id;
  int rc;

  rc = sftp_get_new_id(sftp, &id);
  if (rc != SSH_OK) {
    return -1;
  }

  buffer = ssh_buffer_new();
  if (buffer == NULL) {
    ssh_set_error_oom(sftp->session);
@@ -1643,8 +1694,6 @@ int sftp_rmdir(sftp_session sftp, const char *directory) {
    return -1;
  }

  id = sftp_get_new_id(sftp);

  rc = ssh_buffer_pack(buffer,
                       "ds",
                       id,
@@ -1707,6 +1756,11 @@ int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode)
    uint32_t id;
    int rc;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -1718,8 +1772,6 @@ int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode)
    attr.permissions = mode;
    attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS;

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "ds",
                         id,
@@ -1807,6 +1859,11 @@ int sftp_rename(sftp_session sftp, const char *original, const char *newname)
    int request_type;
    int rc;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -1814,8 +1871,6 @@ int sftp_rename(sftp_session sftp, const char *original, const char *newname)
        return -1;
    }

    id = sftp_get_new_id(sftp);

    /*
     * posix-rename@openssh.com extension will be used
     * if it is supported by sftp
@@ -1920,6 +1975,11 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
        return -1;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -1927,8 +1987,6 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
        return -1;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "ds",
                         id,
@@ -2006,6 +2064,11 @@ sftp_lsetstat(sftp_session sftp, const char *file, sftp_attributes attr)
        return -1;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2013,8 +2076,6 @@ sftp_lsetstat(sftp_session sftp, const char *file, sftp_attributes attr)
        return -1;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer, "dss", id, extension_name, file);
    if (rc != SSH_OK) {
        ssh_set_error_oom(sftp->session);
@@ -2136,6 +2197,11 @@ int sftp_symlink(sftp_session sftp, const char *target, const char *dest)
    return -1;
  }

  rc = sftp_get_new_id(sftp, &id);
  if (rc != SSH_OK) {
    return -1;
  }

  buffer = ssh_buffer_new();
  if (buffer == NULL) {
    ssh_set_error_oom(sftp->session);
@@ -2143,8 +2209,6 @@ int sftp_symlink(sftp_session sftp, const char *target, const char *dest)
    return -1;
  }

  id = sftp_get_new_id(sftp);

  /* The OpenSSH sftp server has order of the arguments reversed, see the
   * section "4.1 sftp: Reversal of arguments to SSH_FXP_SYMLINK' in
   * https://github.com/openssh/openssh-portable/blob/master/PROTOCOL
@@ -2235,6 +2299,12 @@ char *sftp_readlink(sftp_session sftp, const char *path)
        sftp_set_error(sftp, SSH_FX_FAILURE);
        return NULL;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2242,8 +2312,6 @@ char *sftp_readlink(sftp_session sftp, const char *path)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "ds",
                         id,
@@ -2323,6 +2391,11 @@ int sftp_hardlink(sftp_session sftp, const char *oldpath, const char *newpath)
        return -1;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2330,8 +2403,6 @@ int sftp_hardlink(sftp_session sftp, const char *oldpath, const char *newpath)
        return -1;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dsss",
                         id,
@@ -2445,6 +2516,11 @@ sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path)
        return NULL;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2452,8 +2528,6 @@ sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dss",
                         id,
@@ -2518,6 +2592,11 @@ int sftp_fsync(sftp_file file)
    }
    sftp = file->sftp;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2525,8 +2604,6 @@ int sftp_fsync(sftp_file file)
        return -1;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dsS",
                         id,
@@ -2613,6 +2690,11 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file)
    }
    sftp = file->sftp;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2620,8 +2702,6 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dsS",
                         id,
@@ -2730,6 +2810,11 @@ static sftp_limits_t sftp_limits_use_extension(sftp_session sftp)
    if (sftp == NULL)
        return NULL;

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2737,8 +2822,6 @@ static sftp_limits_t sftp_limits_use_extension(sftp_session sftp)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "ds",
                         id,
@@ -2878,6 +2961,11 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path)
        return NULL;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2885,8 +2973,6 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "ds",
                         id,
@@ -2967,6 +3053,11 @@ static sftp_attributes sftp_xstat(sftp_session sftp,
        return NULL;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -2974,8 +3065,6 @@ static sftp_attributes sftp_xstat(sftp_session sftp,
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "ds",
                         id,
@@ -3043,6 +3132,11 @@ sftp_attributes sftp_fstat(sftp_file file)
        return NULL;
    }

    rc = sftp_get_new_id(file->sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(file->sftp->session);
@@ -3050,8 +3144,6 @@ sftp_attributes sftp_fstat(sftp_file file)
        return NULL;
    }

    id = sftp_get_new_id(file->sftp);

    rc = ssh_buffer_pack(buffer,
                         "dS",
                         id,
@@ -3120,6 +3212,11 @@ char *sftp_expand_path(sftp_session sftp, const char *path)
        return NULL;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -3127,8 +3224,6 @@ char *sftp_expand_path(sftp_session sftp, const char *path)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dss",
                         id,
@@ -3204,6 +3299,11 @@ sftp_home_directory(sftp_session sftp, const char *username)
        return NULL;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return NULL;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -3211,8 +3311,6 @@ sftp_home_directory(sftp_session sftp, const char *username)
        return NULL;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dss",
                         id,
@@ -3432,6 +3530,11 @@ int sftp_get_users_groups_by_id(sftp_session sftp,
        return -1;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return -1;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -3439,8 +3542,6 @@ int sftp_get_users_groups_by_id(sftp_session sftp,
        return -1;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer, "ds", id, "users-groups-by-id@openssh.com");
    if (rc != SSH_OK) {
        ssh_set_error_oom(sftp->session);
+10 −3
Original line number Diff line number Diff line
@@ -88,6 +88,11 @@ ssize_t sftp_aio_begin_read(sftp_file file, size_t len, sftp_aio *aio)
        return SSH_ERROR;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return SSH_ERROR;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -95,8 +100,6 @@ ssize_t sftp_aio_begin_read(sftp_file file, size_t len, sftp_aio *aio)
        return SSH_ERROR;
    }

    id = sftp_get_new_id(sftp);

    rc = ssh_buffer_pack(buffer,
                         "dSqd",
                         id,
@@ -352,6 +355,11 @@ ssize_t sftp_aio_begin_write(sftp_file file,
        return SSH_ERROR;
    }

    rc = sftp_get_new_id(sftp, &id);
    if (rc != SSH_OK) {
        return SSH_ERROR;
    }

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        ssh_set_error_oom(sftp->session);
@@ -359,7 +367,6 @@ ssize_t sftp_aio_begin_write(sftp_file file,
        return SSH_ERROR;
    }

    id = sftp_get_new_id(sftp);
    rc = ssh_buffer_pack(buffer,
                         "dSqdP",
                         id,
+56 −0
Original line number Diff line number Diff line
@@ -795,6 +795,8 @@ static sftp_message sftp_get_message(sftp_packet packet)
{
    sftp_session sftp = packet->sftp;
    sftp_message msg = NULL;
    struct ssh_iterator *id_it = NULL;
    bool id_found = false;
    int rc;

    switch (packet->type) {
@@ -842,9 +844,63 @@ static sftp_message sftp_get_message(sftp_packet packet)
            msg->id,
            msg->packet_type);

    /* Validate that this ID is in our outstanding requests list */
    id_it = ssh_list_get_iterator(sftp->outstanding_ids);
    for (; id_it != NULL; id_it = id_it->next) {
        uint32_t *stored_id = (uint32_t *)id_it->data;
        if (*stored_id == msg->id) {
            id_found = true;
            ssh_list_remove(sftp->outstanding_ids, id_it);
            free(stored_id);
            break;
        }
    }

    if (!id_found) {
        ssh_set_error(packet->sftp->session,
                      SSH_FATAL,
                      "Unknown request ID %" PRIu32,
                      msg->id);
        sftp_message_free(msg);
        sftp_set_error(packet->sftp, SSH_FX_FAILURE);
        return NULL;
    }

    return msg;
}

int sftp_get_new_id(sftp_session sftp, uint32_t *id_out)
{
    uint32_t *id = NULL;
    int rc;

    if (id_out == NULL) {
        ssh_set_error_invalid(sftp->session);
        sftp_set_error(sftp, SSH_FX_FAILURE);
        return SSH_ERROR;
    }

    id = malloc(sizeof(uint32_t));
    if (id == NULL) {
        ssh_set_error_oom(sftp->session);
        sftp_set_error(sftp, SSH_FX_FAILURE);
        return SSH_ERROR;
    }

    *id = ++sftp->id_counter;
    rc = ssh_list_append(sftp->outstanding_ids, id);
    if (rc != SSH_OK) {
        free(id);
        ssh_set_error_oom(sftp->session);
        sftp_set_error(sftp, SSH_FX_FAILURE);
        return SSH_ERROR;
    }

    *id_out = *id;

    return SSH_OK;
}

int sftp_read_and_dispatch(sftp_session sftp)
{
    sftp_packet packet = NULL;
Loading