Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed strcasestr() #3076

Merged
merged 1 commit into from
Oct 21, 2022
Merged

Fixed strcasestr() #3076

merged 1 commit into from
Oct 21, 2022

Conversation

iskraman
Copy link
Contributor

$> gcc --version
gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE

$> getconf -a | grep libc
GNU_LIBC_VERSION                   glibc 2.35
  • Test code
// test code
#include <stdio.h>
#include <string.h>

int main() {
	char *data = "sha-256 F1:CD:64:51:BE:0C:5E:3E:81:60:9B:64:AA:4E:27:91:B9:B6:E4:59:29:AB:EB:A2:83:71:1C:9A:86:56:DC:BD";

	if(strcasestr(data, "sha-256 ") == data) {
		printf("Ok!\n");
	} else {
		printf("Failed!\n");
	}

	return 0;
}

$> ./a.out
Failed!

@januscla
Copy link

Thanks for your contribution, @iskraman! Please make sure you sign our CLA, as it's a required step before we can merge this.

@lminiero
Copy link
Member

Problem : strncasecmp() function -> This function may fail to find matches on some platforms

Is strncasecmp a typo here? We use that one A LOT in Janus, while strcasestr is only used for that SHA check.

@lminiero
Copy link
Member

lminiero commented Oct 3, 2022

@iskraman ping...

@iskraman
Copy link
Contributor Author

iskraman commented Oct 11, 2022 via email

@atoppi
Copy link
Member

atoppi commented Oct 13, 2022

TL;DR: I agree with this proposal.
Before merging please:

  1. fix also the other two occurrences of strcasestr in sdp.c
  2. consider the empty char after sha-1 or sha-256 like in the original code
  3. fix indentation

As @iskraman mentioned, being strcasestr not a standard function it needs the definition of _GNU_SOURCE in order to be correctly used.

If that macro is not defined, the shared C snippet will successfully build, but with the following warning:

test.c: In function ‘main’:
test.c:7:12: warning: implicit declaration of function ‘strcasestr’; did you mean ‘strcasecmp’? [-Wimplicit-function-declaration]
    7 |         if(strcasestr(data, "sha-256 ") == data) {
      |            ^~~~~~~~~~
      |            strcasecmp
test.c:7:41: warning: comparison between pointer and integer
    7 |         if(strcasestr(data, "sha-256 ") == data) {
      |

and the output will not be the expected one -> matching failed.

I didn't check, but I guess the compiler is replacing strcasestr with strcasecmp?
In environments with different std libraries that function could not exist at all, leading to building errors.

Since we are basically using strcasestr to check the presence of sha-1/sha-256 at the beginning of the string, replacing it with strncasecmp looks functionally equivalent to me.

@atoppi
Copy link
Member

atoppi commented Oct 17, 2022

TL;DR: checked through gdb and assembly why this is happening, and I am still strongly convinced that a patch is needed here.


When _GNU_SOURCE is not defined the declaration of strcasestr is being skipped and the compiler expects int to be the return type of strcasestr, whereas it should be a pointer (long).
Linking is not failing though, since the standard library actually has the needed symbol so a binary is being successfully produced.

The actual return value of strcasestr is correct in the standard lib (checked going step by step), but the code is casting it to an int value when returning it.
Indeed the pointer returned by strcasestr 0x555555556008 becomes 0x55556008, hence the check failure.

This is confirmed by inspecting the assembly, due to the code fetching the result of strcasestr from eax (32 bit) and extending it to rax (64 bit) through the cdqe instruction, then using the extended value to perform the check:

        mov     eax, 0
        call    strcasestr                 ;     save the output in rax/eax
        cdqe                               ;     extend eax in rax
        cmp     QWORD PTR [rbp-8], rax     ;     compare rax and the ptr to the string

In the version with _GNU_SOURCE defined the rax register includes the return value of strcasestr and is used to check the matching:

        call    strcasestr                 ;     save the output in rax/eax
        cmp     QWORD PTR [rbp-8], rax     ;     compare rax and the ptr to the string

@lminiero
Copy link
Member

@iskraman can you please address the feedback @atoppi provided, so that we can merge? Thanks!

Before merging please:

1. fix also the other two occurrences of `strcasestr` in `sdp.c`

2. consider the empty char after `sha-1` or `sha-256` like in the original code

3. fix indentation

@iskraman
Copy link
Contributor Author

@lminiero @atoppi Please check if what you said is correct.

@@ -357,6 +357,7 @@ int janus_sdp_process_remote(void *ice_handle, janus_sdp *remote_sdp, gboolean r
/* FIXME We should handle this somehow anyway... OpenSSL supports them all */
JANUS_LOG(LOG_WARN, "[%"SCNu64"] Hashing algorithm not the one we expected (sha-256), *NOT* cool\n", handle->handle_id);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove this empty line

@lminiero
Copy link
Member

Thanks! Merging then (I'll remove the extra line myself). I'll also take care of porting the fix to 0.x too.

@lminiero lminiero merged commit 78da5c5 into meetecho:master Oct 21, 2022
@tmatth
Copy link
Contributor

tmatth commented Oct 21, 2022

BTW in case anyone was curious, calling strlen on a literal as done here on strlen("sha-1 ") gets compiled away to a mov of whatever the length (known at compile-time) is, which is cool:
https://godbolt.org/z/ETs1MzW7v

@lminiero
Copy link
Member

@tmatth that's the kind of things that always gets @atoppi way too excited 😄

@iskraman iskraman deleted the strcasestr-fix branch October 21, 2022 14:01
@iskraman
Copy link
Contributor Author

thanks! @lminiero @atoppi

croudet added a commit to croudet/janus-gateway that referenced this pull request Oct 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants