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

DAOS-17131 dfs: Possible missing string termination after strncpy function call #15920

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

grom72
Copy link
Contributor

@grom72 grom72 commented Feb 17, 2025

There are several issues in strncpy usage that may cause memory corruption. Target string may not be ended by \0 character.

Issues detected during sanitizer integration
Ref: #15105

Co-authored-by: Cedric Koch-Hofer [email protected]
Co-autohred-by: Tomasz Gromadzki [email protected]

Signed-off-by: Tomasz Gromadzki [email protected]

Before requesting gatekeeper:

  • Two review approvals and any prior change requests have been resolved.
  • Testing is complete and all tests passed or there is a reason documented in the PR why it should be force landed and forced-landing tag is set.
  • Features: (or Test-tag*) commit pragma was used or there is a reason documented that there are no appropriate tags for this PR.
  • Commit messages follows the guidelines outlined here.
  • Any tests skipped by the ticket being addressed have been run and passed in the PR.

Gatekeeper:

  • You are the appropriate gatekeeper to be landing the patch.
  • The PR has 2 reviews by people familiar with the code, including appropriate owners.
  • Githooks were used. If not, request that user install them and check copyright dates.
  • Checkpatch issues are resolved. Pay particular attention to ones that will show up on future PRs.
  • All builds have passed. Check non-required builds for any new compiler warnings.
  • Sufficient testing is done. Check feature pragmas and test tags and that tests skipped for the ticket are run and now pass with the changes.
  • If applicable, the PR has addressed any potential version compatibility issues.
  • Check the target branch. If it is master branch, should the PR go to a feature branch? If it is a release branch, does it have merge approval in the JIRA ticket.
  • Extra checks if forced landing is requested
    • Review comments are sufficiently resolved, particularly by prior reviewers that requested changes.
    • No new NLT or valgrind warnings. Check the classic view.
    • Quick-build or Quick-functional is not used.
  • Fix the commit message upon landing. Check the standard here. Edit it to create a single commit. If necessary, ask submitter for a new summary.

@grom72 grom72 requested review from a team as code owners February 17, 2025 07:12
@grom72 grom72 marked this pull request as draft February 17, 2025 07:12
Copy link

github-actions bot commented Feb 17, 2025

Ticket title is 'Possible missing string termination after strncpy function call'
Status is 'Awaiting Verification'
Labels: 'scrubbed_2.8'
https://daosio.atlassian.net/browse/DAOS-17131

There are several issues in strncpy usage that may cause memory
corruption. Target string may not be ended by `\0` character.

Issues detected during sanitizer integration
Ref: #15105

Co-authored-by: Cedric Koch-Hofer <[email protected]>
Co-autohred-by: Tomasz Gromadzki <[email protected]>

Signed-off-by: Tomasz Gromadzki <[email protected]>
@grom72 grom72 marked this pull request as ready for review February 17, 2025 07:27
@grom72 grom72 requested a review from knard38 February 17, 2025 07:27
@grom72 grom72 mentioned this pull request Feb 17, 2025
18 tasks
@grom72 grom72 requested a review from liw February 17, 2025 07:39
knard38
knard38 previously approved these changes Feb 17, 2025
liw
liw previously approved these changes Feb 17, 2025
@@ -83,7 +84,8 @@ dfs_cont_create(daos_handle_t poh, uuid_t *cuuid, dfs_attr_t *attr, daos_handle_
dattr.da_chunk_size = DFS_DEFAULT_CHUNK_SIZE;

if (attr->da_hints[0] != 0) {
strncpy(dattr.da_hints, attr->da_hints, DAOS_CONT_HINT_MAX_LEN);
/* DAOS-17042 Replace strncpy with strncat or strlcpy */
Copy link
Contributor

Choose a reason for hiding this comment

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

please remove all these comments from the code. they are not helpful

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

@mchaarawi mchaarawi left a comment

Choose a reason for hiding this comment

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

patch looks good to me, but request to remove all the comments and the ticket number. there is no information gained from those comments overall in the code base.
ticket number should be used to note a known or TBD issue, but not fixes; otherwise code become unreadable if everyone does that.

@mchaarawi
Copy link
Contributor

Also please make sure to run with Features: dfs commit pragma. thanks

Possible missing string termination after strncpy function call.

There are several places where using strncpy can cause
memory corruption - the target string may not be terminated
with `\0` character.

Issue has been detected during sanitizer integration:
#15105

Features: dfs

Signed-off-by: Tomasz Gromadzki <[email protected]>
@grom72 grom72 changed the title DAOS-16501 dfs: Possible missing string termination DAOS-17131 dfs: Possible missing string termination after strncpy function call Feb 18, 2025
@grom72 grom72 dismissed stale reviews from liw and knard38 via ee61c0d February 18, 2025 07:31
@grom72
Copy link
Contributor Author

grom72 commented Feb 18, 2025

Also please make sure to run with Features: dfs commit pragma. thanks

Done

@grom72
Copy link
Contributor Author

grom72 commented Feb 18, 2025

patch looks good to me, but request to remove all the comments and the ticket number. there is no information gained from those comments overall in the code base. ticket number should be used to note a known or TBD issue, but not fixes; otherwise code become unreadable if everyone does that.

A new ticket has been created DAOS-17131. It is only related to issues detected by the sanitizer in #15105.

There is another issue DAOS-17042 that addresses the general problem of possible misuse of strncpy().

@grom72 grom72 requested a review from mchaarawi February 18, 2025 07:42
@daosbuild1
Copy link
Collaborator

Test stage NLT on EL 8.8 completed with status UNSTABLE. https://build.hpdd.intel.com/job/daos-stack/job/daos//view/change-requests/job/PR-15920/4/testReport/

Parallel-build: true
Skip-build-el8-rpm: true
Skip-build-el9-rpm: true
Skip-build-leap15-rpm: true
Skip-build-ubuntu20-rpm: true
Skip-build-el8-gcc-dev: true

Skip-build-leap15-icc: true

Skip-test: true
Skip-unit-test: true
Skip-unit-test-memcheck: true
Skip-bullseye: true

Signed-off-by: Tomasz Gromadzki <[email protected]>
@grom72
Copy link
Contributor Author

grom72 commented Feb 20, 2025

Test stage NLT on EL 8.8 completed with status UNSTABLE. https://build.hpdd.intel.com/job/daos-stack/job/daos//view/change-requests/job/PR-15920/4/testReport/

Transient issue in CI fixed in the next build without any source code modification.
https://build.hpdd.intel.com/job/daos-stack/job/daos/view/change-requests/job/PR-15920/5/testReport/

@grom72 grom72 requested a review from a team February 20, 2025 16:54
@mchaarawi
Copy link
Contributor

Test stage NLT on EL 8.8 completed with status UNSTABLE. https://build.hpdd.intel.com/job/daos-stack/job/daos//view/change-requests/job/PR-15920/4/testReport/

Transient issue in CI fixed in the next build without any source code modification. https://build.hpdd.intel.com/job/daos-stack/job/daos/view/change-requests/job/PR-15920/5/testReport/

what is the transient error? is it a known issue? more info is needed when saying the error is transient. it should be a known issue with a ticket.

Copy link
Contributor

@jxiong jxiong left a comment

Choose a reason for hiding this comment

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

There is nothing wrong with the original implementation, IMO. We should address the consistency issue though

@@ -83,7 +84,7 @@ dfs_cont_create(daos_handle_t poh, uuid_t *cuuid, dfs_attr_t *attr, daos_handle_
dattr.da_chunk_size = DFS_DEFAULT_CHUNK_SIZE;

if (attr->da_hints[0] != 0) {
strncpy(dattr.da_hints, attr->da_hints, DAOS_CONT_HINT_MAX_LEN);
strncpy(dattr.da_hints, attr->da_hints, DAOS_CONT_HINT_MAX_LEN - 1);
dattr.da_hints[DAOS_CONT_HINT_MAX_LEN - 1] = '\0';
Copy link
Contributor

Choose a reason for hiding this comment

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

The implementation is actually perfectly fine. Are you see any issues with the original code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, please take a look at #15105

Copy link
Contributor

Choose a reason for hiding this comment

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

I do think the existing code has a bug. If attr->da_hints is exactly DAOS_CONT_HINT_MAX_LEN long, then strncpy copies the entire buffer as expected. But then dattr.da_hints[DAOS_CONT_HINT_MAX_LEN - 1] = '\0'; overwrites the last character.
E.g.

strncpy(dattr.da_hints, "1234", 4);
dattr.da_hints[4 - 1] = '\0';

Yields dattr.da_hints = "123\0"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, finally the string will be somehow OK, but it will be not the same string. The problem of strncpy misusage has been discussed in #15105

Copy link
Contributor

Choose a reason for hiding this comment

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

But then again I guess it doesn't matter because attr->da_hints could be longer than DAOS_CONT_HINT_MAX_LEN and not copied entirely anyway

Copy link
Contributor

Choose a reason for hiding this comment

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

Reading up on this more, it's not actually a misuse of strncpy, but just simply that -Wstringop-truncation warns that you might lose data from the source string.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, doing some local testing, the compiler complains either way. So this change doesn't solve anything

With

char my_string[4];
strncpy(my_string, "1234", 4);
my_string[4-1] = '\0';

It complains with

warning: ‘strncpy’ output truncated before terminating nul copying 4 bytes from a string of the same length [-Wstringop-truncation]
     strncpy(my_string, "1234", 4);

And with

char my_string[4];
strncpy(my_string, "1234", 4-1);
my_string[4-1] = '\0';

It complains with

warning: ‘strncpy’ output truncated copying 3 bytes from a string of length 4 [-Wstringop-truncation]
     strncpy(my_string, "1234", 4-1);

Copy link
Contributor

Choose a reason for hiding this comment

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

I see. thanks for the explanation

@@ -510,7 +511,8 @@ dfs_dup(dfs_t *dfs, dfs_obj_t *obj, int flags, dfs_obj_t **_new_obj)
D_GOTO(err, rc = EINVAL);
}

strncpy(new_obj->name, obj->name, DFS_MAX_NAME + 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Again this is fine too if the obj->name is already valid.

I think a serious issue is about the consistency of using DFS_MAX_NAME. Sometimes the name is defined as name[DFS_MAX_NAME + 1] but sometimes it's name[DFS_MAX_NAME]. I would prefer to use the latter and then redefining maximum object name as DFS_MAX_NAME including the ending zero.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again, this is the result of #15105 + see my comment above: #15920 (comment)

@grom72
Copy link
Contributor Author

grom72 commented Feb 21, 2025

Test stage NLT on EL 8.8 completed with status UNSTABLE. https://build.hpdd.intel.com/job/daos-stack/job/daos//view/change-requests/job/PR-15920/4/testReport/

Transient issue in CI fixed in the next build without any source code modification. https://build.hpdd.intel.com/job/daos-stack/job/daos/view/change-requests/job/PR-15920/5/testReport/

what is the transient error? is it a known issue? more info is needed when saying the error is transient. it should be a known issue with a ticket.

Issue has been created: https://daosio.atlassian.net/browse/DAOS-17149

Features: dfs

Signed-off-by: Tomasz Gromadzki <[email protected]>
@jxiong jxiong self-requested a review February 21, 2025 17:49
@daltonbohning daltonbohning removed the request for review from a team February 21, 2025 17:52
@daosbuild1
Copy link
Collaborator

Test stage Functional Hardware Large completed with status FAILURE. https://build.hpdd.intel.com//job/daos-stack/job/daos/view/change-requests/job/PR-15920/6/execution/node/1420/log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

8 participants