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

[all versions] off by one error in sds string lib flb_sds_printf triggered by specific conditions #7143

Closed
PettitWesley opened this issue Apr 8, 2023 · 13 comments
Assignees
Labels

Comments

@PettitWesley
Copy link
Contributor

PettitWesley commented Apr 8, 2023

Discovered here in a conversation on the linked bug fix: #7129 (comment)

flb_sds_printf will re-alloc if needed: https://github.com/fluent/fluent-bit/blob/master/src/flb_sds.c#L437

However, note the inclusive and exclusive wording in the docs below:

The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte ('\0')). If the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated. (See also below under NOTES.)

https://linux.die.net/man/3/vsnprintf

So the condition on re-alloc'ing the string in the code should be >= and the re-alloc should be +1 larger I think.

Demo

branch: https://github.com/PettitWesley/fluent-bit/commits/sds-off-by-1-demo

See the demo here: PettitWesley@57925b8

And fix here: PettitWesley@a333eeb

unit test here: PettitWesley@8075d6e

[ec2-user@ip-10-192-11-106 build]$ ./bin/fluent-bit -i dummy -o stdout
Fluent Bit v2.1.0
* Copyright (C) 2015-2022 The Fluent Bit Authors
* Fluent Bit is a CNCF sub-project under the umbrella of Fluentd
* https://fluentbit.io

[2023/04/08 00:06:19] [ info] [fluent bit] version=2.1.0, commit=06ae7f1756, pid=11668
[2023/04/08 00:06:19] [ info] [storage] ver=1.4.0, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2023/04/08 00:06:19] [ info] [cmetrics] version=0.6.1
[2023/04/08 00:06:19] [ info] [ctraces ] version=0.3.0
[2023/04/08 00:06:19] [ info] [input:dummy:dummy.0] initializing
[2023/04/08 00:06:19] [ info] [input:dummy:dummy.0] storage_strategy='memory' (memory only)
[2023/04/08 00:06:19] [ info] [sp] stream processor started
[2023/04/08 00:06:19] [ info] [output:stdout:stdout.0] worker #0 started
[2023/04/08 00:06:21] [ info] Example below will work as expected, note that all letters up to z are printed:
[2023/04/08 00:06:21] [ info] [sds] len=64
[2023/04/08 00:06:21] [ info] [sds] size1=66
[2023/04/08 00:06:21] [ info] [sds] size2=66
[2023/04/08 00:06:21] [ info] [sds] head->len=66
[2023/04/08 00:06:21] [ info] TEST: A0123456789 this-is-54-chars-1234567890-abcdefghijklmnopqrstuvwxyz
[2023/04/08 00:06:21] [ info] Example below shows bug, note that all letters up to z are not printed:
[2023/04/08 00:06:21] [ info] [sds] len=64
[2023/04/08 00:06:21] [ info] [sds] size1=64
[0] dummy.0: [[1680912380.264105949, {}], {"message"=>"dummy"}]
[2023/04/08 00:06:21] [ info] [sds] size2=64
[2023/04/08 00:06:21] [ info] [sds] head->len=64
[2023/04/08 00:06:21] [ info] TEST: 123456789 this-is-54-chars-1234567890-abcdefghijklmnopqrstuvwxy

Conditions that cause it

See the len logic here: https://github.com/fluent/fluent-bit/blob/master/src/flb_sds.c#L411

I think to cause this bug to surface, the variables used in the format must be longer than the format in just the right way to get vsnprintf returned size that's equal to the currently alloc'd size.

