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

fuzzing: fixed harness bug #1393

Merged
merged 2 commits into from
Aug 26, 2024
Merged

fuzzing: fixed harness bug #1393

merged 2 commits into from
Aug 26, 2024

Conversation

pkillarjun
Copy link
Contributor

@pkillarjun pkillarjun commented Aug 16, 2024

The first patch is straightforward; 69b830b 70961.

The second patch, on the other hand, is quite suspicious. It works now, but I have no idea what I am doing.
I think it does require some changes to the JSON parsing and JSON after parsing.
0d581e8 70961

Report:

The addr->length is 0. It does make my job easy, so I added a check: if the length is zero, return null.
But addr->start holds 303 bytes.

diff --git a/src/nxt_sockaddr.c b/src/nxt_sockaddr.c
index 32941893..c48e0662 100644
--- a/src/nxt_sockaddr.c
+++ b/src/nxt_sockaddr.c
@@ -734,6 +734,9 @@ nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr)
 
     inaddr = INADDR_ANY;
 
+    printf("%c\n", addr->start[303]);
+    printf("%c\n", addr->start[304]); // Crash.
+
     if (length != 1 || addr->start[0] != '*') {
         inaddr = nxt_inet_addr(addr->start, length);
         if (nxt_slow_path(inaddr == INADDR_NONE)) {

Bytes in addr->start

3A20 2020 FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF 2020 2020 2020 2020 2020
2020 2020 2020 2020 2020 2020 2020 2020
2020 2020 FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
FFFF FFFF FFFF FFFF FF20 2020 2020 2020
2020 2020 2020 2020 2020 2020 2020 2020
2020 2020 2020 2020 2020 2020 2020 2020
2020 2020 2020 2020 2020 2020 2020 2020
20BE BEBE BEBE BEBE C003 0000 E050 0000
C003 0000 E050 0000 B002 0000 D050 0000
0102 00BE 0101 0000 4009 0000 2051 00

xxd clusterfuzz-testcase-minimized-fuzz_json-4875165201137664

00000000: 7b22 6c69 7374 656e 6572 7322 3a7b 223a  {"listeners":{":
00000010: 2020 20ff ffff ffff ffff ffff ffff ffff     .............
00000020: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000030: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000040: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000050: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000060: ffff ffff ff20 2020 2020 2020 2020 2020  .....           
00000070: 2020 2020 2020 2020 2020 2020 2020 2020                  
00000080: 2020 20ff ffff ffff ffff ffff ffff ffff     .............
00000090: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000a0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000b0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000c0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000d0: ffff ffff ffff ffff 2020 2020 2020 2020  ........        
000000e0: 2020 2020 2020 2020 2020 2020 2020 2020                  
000000f0: 2020 2020 2020 2020 2020 2020 2020 2020                  
00000100: 2020 2020 2020 2020 2020 2020 2020 2020                  
00000110: 223a 2222 7d7d                           ":""}}

I believe the second patch does require some fine-tuning, nonetheless.

@pkillarjun pkillarjun marked this pull request as draft August 16, 2024 10:57
@pkillarjun pkillarjun changed the title Harness bug fuzzing: fixed harness bug Aug 23, 2024
@pkillarjun pkillarjun marked this pull request as ready for review August 23, 2024 03:45
@ac000
Copy link
Member

ac000 commented Aug 23, 2024

Hmm, does nxt_sockaddr_parse() not catch this? (This is called during configuration validation time).

@hongzhidao
Copy link
Contributor

    if (length == 0) {
        nxt_thread_log_error(NXT_LOG_ERR, "invalid size \"%V\"", length);  /* this looks like a typo, %V is used for nxt_str_t. */
        return NULL;
    }

BTW, can we see the unit.log when running fuzzing? If yes, it's a good way to see what the value from "addr" is.

@hongzhidao
Copy link
Contributor

Hmm, does nxt_sockaddr_parse() not catch this? (This is called during configuration validation time).

You could take a look at its implementation, before nxt_sockaddr_inet_parse() is called, the check of "length == 0" is done in nxt_sockaddr_parse(). I can't get why the added condition can fix the issue if it exists.

@pkillarjun
Copy link
Contributor Author

Hmm, does nxt_sockaddr_parse() not catch this? (This is called during configuration validation time).

I think you are referring to the addr->length check in nxt_sockaddr_parse_optport.

    if (addr->length == 0) {
        nxt_thread_log_error(NXT_LOG_ERR, "socket address cannot be empty");
        return NULL;
    }

nxt_sockaddr_inet_parse execution flow :

static nxt_sockaddr_t *
nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr)
{
    u_char          *p;
    size_t          length;
    nxt_int_t       port;
    in_addr_t       inaddr;
    nxt_sockaddr_t  *sa;

    p = memchr(addr->start, ':', addr->length);

    if (p == NULL) {
        length = addr->length;

    } else {
        length = p - addr->start;  // This is where the length is assigned.
    }

    inaddr = INADDR_ANY;

So, we did check for addr->length in nxt_sockaddr_parse_optport.
but didn't check for length = p - addr->start condition.

Because the length is 0, a bug in nxt_inet_addr got triggered.

    if (nxt_slow_path(*(buf + length - 1) == '.')) { // ASan says hello crash.
        return INADDR_NONE;
    }

@pkillarjun
Copy link
Contributor Author

    if (length == 0) {
        nxt_thread_log_error(NXT_LOG_ERR, "invalid size \"%V\"", length);  /* this looks like a typo, %V is used for nxt_str_t. */
        return NULL;
    }

BTW, can we see the unit.log when running fuzzing? If yes, it's a good way to see what the value from "addr" is.

Patch for enabling logging:

diff --git a/fuzzing/nxt_json_fuzz.c b/fuzzing/nxt_json_fuzz.c
index fa222988..eafbbad8 100644
--- a/fuzzing/nxt_json_fuzz.c
+++ b/fuzzing/nxt_json_fuzz.c
@@ -33,6 +33,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 {
     nxt_mp_t                *mp;
     nxt_str_t               input;
+    nxt_task_t              task;
     nxt_thread_t            *thr;
     nxt_runtime_t           *rt;
     nxt_conf_value_t        *conf;
@@ -43,7 +44,11 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
         return 0;
     }
 
+    nxt_main_log.level = NXT_LOG_DEBUG;
+    task.log  = &nxt_main_log;
+
     thr = nxt_thread();
+    thr->task = &task;
 
     mp = nxt_mp_create(1024, 128, 256, 32);
     if (mp == NULL) {

I think this is what you are asking for:

$ ./build/fuzz_json ~/Downloads/clusterfuzz-testcase-minimized-fuzz_json-4875165201137664
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 1953883576
INFO: Loaded 1 modules   (64882 inline 8-bit counters): 64882 [0x932500, 0x942272), 
INFO: Loaded 1 PC tables (64882 PCs): 64882 [0x942278,0xa3f998), 
./build/fuzz_json: Running 1 inputs 1 time(s) each.
Running: /home/cold/Downloads/clusterfuzz-testcase-minimized-fuzz_json-4875165201137664
fuzzing: [error] invalid size ""
Executed /home/cold/Downloads/clusterfuzz-testcase-minimized-fuzz_json-4875165201137664 in 0 ms
***
*** NOTE: fuzzing was not performed, you have only
***       executed the target code on a fixed set of inputs.

@hongzhidao
Copy link
Contributor

Hi @pkillarjun,
Could you add the python test together with your commit?

diff -r b950107de5c8 test/test_configuration.py
--- a/test/test_configuration.py        Wed Aug 21 16:37:35 2024 +0100
+++ b/test/test_configuration.py        Fri Aug 23 23:09:09 2024 +0800
@@ -261,6 +261,7 @@


 def test_listeners_addr_error():
+    assert 'error' in try_addr(":"), 'no address and port'
     assert 'error' in try_addr("127.0.0.1"), 'no port'

@@ -734,6 +734,11 @@ nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr)

inaddr = INADDR_ANY;

if (length == 0) {
nxt_thread_log_error(NXT_LOG_ERR, "invalid size \"%V\"", length);
Copy link
Contributor

Choose a reason for hiding this comment

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

The logging could be like this:

(..., "invalid address \"%V\"", addr);

Copy link
Member

Choose a reason for hiding this comment

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

The length check should really come before inaddr = INADDR_ANY;... but lets see if this is really the right place for this...

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense.

@pkillarjun
Copy link
Contributor Author

Also,

1. Yes there is a typo:

        nxt_thread_log_error(NXT_LOG_ERR, "invalid size \"%V\"", length);  /* this looks like a typo, %V is used for nxt_str_t. */

2. Yes, commit message is super misleading.

I will fix them.

Could you add the python test together with your commit?

Ok, I will.

Copy link
Contributor

@hongzhidao hongzhidao left a comment

Choose a reason for hiding this comment

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

json: fix Heap-buffer-overflow bug

I don't think the prefix is "json:", you could just use like this:

Fix Heap-buffer-overflow bug in nxt_sockaddr_inet_parse()

Others look good to me.
@ac000 welcome to review.

@ac000
Copy link
Member

ac000 commented Aug 23, 2024

Hmm, I think I'm still confused about exactly what causes the issue...

{                                                                               
    "listeners": {                                                              
        ":": {                                                                                                  
            "pass": "routes"                                                    
        }                                                                       
    },                                                                          
                                                                                
    "routes": [                                                                 
        {                                                                       
            "match": {                                                          
                "uri": "*"                                                      
            },                                                                  
                                                                                
            "action": {                                                         
                "share": "/srv/unit-share$uri"                                  
            }                                                                   
        }                                                                       
    ]                                                                           
}
$ curl -X PUT --data-binary @/home/andrew/src/unit/ZZconfig/invalid-addr.json --unix-socket /opt/unit/control.unit.sock http://localhost/config/
{
	"error": "Invalid configuration.",
	"detail": "The listener address \":\" is invalid."
}

@ac000
Copy link
Member

ac000 commented Aug 23, 2024

An address of : is caught by

    if (length != 1 || addr->start[0] != '*') {                                 
        inaddr = nxt_inet_addr(addr->start, length);                            
        if (nxt_slow_path(inaddr == INADDR_NONE)) {                             
            nxt_thread_log_error(NXT_LOG_ERR, "invalid address \"%V\"", addr);  
            return NULL;                                                        
        }                                                                       
    }

in nxt_sockaddr_inet_parse()

@ac000
Copy link
Member

ac000 commented Aug 23, 2024

If we call into nxt_inet_addr() and length == 0 then we essentially short circuit out that function and return INADDR_NONE;

If we find length is 0 after

    if (p == NULL) {                                                            
        length = addr->length;                                                  
                                                                                
    } else {                                                                    
        length = p - addr->start;                                               
    }

in nxt_sockaddr_inet_parse()

Then yes, I believe returning "invalid address" is right, not because of any error, but just because there's no point going any further.

However couldn't we short circuit this whole thing by simply adding a length < 2 check in nxt_conf_vldt_listener()? (I can't think of any single digit/character as a valid address, (::) is the shortest I can think of, but even that isn't valid here...

The port needs to be specified, so I believe the shortest valid listener address would be six characters, e.g [::]:0 (we don't seem to support short form dotted quad addresses, e.g 1.1:0). If we have less than that there's simply no point going any further...

@ac000
Copy link
Member

ac000 commented Aug 23, 2024

I've tried all kinds of crazzy stuff and don't see any crash...

{
	"error": "Invalid configuration.",
	"detail": "The listener address \":::\" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \"1:1234\" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \"1:1\" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \"1:\" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \":1:\" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \":   \" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \" :\" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \"   :\" is invalid."
}

{
	"error": "Invalid configuration.",
	"detail": "The listener address \"   :   \" is invalid."
}

@ac000
Copy link
Member

ac000 commented Aug 23, 2024

Trying to parse the commit message

nxt_sockaddr_inet_parse calls nxt_inet_addr and processes addr->start and
length,

addr->start is just some pointer that should be pointing to the start of the address string.
length should be the length of that string minus the port part.

Even when length is set to zero, which leads to a mismatch of
buffer and length in nxt_inet_addr, That leads to a crash.

The only way I can get length to be 0 is if the address string starts with a :, which makes sense due to

 p = memchr(addr->start, ':', addr->length);

But then in that case (in nxt_inet_addr())

end = buf + length;

means end == buf

Which then means we don't do

while (buf < end) {
    ...

or

if (dots == 3 && octet < 256) {
    ...

and so just

return INADDR_NONE;

AFAICT, with a length of 0, it doesn't matter what addr->start is in nxt_inet_addr() (other than if is NULL, which it can't/shouldn't be) we would just return with INADDR_NONE.

@ac000
Copy link
Member

ac000 commented Aug 23, 2024

Because the length is 0, a bug in nxt_inet_addr got triggered.

    if (nxt_slow_path(*(buf + length - 1) == '.')) { // ASan says hello crash.
        return INADDR_NONE;
    }

OK, I see it. I think the commit message is a little misleading as I don't see any crash.

Could also be fixed with (in nxt_inet_addr())

    if (nxt_slow_path(length > 0 && *(buf + length - 1) == '.')) {              
        return INADDR_NONE;                                                     
    }

Though I guess your patch is better as it's probably best to invalidate the address as early as possible...

But I think the commit message needs re-working to make it much clearer what and where the problem is...

@ac000
Copy link
Member

ac000 commented Aug 23, 2024

Perhaps something like

socket: Prevent buffer under-read in nxt_inet_addr()

This was found via ASan.

Given a listener address like ":" (or any address where the first
character is a colon) we can end up under-reading the addr->start
buffer here

  if (nxt_slow_path(*(buf + length - 1) == '.')) {              

due to length (essentially the position of the ":" in the string) being
0.

Seeing as any address that starts with a ":" is invalid Unit config
wise, we should simply reject the address if length == 0 in
nxt_sockaddr_inet_parse().

Link: <https://clang.llvm.org/docs/AddressSanitizer.html>
Signed-off-by: Arjun <[email protected]>
[ Commit message - Andrew ]
Signed-off-by: Andrew Clayton <[email protected]>

btw I was curious what GCC's -fanalyzer would say about this sort of thing...

$ gcc -fanalyzer -o u u.c
u.c: In function ‘main’:
u.c:5:13: warning: buffer under-read [CWE-127] [-Wanalyzer-out-of-bounds]
    5 |         if (*(s - 1) == 'H')
      |             ^~~~~~~~
  ‘main’: event 1
    |
    |    5 |         if (*(s - 1) == 'H')
    |      |             ^~~~~~~~
    |      |             |
    |      |             (1) out-of-bounds read at byte -1 but ‘"Hello World"’ starts at byte 0
    |
u.c:5:13: note: valid subscripts for ‘"Hello World"’ are ‘[0]’ to ‘[11]’

  ┌─────────────────────────────┐
  │read of ‘const char’ (1 byte)│
  └─────────────────────────────┘
                 ^
                 │
                 │
  ┌─────────────────────────────┐┌───┬───────────────────────────────────────┬────┐
  │                             ││[0]│                  ...                  │[11]│
  │                             │├───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼────┤
  │     before valid range      ││‘H’│‘e’│‘l’│‘l’│‘o’│‘ ’│‘W’│‘o’│‘r’│‘l’│‘d’│NUL │
  │                             │├───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴────┤
  │                             ││       string literal (type: ‘char[12]’)        │
  └─────────────────────────────┘└────────────────────────────────────────────────┘
  ├──────────────┬──────────────┤├───────────────────────┬────────────────────────┤
                 │                                       │
     ╭───────────┴───────────╮                   ╭───────┴──────╮
     │⚠️  under-read of 1 byte│                  │size: 12 bytes│
     ╰───────────────────────╯                   ╰──────────────╯

@hongzhidao
Copy link
Contributor

Though I guess your patch is better as it's probably best to invalidate the address as early as possible...

Agree, it looks better to be in nxt_sockaddr_inet_parse().

@pkillarjun
Copy link
Contributor Author

Hmm, I think I'm still confused about exactly what causes the issue...
I've tried all kinds of crazzy stuff and don't see any crash...

Try this, Total number of space is 256:

{"listeners":{":                                                                                                                                                                                                                                                                ":""}}

You know I still think our patch is wrong, and there is some kind of weird bug in JSON parsing.
Because we are in a state, and that state causes a crash. This shouldn't happen in the first place where JSON parsing should not allow this state to be created in the first place. We are only fixing the symptom, not the actual cause.

@hongzhidao
Copy link
Contributor

Good point, will look into JSON parsing.

@hongzhidao
Copy link
Contributor

Hmm, I think I'm still confused about exactly what causes the issue...
I've tried all kinds of crazzy stuff and don't see any crash...

Try this, Total number of space is 256:

{"listeners":{":                                                                                                                                                                                                                                                                ":""}}

You know I still think our patch is wrong, and there is some kind of weird bug in JSON parsing. Because we are in a state, and that state causes a crash. This shouldn't happen in the first place where JSON parsing should not allow this state to be created in the first place. We are only fixing the symptom, not the actual cause.

Did you mean your example is an invalid JSON?
Actually, it’s valid.

@pkillarjun
Copy link
Contributor Author

pkillarjun commented Aug 24, 2024

Did you mean your example is an invalid JSON?
Actually, it’s valid.

No, not that.

When the JSON parser assigns addr->start a value, it should do that.

The JSON parser rejects everything if it goes under HEX 0x20, but it doesn't do it when it goes to 0x20 and more than that.

Or possibly I am thinking of something else here.

@hongzhidao
Copy link
Contributor

You know I still think our patch is wrong

It looks like another topic related to JSON parsing.
The fixing to nxt_sockaddr_inet_parse() is correct. nxt_sockaddr_inet_parse() is not only called by conf validation but also by the control socket. For example:

> ./build/unitd --control ":" --no-daemon

@pkillarjun
Copy link
Contributor Author

pkillarjun commented Aug 24, 2024

You know I still think our patch is wrong

It looks like another topic related to JSON parsing. The fixing to nxt_sockaddr_inet_parse() is correct. nxt_sockaddr_inet_parse() is not only called by conf validation but also by the control socket. For example:

> ./build/unitd --control ":" --no-daemon

Ha, make sense now.

When the JSON parser assigns addr->start a value, it should do that.
The JSON parser rejects everything if it goes under HEX 0x20, but it doesn't do it when it goes to 0x20 and more than that.

I was thinking of something else. I meant to say: The address is nothing, the port is not even a number. So why are these even assigned?

{
    "listeners": {
        ":                                                                                                                                                                                                                                                                "
        :""
    }
}

@hongzhidao
Copy link
Contributor

Firstly, it’s valid JSON. It’s successful parsing by JSON parser, then JSON validator which is independent of JSON parser validates the parsed object. The sockaddr parse happens during validation.

@pkillarjun
Copy link
Contributor Author

Firstly, it’s valid JSON. It’s successful parsing by JSON parser, then JSON validator which is independent of JSON parser validates the parsed object. The sockaddr parse happens during validation.

Oh, shit.
I confused myself with JSON and something else. JSON doesn't need a schema. I get it now.

@hongzhidao
Copy link
Contributor

hongzhidao commented Aug 24, 2024

No worries, that kind of confusion is common.
A valid example would be like this:

{
    "listeners": {
        "*:8080": {
             "pass": "routes"
       }
    }
}

The address is used as an object key.

@pkillarjun
Copy link
Contributor Author

Alright, now we are on the same page. You can take a look at it. 1e4c425

@hongzhidao
Copy link
Contributor

Alright, now we are on the same page. You can take a look at it. 1e4c425

LGTM.
BTW, we will release 1.33 soon, it would be great to merge the commit into 1.33. Thanks again.

@pkillarjun
Copy link
Contributor Author

pkillarjun commented Aug 24, 2024

Hi @pkillarjun, Could you add the python test together with your commit?

diff -r b950107de5c8 test/test_configuration.py
--- a/test/test_configuration.py        Wed Aug 21 16:37:35 2024 +0100
+++ b/test/test_configuration.py        Fri Aug 23 23:09:09 2024 +0800
@@ -261,6 +261,7 @@


 def test_listeners_addr_error():
+    assert 'error' in try_addr(":"), 'no address and port'
     assert 'error' in try_addr("127.0.0.1"), 'no port'

I don't think adding a Python test is necessary. Cifuzz will take care of every malformed data.

For Trailing space, I need to use whitespace=-blank-at-eol,-blank-at-eof for test_configuration.py.
And as we know, assert 'error' in try_addr(":"), 'no address and port' is not the actual test.

BTW, we will release 1.33 soon, it would be great to merge the commit into 1.33. Thanks again.

Alright, that will do.

@hongzhidao
Copy link
Contributor

Hi @pkillarjun, Could you add the python test together with your commit?

diff -r b950107de5c8 test/test_configuration.py
--- a/test/test_configuration.py        Wed Aug 21 16:37:35 2024 +0100
+++ b/test/test_configuration.py        Fri Aug 23 23:09:09 2024 +0800
@@ -261,6 +261,7 @@


 def test_listeners_addr_error():
+    assert 'error' in try_addr(":"), 'no address and port'
     assert 'error' in try_addr("127.0.0.1"), 'no port'

I don't think adding a Python test is necessary. Cifuzz will take care of every malformed data.

For Trailing space, I need to use whitespace=-blank-at-eol,-blank-at-eof for test_configuration.py. And as we know, assert 'error' in try_addr(":"), 'no address and port' is not the actual test.

BTW, we will release 1.33 soon, it would be great to merge the commit into 1.33. Thanks again.

Alright, that will do.

Ok, we could do it separately.

@ac000
Copy link
Member

ac000 commented Aug 24, 2024

Right, from what I've seen that test likely wouldn't show any issue, unless the byte before addr->start just so happened to be a ....

@ac000
Copy link
Member

ac000 commented Aug 24, 2024

Thanks @pkillarjun looks good, I'll be happy to merge this on Monday...

@ac000 ac000 added this to the 1.33 milestone Aug 24, 2024
False positive bug in harness due to improper use of the internal API.

Fixes: a93d878 ("fuzzing: add fuzzing targets")
Signed-off-by: Arjun <[email protected]>
Signed-off-by: Andrew Clayton <[email protected]>
This was found via ASan.

Given a listener address like ":" (or any address where the first
character is a colon) we can end up under-reading the addr->start
buffer here

  if (nxt_slow_path(*(buf + length - 1) == '.')) {

due to length (essentially the position of the ":" in the string) being
0.

Seeing as any address that starts with a ":" is invalid Unit config
wise, we should simply reject the address if length == 0 in
nxt_sockaddr_inet_parse().

Link: <https://clang.llvm.org/docs/AddressSanitizer.html>
Signed-off-by: Arjun <[email protected]>
[ Commit message - Andrew ]
Signed-off-by: Andrew Clayton <[email protected]>
@ac000
Copy link
Member

ac000 commented Aug 26, 2024

Rebased with master

$ git range-diff 1e4c4255...932b9146
 -:  -------- >  1:  5d32e500 Packaging: fix build-depends on multiarch debian systems
 -:  -------- >  2:  12c376ab README: Update number of supported languages
 -:  -------- >  3:  11a70a32 docs/openapi: Update the /status endpoint URL
 -:  -------- >  4:  ae4795aa docs/openapi: Add entries for the new /status/modules endpoint
 -:  -------- >  5:  f38201c2 auto: Add a check for Linux's sched_getaffinity(2)
 -:  -------- >  6:  2444d45e lib: Better available cpu count determination on Linux
 -:  -------- >  7:  57c88fd4 router: Make the number of router threads configurable
 -:  -------- >  8:  97c15fa3 socket: Use a default listen backlog of -1 on Linux
 -:  -------- >  9:  76489fb7 conf, router: Make the listen(2) backlog configurable
 -:  -------- > 10:  2eecee75 var: Restrict nxt_tstr_query() to only support synchronous operation
 -:  -------- > 11:  76a255b2 http: Refactor return action
 -:  -------- > 12:  08a23272 http: Refactor route pass query
 -:  -------- > 13:  9d19e7e0 http: Refactor static action
 -:  -------- > 14:  ecb3f86c http: Refactor access log write
 -:  -------- > 15:  5f6ae1a1 var: Remove unused functions and structure fields
 -:  -------- > 16:  82e168fe http: Refactor out nxt_tstr_cond_t from the access log module
 -:  -------- > 17:  57f93956 http: Get rid of nxt_http_request_access_log()
 -:  -------- > 18:  debd61c3 http: Add "if" option to the "match" object
 -:  -------- > 19:  43c4bfdc tests: "if" option in http route match
 -:  -------- > 20:  593564fd ci/unitctl: Update paths
 -:  -------- > 21:  cad6aed5 Tests: initial "wasm-wasi-component" test
 -:  -------- > 22:  05b1c769 docs/openapi: Fix brokenness
 -:  -------- > 23:  cff18f89 docs/openapi: Add new config options
 1:  69b830bf ! 24:  71920769 fuzzing: fixed harness bug
    @@ Commit message
     
         Fixes: a93d878 ("fuzzing: add fuzzing targets")
         Signed-off-by: Arjun <[email protected]>
    +    Signed-off-by: Andrew Clayton <[email protected]>
     
      ## fuzzing/nxt_http_h1p_peer_fuzz.c ##
     @@ fuzzing/nxt_http_h1p_peer_fuzz.c: LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 2:  1e4c4255 = 25:  932b9146 socket: Prevent buffer under-read in nxt_inet_addr()

@ac000 ac000 merged commit 932b914 into nginx:master Aug 26, 2024
25 checks passed
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.

3 participants