Blame tests/unittests/torture_threads_buffer.c

Packit Service 31306d
/*
Packit Service 31306d
 * This file is part of the SSH Library
Packit Service 31306d
 *
Packit Service 31306d
 * Copyright (c) 2018 by Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Packit Service 31306d
 *
Packit Service 31306d
 * The SSH Library is free software; you can redistribute it and/or modify
Packit Service 31306d
 * it under the terms of the GNU Lesser General Public License as published by
Packit Service 31306d
 * the Free Software Foundation; either version 2.1 of the License, or (at your
Packit Service 31306d
 * option) any later version.
Packit Service 31306d
 *
Packit Service 31306d
 * The SSH Library is distributed in the hope that it will be useful, but
Packit Service 31306d
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit Service 31306d
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
Packit Service 31306d
 * License for more details.
Packit Service 31306d
 *
Packit Service 31306d
 * You should have received a copy of the GNU Lesser General Public License
Packit Service 31306d
 * along with the SSH Library; see the file COPYING.  If not, write to
Packit Service 31306d
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
Packit Service 31306d
 * MA 02111-1307, USA.
Packit Service 31306d
 */
Packit Service 31306d
Packit Service 31306d
#include "config.h"
Packit Service 31306d
Packit Service 31306d
#define LIBSSH_STATIC
Packit Service 31306d
Packit Service 31306d
#include "torture.h"
Packit Service 31306d
#define DEBUG_BUFFER
Packit Service 31306d
#include "buffer.c"
Packit Service 31306d
Packit Service 31306d
#include <pthread.h>
Packit Service 31306d
Packit Service 31306d
#define NUM_THREADS 20
Packit Service 31306d
Packit Service 31306d
#define BUFFER_LIMIT (8 * 1024 * 1024)
Packit Service 31306d
Packit Service 31306d
static int run_on_threads(void *(*func)(void *))
Packit Service 31306d
{
Packit Service 31306d
    pthread_t threads[NUM_THREADS];
Packit Service 31306d
    int rc;
Packit Service 31306d
    int i;
Packit Service 31306d
Packit Service 31306d
    for (i = 0; i < NUM_THREADS; ++i) {
Packit Service 31306d
        rc = pthread_create(&threads[i], NULL, func, NULL);
Packit Service 31306d
        assert_int_equal(rc, 0);
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    for (i = 0; i < NUM_THREADS; ++i) {
Packit Service 31306d
        void *p = NULL;
Packit Service 31306d
        uint64_t *result = NULL;
Packit Service 31306d
Packit Service 31306d
        rc = pthread_join(threads[i], &p);
Packit Service 31306d
        assert_int_equal(rc, 0);
Packit Service 31306d
Packit Service 31306d
        result = (uint64_t *)p;
Packit Service 31306d
        assert_null(result);
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    return rc;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/*
Packit Service 31306d
 * Test if the continuously growing buffer size never exceeds 2 time its
Packit Service 31306d
 * real capacity
Packit Service 31306d
 */
Packit Service 31306d
static void *thread_growing_buffer(void *threadid)
Packit Service 31306d
{
Packit Service 31306d
    ssh_buffer buffer = NULL;
Packit Service 31306d
    int i;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) threadid;
Packit Service 31306d
Packit Service 31306d
    /* Setup */
Packit Service 31306d
    buffer = ssh_buffer_new();
Packit Service 31306d
    if (buffer == NULL) {
Packit Service 31306d
        pthread_exit((void *)-1);
Packit Service 31306d
    }
Packit Service 31306d
    ssh_buffer_set_secure(buffer);
Packit Service 31306d
Packit Service 31306d
    for (i = 0; i < BUFFER_LIMIT; ++i) {
Packit Service 31306d
        ssh_buffer_add_data(buffer,"A",1);
Packit Service 31306d
        if (buffer->used >= 128) {
Packit Service 31306d
            if (ssh_buffer_get_len(buffer) * 2 < buffer->allocated) {
Packit Service 31306d
                assert_true(ssh_buffer_get_len(buffer) * 2 >= buffer->allocated);
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    /* Teardown */
Packit Service 31306d
    SSH_BUFFER_FREE(buffer);
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_growing_buffer(void **state)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_growing_buffer);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/*
Packit Service 31306d
 * Test if the continuously growing buffer size never exceeds 2 time its
Packit Service 31306d
 * real capacity, when we remove 1 byte after each call (sliding window)
Packit Service 31306d
 */
Packit Service 31306d
static void *thread_growing_buffer_shifting(void *threadid)
Packit Service 31306d
{
Packit Service 31306d
    ssh_buffer buffer;
Packit Service 31306d
    int i;
Packit Service 31306d
    unsigned char c;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) threadid;
Packit Service 31306d
Packit Service 31306d
    /* Setup */
Packit Service 31306d
    buffer = ssh_buffer_new();
Packit Service 31306d
    if (buffer == NULL) {
Packit Service 31306d
        pthread_exit((void *)-1);
Packit Service 31306d
    }
Packit Service 31306d
    ssh_buffer_set_secure(buffer);
Packit Service 31306d
Packit Service 31306d
Packit Service 31306d
    for (i = 0; i < 1024; ++i) {
Packit Service 31306d
        ssh_buffer_add_data(buffer,"S",1);
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    for (i = 0; i < BUFFER_LIMIT; ++i) {
Packit Service 31306d
        ssh_buffer_get_u8(buffer,&c);
Packit Service 31306d
        ssh_buffer_add_data(buffer,"A",1);
Packit Service 31306d
        if (buffer->used >= 128) {
Packit Service 31306d
            if (ssh_buffer_get_len(buffer) * 4 < buffer->allocated) {
Packit Service 31306d
                assert_true(ssh_buffer_get_len(buffer) * 4 >= buffer->allocated);
Packit Service 31306d
                /* Teardown */
Packit Service 31306d
                SSH_BUFFER_FREE(buffer);
Packit Service 31306d
                pthread_exit(NULL);
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    /* Teardown */
Packit Service 31306d
    SSH_BUFFER_FREE(buffer);
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_growing_buffer_shifting(void **state)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_growing_buffer_shifting);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/*
Packit Service 31306d
 * Test the behavior of ssh_buffer_prepend_data
Packit Service 31306d
 */
Packit Service 31306d
static void *thread_buffer_prepend(void *threadid)
Packit Service 31306d
{
Packit Service 31306d
    ssh_buffer buffer = NULL;
Packit Service 31306d
    uint32_t v;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) threadid;
Packit Service 31306d
Packit Service 31306d
    /* Setup */
Packit Service 31306d
    buffer = ssh_buffer_new();
Packit Service 31306d
    if (buffer == NULL) {
Packit Service 31306d
        pthread_exit((void *)-1);
Packit Service 31306d
    }
Packit Service 31306d
    ssh_buffer_set_secure(buffer);
Packit Service 31306d
Packit Service 31306d
    ssh_buffer_add_data(buffer, "abcdef", 6);
Packit Service 31306d
    ssh_buffer_prepend_data(buffer, "xyz", 3);
Packit Service 31306d
    assert_int_equal(ssh_buffer_get_len(buffer), 9);
Packit Service 31306d
    assert_memory_equal(ssh_buffer_get(buffer),  "xyzabcdef", 9);
Packit Service 31306d
Packit Service 31306d
    /* Now remove 4 bytes and see if we can replace them */
Packit Service 31306d
    ssh_buffer_get_u32(buffer, &v);
Packit Service 31306d
    assert_int_equal(ssh_buffer_get_len(buffer), 5);
Packit Service 31306d
    assert_memory_equal(ssh_buffer_get(buffer), "bcdef", 5);
Packit Service 31306d
Packit Service 31306d
    ssh_buffer_prepend_data(buffer, "aris", 4);
Packit Service 31306d
    assert_int_equal(ssh_buffer_get_len(buffer), 9);
Packit Service 31306d
    assert_memory_equal(ssh_buffer_get(buffer), "arisbcdef", 9);
Packit Service 31306d
Packit Service 31306d
    /* same thing but we add 5 bytes now */
Packit Service 31306d
    ssh_buffer_get_u32(buffer, &v);
Packit Service 31306d
    assert_int_equal(ssh_buffer_get_len(buffer), 5);
Packit Service 31306d
    assert_memory_equal(ssh_buffer_get(buffer), "bcdef", 5);
Packit Service 31306d
Packit Service 31306d
    ssh_buffer_prepend_data(buffer, "12345", 5);
Packit Service 31306d
    assert_int_equal(ssh_buffer_get_len(buffer), 10);
Packit Service 31306d
    assert_memory_equal(ssh_buffer_get(buffer), "12345bcdef", 10);
Packit Service 31306d
Packit Service 31306d
    /* Teardown */
Packit Service 31306d
    SSH_BUFFER_FREE(buffer);
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_buffer_prepend(void **state)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_buffer_prepend);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/*
Packit Service 31306d
 * Test the behavior of ssh_buffer_get_ssh_string with invalid data
Packit Service 31306d
 */
Packit Service 31306d
static void *thread_ssh_buffer_get_ssh_string(void *threadid)
Packit Service 31306d
{
Packit Service 31306d
    ssh_buffer buffer = NULL;
Packit Service 31306d
    size_t i, j, k, l;
Packit Service 31306d
    int rc;
Packit Service 31306d
    /* some values that can go wrong */
Packit Service 31306d
    uint32_t values[] = {
Packit Service 31306d
        0xffffffff, 0xfffffffe, 0xfffffffc, 0xffffff00,
Packit Service 31306d
        0x80000000, 0x80000004, 0x7fffffff};
Packit Service 31306d
    char data[128] = {0};
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void)threadid;
Packit Service 31306d
Packit Service 31306d
    memset(data, 'X', sizeof(data));
Packit Service 31306d
Packit Service 31306d
    for (i = 0; i < ARRAY_SIZE(values); ++i) {
Packit Service 31306d
        for (j = 0; j < (int)sizeof(data); ++j) {
Packit Service 31306d
            for (k = 1; k < 5; ++k) {
Packit Service 31306d
                buffer = ssh_buffer_new();
Packit Service 31306d
                assert_non_null(buffer);
Packit Service 31306d
Packit Service 31306d
                for (l = 0; l < k; ++l) {
Packit Service 31306d
                    rc = ssh_buffer_add_u32(buffer, htonl(values[i]));
Packit Service 31306d
                    assert_int_equal(rc, 0);
Packit Service 31306d
                }
Packit Service 31306d
                rc = ssh_buffer_add_data(buffer,data,j);
Packit Service 31306d
                assert_int_equal(rc, 0);
Packit Service 31306d
                for (l = 0; l < k; ++l) {
Packit Service 31306d
                    ssh_string str = ssh_buffer_get_ssh_string(buffer);
Packit Service 31306d
                    assert_null(str);
Packit Service 31306d
                    SSH_STRING_FREE(str);
Packit Service 31306d
                }
Packit Service 31306d
                SSH_BUFFER_FREE(buffer);
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_ssh_buffer_get_ssh_string(void **state){
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_ssh_buffer_get_ssh_string);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void *thread_ssh_buffer_add_format(void *threadid)
Packit Service 31306d
{
Packit Service 31306d
    ssh_buffer buffer = NULL;
Packit Service 31306d
    uint8_t b;
Packit Service 31306d
    uint16_t w;
Packit Service 31306d
    uint32_t d;
Packit Service 31306d
    uint64_t q;
Packit Service 31306d
    ssh_string s = NULL;
Packit Service 31306d
    int rc;
Packit Service 31306d
    size_t len;
Packit Service 31306d
    uint8_t verif[] = "\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46"
Packit Service 31306d
        "\xac\xbd\xce\xdf"
Packit Service 31306d
        "\x00\x00\x00\x06" "libssh"
Packit Service 31306d
        "\x00\x00\x00\x05" "rocks"
Packit Service 31306d
        "So much"
Packit Service 31306d
        "Fun!";
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) threadid;
Packit Service 31306d
Packit Service 31306d
    /* Setup */
Packit Service 31306d
    buffer = ssh_buffer_new();
Packit Service 31306d
    if (buffer == NULL) {
Packit Service 31306d
        pthread_exit((void *)-1);
Packit Service 31306d
    }
Packit Service 31306d
    ssh_buffer_set_secure(buffer);
Packit Service 31306d
Packit Service 31306d
    b = 0x42;
Packit Service 31306d
    w = 0x1337;
Packit Service 31306d
    d = 0xbadc0de;
Packit Service 31306d
    q = 0x13243546acbdcedf;
Packit Service 31306d
    s = ssh_string_from_char("libssh");
Packit Service 31306d
    rc = ssh_buffer_pack(buffer,
Packit Service 31306d
                         "bwdqSsPt",
Packit Service 31306d
                         b,
Packit Service 31306d
                         w,
Packit Service 31306d
                         d,
Packit Service 31306d
                         q,
Packit Service 31306d
                         s,
Packit Service 31306d
                         "rocks",
Packit Service 31306d
                         7,
Packit Service 31306d
                         "So much",
Packit Service 31306d
                         "Fun!");
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    len = ssh_buffer_get_len(buffer);
Packit Service 31306d
    assert_int_equal(len, sizeof(verif) - 1);
Packit Service 31306d
    assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1);
Packit Service 31306d
Packit Service 31306d
    SSH_STRING_FREE(s);
Packit Service 31306d
Packit Service 31306d
    /* Teardown */
Packit Service 31306d
    SSH_BUFFER_FREE(buffer);
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_ssh_buffer_add_format(void **state){
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_ssh_buffer_add_format);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void *thread_ssh_buffer_get_format(void *threadid) {
Packit Service 31306d
    ssh_buffer buffer;
Packit Service 31306d
    uint8_t b = 0;
Packit Service 31306d
    uint16_t w = 0;
Packit Service 31306d
    uint32_t d = 0;
Packit Service 31306d
    uint64_t q = 0;
Packit Service 31306d
    ssh_string s = NULL;
Packit Service 31306d
    char *s1 = NULL, *s2 = NULL;
Packit Service 31306d
    int rc;
Packit Service 31306d
    size_t len;
Packit Service 31306d
    uint8_t verif[] = "\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46"
Packit Service 31306d
        "\xac\xbd\xce\xdf"
Packit Service 31306d
        "\x00\x00\x00\x06" "libssh"
Packit Service 31306d
        "\x00\x00\x00\x05" "rocks"
Packit Service 31306d
        "So much";
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) threadid;
Packit Service 31306d
Packit Service 31306d
    /* Setup */
Packit Service 31306d
    buffer = ssh_buffer_new();
Packit Service 31306d
    if (buffer == NULL) {
Packit Service 31306d
        pthread_exit((void *)-1);
Packit Service 31306d
    }
Packit Service 31306d
    ssh_buffer_set_secure(buffer);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_buffer_add_data(buffer, verif, sizeof(verif) - 1);
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_buffer_unpack(buffer,
Packit Service 31306d
                           "bwdqSsP",
Packit Service 31306d
                           &b,
Packit Service 31306d
                           &w,
Packit Service 31306d
                           &d,
Packit Service 31306d
                           &q,
Packit Service 31306d
                           &s,
Packit Service 31306d
                           &s1,
Packit Service 31306d
                           (size_t)7,
Packit Service 31306d
                           &s2;;
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    assert_int_equal(b, 0x42);
Packit Service 31306d
    assert_int_equal(w, 0x1337);
Packit Service 31306d
Packit Service 31306d
    assert_true(d == 0xbadc0de);
Packit Service 31306d
    assert_true(q == 0x13243546acbdcedf);
Packit Service 31306d
Packit Service 31306d
    assert_non_null(s);
Packit Service 31306d
    assert_int_equal(ssh_string_len(s), 6);
Packit Service 31306d
    assert_memory_equal(ssh_string_data(s), "libssh", 6);
Packit Service 31306d
Packit Service 31306d
    assert_non_null(s1);
Packit Service 31306d
    assert_string_equal(s1, "rocks");
Packit Service 31306d
Packit Service 31306d
    assert_non_null(s2);
Packit Service 31306d
    assert_memory_equal(s2, "So much", 7);
Packit Service 31306d
Packit Service 31306d
    len = ssh_buffer_get_len(buffer);
Packit Service 31306d
    assert_int_equal(len, 0);
Packit Service 31306d
    SAFE_FREE(s);
Packit Service 31306d
    SAFE_FREE(s1);
Packit Service 31306d
    SAFE_FREE(s2);
Packit Service 31306d
Packit Service 31306d
    /* Teardown */
Packit Service 31306d
    SSH_BUFFER_FREE(buffer);
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_ssh_buffer_get_format(void **state)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_ssh_buffer_get_format);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void *thread_ssh_buffer_get_format_error(void *threadid)
Packit Service 31306d
{
Packit Service 31306d
    ssh_buffer buffer = NULL;
Packit Service 31306d
    uint8_t b = 0;
Packit Service 31306d
    uint16_t w = 0;
Packit Service 31306d
    uint32_t d = 0;
Packit Service 31306d
    uint64_t q = 0;
Packit Service 31306d
    ssh_string s = NULL;
Packit Service 31306d
    char *s1 = NULL, *s2 = NULL;
Packit Service 31306d
    int rc;
Packit Service 31306d
    uint8_t verif[] = "\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46"
Packit Service 31306d
        "\xac\xbd\xce\xdf"
Packit Service 31306d
        "\x00\x00\x00\x06" "libssh"
Packit Service 31306d
        "\x00\x00\x00\x05" "rocks"
Packit Service 31306d
        "So much";
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) threadid;
Packit Service 31306d
Packit Service 31306d
    /* Setup */
Packit Service 31306d
    buffer = ssh_buffer_new();
Packit Service 31306d
    if (buffer == NULL) {
Packit Service 31306d
        pthread_exit((void *)-1);
Packit Service 31306d
    }
Packit Service 31306d
    ssh_buffer_set_secure(buffer);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_buffer_add_data(buffer, verif, sizeof(verif) - 1);
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
    rc = ssh_buffer_unpack(buffer,
Packit Service 31306d
                           "bwdqSsPb",
Packit Service 31306d
                           &b,
Packit Service 31306d
                           &w,
Packit Service 31306d
                           &d,
Packit Service 31306d
                           &q,
Packit Service 31306d
                           &s,
Packit Service 31306d
                           &s1,
Packit Service 31306d
                           (size_t)7,
Packit Service 31306d
                           &s2,
Packit Service 31306d
                           &b);
Packit Service 31306d
    assert_int_equal(rc, SSH_ERROR);
Packit Service 31306d
Packit Service 31306d
    assert_null(s);
Packit Service 31306d
    assert_null(s1);
Packit Service 31306d
    assert_null(s2);
Packit Service 31306d
Packit Service 31306d
    /* Teardown */
Packit Service 31306d
    SSH_BUFFER_FREE(buffer);
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_ssh_buffer_get_format_error(void **state)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_ssh_buffer_get_format_error);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void *thread_buffer_pack_badformat(void *threadid)
Packit Service 31306d
{
Packit Service 31306d
    ssh_buffer buffer = NULL;
Packit Service 31306d
    uint8_t b = 42;
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) threadid;
Packit Service 31306d
Packit Service 31306d
    /* Setup */
Packit Service 31306d
    buffer = ssh_buffer_new();
Packit Service 31306d
    if (buffer == NULL) {
Packit Service 31306d
        pthread_exit((void *)-1);
Packit Service 31306d
    }
Packit Service 31306d
    ssh_buffer_set_secure(buffer);
Packit Service 31306d
Packit Service 31306d
    /* first with missing format */
Packit Service 31306d
    rc = ssh_buffer_pack(buffer, "b", b, b);
Packit Service 31306d
    assert_int_equal(rc, SSH_ERROR);
Packit Service 31306d
    ssh_buffer_reinit(buffer);
Packit Service 31306d
Packit Service 31306d
    /* with additional format */
Packit Service 31306d
    rc = ssh_buffer_pack(buffer, "bb", b);
Packit Service 31306d
    /* check that we detect the missing parameter */
Packit Service 31306d
    assert_int_equal(rc, SSH_ERROR);
Packit Service 31306d
Packit Service 31306d
    /* unpack with missing format */
Packit Service 31306d
    ssh_buffer_reinit(buffer);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_buffer_pack(buffer, "bb", 42, 43);
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_buffer_unpack(buffer, "b", &b, &b);
Packit Service 31306d
    assert_int_equal(rc, SSH_ERROR);
Packit Service 31306d
Packit Service 31306d
    /* not doing the test with additional format as
Packit Service 31306d
     * it could crash the process */
Packit Service 31306d
Packit Service 31306d
    /* Teardown */
Packit Service 31306d
    SSH_BUFFER_FREE(buffer);
Packit Service 31306d
    pthread_exit(NULL);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void torture_buffer_pack_badformat(void **state)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Unused */
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    rc = run_on_threads(thread_buffer_pack_badformat);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
#define NUM_TESTS 8
Packit Service 31306d
Packit Service 31306d
static void torture_mixed(void **state)
Packit Service 31306d
{
Packit Service 31306d
    pthread_t threads[NUM_TESTS][NUM_THREADS];
Packit Service 31306d
    int i;
Packit Service 31306d
    int f;
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    /* Array of functions to run on threads */
Packit Service 31306d
    static void *(*funcs[NUM_TESTS])(void *) = {
Packit Service 31306d
        thread_growing_buffer,
Packit Service 31306d
        thread_growing_buffer_shifting,
Packit Service 31306d
        thread_buffer_prepend,
Packit Service 31306d
        thread_ssh_buffer_get_ssh_string,
Packit Service 31306d
        thread_ssh_buffer_add_format,
Packit Service 31306d
        thread_ssh_buffer_get_format,
Packit Service 31306d
        thread_ssh_buffer_get_format_error,
Packit Service 31306d
        thread_buffer_pack_badformat
Packit Service 31306d
    };
Packit Service 31306d
Packit Service 31306d
    (void) state;
Packit Service 31306d
Packit Service 31306d
    /* Call tests in a round-robin fashion */
Packit Service 31306d
    for (i = 0; i < NUM_THREADS; ++i) {
Packit Service 31306d
        for (f = 0; f < NUM_TESTS; f++) {
Packit Service 31306d
            rc = pthread_create(&threads[f][i], NULL, funcs[f], NULL);
Packit Service 31306d
            assert_int_equal(rc, 0);
Packit Service 31306d
        }
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    for (f = 0; f < NUM_TESTS; f++) {
Packit Service 31306d
        for (i = 0; i < NUM_THREADS; ++i) {
Packit Service 31306d
            void *p = NULL;
Packit Service 31306d
            uint64_t *result = NULL;
Packit Service 31306d
Packit Service 31306d
            rc = pthread_join(threads[f][i], &p);
Packit Service 31306d
            assert_int_equal(rc, 0);
Packit Service 31306d
Packit Service 31306d
            result = (uint64_t *)p;
Packit Service 31306d
            assert_null(result);
Packit Service 31306d
        }
Packit Service 31306d
    }
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
int torture_run_tests(void)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
    struct CMUnitTest tests[] = {
Packit Service 31306d
        cmocka_unit_test(torture_growing_buffer),
Packit Service 31306d
        cmocka_unit_test(torture_growing_buffer_shifting),
Packit Service 31306d
        cmocka_unit_test(torture_buffer_prepend),
Packit Service 31306d
        cmocka_unit_test(torture_ssh_buffer_get_ssh_string),
Packit Service 31306d
        cmocka_unit_test(torture_ssh_buffer_add_format),
Packit Service 31306d
        cmocka_unit_test(torture_ssh_buffer_get_format),
Packit Service 31306d
        cmocka_unit_test(torture_ssh_buffer_get_format_error),
Packit Service 31306d
        cmocka_unit_test(torture_buffer_pack_badformat),
Packit Service 31306d
        cmocka_unit_test(torture_mixed),
Packit Service 31306d
    };
Packit Service 31306d
Packit Service 31306d
    /*
Packit Service 31306d
     * If the library is statically linked, ssh_init() is not called
Packit Service 31306d
     * automatically
Packit Service 31306d
     */
Packit Service 31306d
    ssh_init();
Packit Service 31306d
    torture_filter_tests(tests);
Packit Service 31306d
    rc = cmocka_run_group_tests(tests, NULL, NULL);
Packit Service 31306d
    ssh_finalize();
Packit Service 31306d
Packit Service 31306d
    return rc;
Packit Service 31306d
}