This is what I used in the demo above:

    flb_sds_t tmp;
    flb_sds_t test = flb_sds_create_size(64);
    if (!test) {
        flb_errno();
        FLB_OUTPUT_RETURN(FLB_ERROR);
    }

    flb_info("Example below will work as expected, note that all letters up to z are printed:");

    tmp = flb_sds_printf(&test, "A0123456789 %s", "this-is-54-chars-1234567890-abcdefghijklmnopqrstuvwxyz");
    flb_info("TEST: %s", tmp);

    flb_sds_t test2 = flb_sds_create_size(64);
    if (!test2) {
        flb_errno();
        FLB_OUTPUT_RETURN(FLB_ERROR);
    }

    flb_info("Example below shows bug, note that all letters up to z are not printed: ");
    tmp = flb_sds_printf(&test2, "123456789 %s", "this-is-54-chars-1234567890-abcdefghijklmnopqrstuvwxyz");
    flb_info("TEST: %s", tmp);
@PettitWesley
Copy link
Contributor Author

Will submit fix PR from above commit very soon.

@PettitWesley
Copy link
Contributor Author

PettitWesley commented Apr 8, 2023

See relevant similar code in upstream/original SDS library: https://github.com/antirez/sds/blob/master/sds.c#L559

Looks like that logic recently changed from a much different older code: antirez/sds@a9a03bb

https://github.com/antirez/sds/blame/fb463145c9c245636feb28b5aac0fc897e16f67e/sds.c#L543

@nokute78
Copy link
Collaborator

nokute78 commented Apr 8, 2023

Note: #7042 and #7041

@leonardo-albertovich
Copy link
Collaborator

Thanks for the links @nokute78, I was sure I had verified this issue with someone else in the past and thought it would've definitely been fixed but I guess it never took off.

It's a legit bug the patches are wrong because flb_sds_increase increments the buffer size by N, doesn't resize the buffer to N which means 438 should be :

tmp = flb_sds_increase(s, flb_sds_alloc(s) - size);

Which in the case of the 64 character string would mean passing 0 as the increment size to the function but considering that the function adds 1 character for the terminator it works.

If the patch is applied as is the buffer would go from 80 characters to 145 whereas with the proper change it would go from 80 to 81.

@PettitWesley
Copy link
Contributor Author

@leonardo-albertovich flb_sds_increase is used twice in the function, right now the first usage increases the alloc by 64... should I also change that to increase it to 64??

@leonardo-albertovich
Copy link
Collaborator

Sure.

@PettitWesley
Copy link
Contributor Author

@leonardo-albertovich sorry actually I think it should be:

tmp = flb_sds_increase(s, size - flb_sds_avail(s) + 1);

We check the avail in the condition which makes sense since the some of the alloc might already be taken by an existing string.

@PettitWesley
Copy link
Contributor Author

I will add unit test for this bug as well

PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Apr 10, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Apr 10, 2023
@PettitWesley
Copy link
Contributor Author

PettitWesley commented Apr 10, 2023

The test here repros it: PettitWesley@8075d6e

PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Apr 10, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Apr 10, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Apr 10, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Apr 10, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Apr 10, 2023
@leonardo-albertovich
Copy link
Collaborator

You are right, I just approved your PRs, thanks a lot!

edsiper pushed a commit that referenced this issue Apr 11, 2023
edsiper pushed a commit that referenced this issue Apr 11, 2023
edsiper pushed a commit that referenced this issue Apr 11, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue May 2, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Jun 2, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue Jun 8, 2023
@github-actions
Copy link
Contributor

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 5 days. Maintainers can add the exempt-stale label.

@github-actions github-actions bot added the Stale label Jul 10, 2023
@github-actions
Copy link
Contributor

This issue was closed because it has been stalled for 5 days with no activity.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jul 15, 2023
@PettitWesley
Copy link
Contributor Author

This was fixed:
#7148
#7147
#7146

@PettitWesley PettitWesley reopened this Jul 17, 2023
matthewfala pushed a commit to matthewfala/fluent-bit that referenced this issue Sep 23, 2023
PettitWesley added a commit to PettitWesley/fluent-bit that referenced this issue May 22, 2024
zhihonl pushed a commit to zhihonl/fluent-bit that referenced this issue Aug 20, 2024
swapneils pushed a commit to amazon-contributing/upstream-to-fluent-bit that referenced this issue Oct 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants