mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Allow building without the exec() supported ...
.. to satisfy restricted environment or fuzzers We are encountering weird issues in the oss-fuzz that the file disappears during coverage build so I assume some corpus sneaked in, that contains some commands that end up being executed as part of the coverage run causing it randomly failing. The solution I propose is to build fuzzers without ability to call arbitrary commands on the filesystem (such as `rm -rf /`) as this is not the point the fuzzers should be testing. This is controlled by the WITH_EXEC CMake option (enabled by default). https://github.com/google/oss-fuzz/issues/10136 Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Sahana Prasad <sahana@redhat.com> Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
This commit is contained in:
committed by
Sahana Prasad
parent
2fe9ed1764
commit
bed4438695
@@ -69,7 +69,9 @@ static void torture_options_set_proxycommand(void **state)
|
||||
char command[255] = {0};
|
||||
struct stat sb;
|
||||
int rc;
|
||||
#ifdef WITH_EXEC
|
||||
socket_t fd;
|
||||
#endif
|
||||
|
||||
rc = stat(NCAT_EXECUTABLE, &sb);
|
||||
if (rc != 0 || (sb.st_mode & S_IXOTH) == 0) {
|
||||
@@ -88,11 +90,15 @@ static void torture_options_set_proxycommand(void **state)
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, command);
|
||||
assert_int_equal(rc, 0);
|
||||
rc = ssh_connect(session);
|
||||
#ifdef WITH_EXEC
|
||||
assert_ssh_return_code(session, rc);
|
||||
fd = ssh_get_fd(session);
|
||||
assert_true(fd != SSH_INVALID_SOCKET);
|
||||
rc = fcntl(fd, F_GETFL);
|
||||
assert_int_equal(rc & O_RDWR, O_RDWR);
|
||||
#else
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
#endif /* WITH_EXEC */
|
||||
}
|
||||
|
||||
#else /* NCAT_EXECUTABLE */
|
||||
@@ -124,7 +130,9 @@ static void torture_options_set_proxycommand_ssh(void **state)
|
||||
const char *address = torture_server_address(AF_INET);
|
||||
char command[255] = {0};
|
||||
int rc;
|
||||
#ifdef WITH_EXEC
|
||||
socket_t fd;
|
||||
#endif
|
||||
|
||||
rc = snprintf(command, sizeof(command),
|
||||
"ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -W [%%h]:%%p alice@%s",
|
||||
@@ -134,11 +142,15 @@ static void torture_options_set_proxycommand_ssh(void **state)
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, command);
|
||||
assert_int_equal(rc, 0);
|
||||
rc = ssh_connect(session);
|
||||
#ifdef WITH_EXEC
|
||||
assert_ssh_return_code(session, rc);
|
||||
fd = ssh_get_fd(session);
|
||||
assert_true(fd != SSH_INVALID_SOCKET);
|
||||
rc = fcntl(fd, F_GETFL);
|
||||
assert_int_equal(rc & O_RDWR, O_RDWR);
|
||||
#else
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
#endif /* WITH_EXEC */
|
||||
}
|
||||
|
||||
static void torture_options_set_proxycommand_ssh_stderr(void **state)
|
||||
@@ -148,7 +160,9 @@ static void torture_options_set_proxycommand_ssh_stderr(void **state)
|
||||
const char *address = torture_server_address(AF_INET);
|
||||
char command[255] = {0};
|
||||
int rc;
|
||||
#ifdef WITH_EXEC
|
||||
socket_t fd;
|
||||
#endif
|
||||
|
||||
/* The -vvv switches produce the desired output on the standard error */
|
||||
rc = snprintf(command, sizeof(command),
|
||||
@@ -159,11 +173,15 @@ static void torture_options_set_proxycommand_ssh_stderr(void **state)
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, command);
|
||||
assert_int_equal(rc, 0);
|
||||
rc = ssh_connect(session);
|
||||
#ifdef WITH_EXEC
|
||||
assert_ssh_return_code(session, rc);
|
||||
fd = ssh_get_fd(session);
|
||||
assert_true(fd != SSH_INVALID_SOCKET);
|
||||
rc = fcntl(fd, F_GETFL);
|
||||
assert_int_equal(rc & O_RDWR, O_RDWR);
|
||||
#else
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
#endif /* WITH_EXEC */
|
||||
}
|
||||
|
||||
static void torture_options_proxycommand_injection(void **state)
|
||||
|
||||
@@ -10,6 +10,8 @@ but they are suitable for debugging.
|
||||
|
||||
## Background
|
||||
|
||||
### Turn off encryption
|
||||
|
||||
Fuzzing ssh protocol is complicated by the way that all the communication
|
||||
between client and server is encrypted and authenticated using keys based
|
||||
on random data, making it impossible to fuzz the actual underlying protocol
|
||||
@@ -17,6 +19,17 @@ as every change in the encrypted data causes integrity errors. For that reason,
|
||||
libssh needs to implement "none" cipher and MAC as described in RFC 4253
|
||||
and these need to be used during fuzzing to be able to accomplish
|
||||
reproducibility and for fuzzers to be able to progress behind key exchange.
|
||||
This is enabled with the `WITH_INSECURE_NONE` CMake option.
|
||||
|
||||
### Do not allow filesystem modification
|
||||
|
||||
The OpenSSH configuration files are quite rich and expects users to know what
|
||||
they do when they write their configuration files. The fuzzer driver is not an
|
||||
average user so it is very happy to try whatever commands come to its "mind",
|
||||
including `rm -rf /` and libssh would be very happy to run it by default. This
|
||||
might remove some parts of the system that are mandatory for fuzzing.
|
||||
To avoid executing dangerous commands like this, the `WITH_EXEC=OFF` CMake
|
||||
option prevents invoking any external command through `exec()` syscall.
|
||||
|
||||
## Corpus creation
|
||||
|
||||
@@ -31,7 +44,7 @@ to use none cipher for the key exchange to be plausible.
|
||||
|
||||
* Compile libssh with support for none cipher and pcap:
|
||||
|
||||
cmake -DWITH_INSECURE_NONE=ON -DWITH_PCAP=ON ../
|
||||
cmake -DWITH_INSECURE_NONE=ON -DWITH_EXEC=OFF -DWITH_PCAP=ON ../
|
||||
|
||||
* Create a configuration file enabling none cipher and mac:
|
||||
|
||||
|
||||
@@ -862,7 +862,7 @@ static void torture_config_match(void **state,
|
||||
}
|
||||
torture_reset_config(session);
|
||||
_parse_config(session, file, string, SSH_OK);
|
||||
#ifdef _WIN32
|
||||
#ifndef WITH_EXEC
|
||||
/* The match exec is not supported on windows at this moment */
|
||||
assert_string_equal(session->opts.host, "otherhost");
|
||||
#else
|
||||
@@ -878,7 +878,7 @@ static void torture_config_match(void **state,
|
||||
}
|
||||
torture_reset_config(session);
|
||||
_parse_config(session, file, string, SSH_OK);
|
||||
#ifdef _WIN32
|
||||
#ifndef WITH_EXEC
|
||||
/* The match exec is not supported on windows at this moment */
|
||||
assert_string_equal(session->opts.host, "otherhost");
|
||||
#else
|
||||
@@ -894,7 +894,7 @@ static void torture_config_match(void **state,
|
||||
}
|
||||
torture_reset_config(session);
|
||||
_parse_config(session, file, string, SSH_OK);
|
||||
#ifdef _WIN32
|
||||
#ifndef WITH_EXEC
|
||||
/* The match exec is not supported on windows at this moment */
|
||||
assert_string_equal(session->opts.host, "otherhost");
|
||||
#else
|
||||
@@ -1855,7 +1855,7 @@ static void torture_config_parser_get_cmd(void **state)
|
||||
{
|
||||
char *p = NULL, *tok = NULL;
|
||||
char data[256];
|
||||
#ifdef __unix__
|
||||
#ifdef WITH_EXEC
|
||||
FILE *outfile = NULL, *infile = NULL;
|
||||
int pid;
|
||||
char buffer[256] = {0};
|
||||
@@ -1899,7 +1899,7 @@ static void torture_config_parser_get_cmd(void **state)
|
||||
assert_string_equal(tok, data);
|
||||
assert_int_equal(*p, '\0');
|
||||
|
||||
#ifdef __unix__
|
||||
#ifdef WITH_EXEC
|
||||
/* Check if the command would get correctly executed
|
||||
* Use the script file "hello world.sh" to echo the first argument
|
||||
* Run as <= "/workdir/hello world.sh" "hello libssh" => */
|
||||
@@ -1929,7 +1929,7 @@ static void torture_config_parser_get_cmd(void **state)
|
||||
|
||||
fclose(outfile);
|
||||
assert_string_equal(buffer, "hello libssh");
|
||||
#endif
|
||||
#endif /* WITH_EXEC */
|
||||
}
|
||||
|
||||
/* ssh_config_get_token() should behave as expected
|
||||
|
||||
@@ -1147,7 +1147,7 @@ static void torture_options_config_match(void **state)
|
||||
|
||||
rv = ssh_options_parse_config(session, "test_config");
|
||||
assert_ssh_return_code(session, rv);
|
||||
#ifdef _WIN32
|
||||
#ifndef WITH_EXEC
|
||||
/* The match exec is not supported on windows at this moment */
|
||||
assert_int_equal(session->opts.port, 34);
|
||||
#else
|
||||
@@ -1169,7 +1169,7 @@ static void torture_options_config_match(void **state)
|
||||
|
||||
rv = ssh_options_parse_config(session, "test_config");
|
||||
assert_ssh_return_code(session, rv);
|
||||
#ifdef _WIN32
|
||||
#ifndef WITH_EXEC
|
||||
/* The match exec is not supported on windows at this moment */
|
||||
assert_int_equal(session->opts.port, 34);
|
||||
#else
|
||||
@@ -1222,7 +1222,7 @@ static void torture_options_config_match_multi(void **state)
|
||||
|
||||
rv = ssh_options_parse_config(session, "test_config");
|
||||
assert_ssh_return_code(session, rv);
|
||||
#ifdef _WIN32
|
||||
#ifndef WITH_EXEC
|
||||
/* The match exec is not supported on windows at this moment */
|
||||
assert_int_equal(session->opts.port, 34);
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user