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

Directory traversal support #830

Merged
merged 42 commits into from
Oct 15, 2021
Merged

Directory traversal support #830

merged 42 commits into from
Oct 15, 2021

Conversation

JonathanHenson
Copy link
Contributor

@JonathanHenson JonathanHenson commented Aug 3, 2021

mem_acquire no longer allows returning NULL, implementation and tests of file-system operations

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

…e-system traversal with posix implementation.
@JonathanHenson JonathanHenson requested a review from a team August 3, 2021 23:18
include/aws/common/file.h Outdated Show resolved Hide resolved
source/allocator.c Outdated Show resolved Hide resolved
source/allocator.c Outdated Show resolved Hide resolved
source/posix/file.c Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
source/allocator.c Outdated Show resolved Hide resolved
source/allocator.c Outdated Show resolved Hide resolved
source/file.c Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
enum aws_file_type {
AWS_FILE_TYPE_NONE,
AWS_FILE_TYPE_FILE,
AWS_FILE_TYPE_SYM_LINK,
Copy link
Contributor

Choose a reason for hiding this comment

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

How about we get rid of this enum and just add aws_directory_entry_is_file(), _is_directory(), _is_symlink(), etc. Since an entry can be symlink AND file, or symlink AND directory.

That's the approach taken by std::filesystem::directory_entry

include/aws/common/file.h Outdated Show resolved Hide resolved
@JonathanHenson JonathanHenson changed the title Directory traversal support [Draft, do not merge] Directory traversal support Aug 13, 2021
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
* Returns at least `size` of memory ready for usage. In versions v0.6.8 and prior, this function was allowed to return
* NULL. In later versions, if allocator->mem_acquire() returns NULL, this function will assert and exit. To handle
* conditions where OOM is not a fatal error, allocator->mem_acquire() is responsible for finding/reclaiming/running a
* GC etc...before returning.
*/
AWS_COMMON_API
void *aws_mem_acquire(struct aws_allocator *allocator, size_t size);
Copy link
Contributor

Choose a reason for hiding this comment

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

Food for thought: Do we want to let users register a global callback that fires before we terminate?

In the Herb Sutter paper that kicked off this whole discussion, it's mentioned as something they might do, in the theoretical world where C++ went this route:

We can additionally allow the program to register a global function to allow customizing what happens when
exiting each function body with an error, intended to be used only by the owner of the whole program. This is
useful for several purposes:
• To integrate with an existing system’s error handling or logging policy.

Copy link
Contributor

Choose a reason for hiding this comment

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

Man, I love that paper:

Microsoft Word. Word also had been intentionally written to handle allocation failure gracefully. Re-
cently (summer 2019), the Word team conducted similar allocation fault injection test using their own
low-memory test environment. It discovered that the code they believed was allocation failure-resilient
actually failed pervasively when allocation failure was actually encountered; for example, 98% of execu-
tions crashed if <5MB memory was available. Examination showed that the code was doing a consist-
ently good job of checking for failures, but was consistently unable to meaningfully handle them. As an
experiment, the team built Word to unconditionally terminate on allocation failure, gradually rolled it
out to larger and larger subsets of users, and then made it universal in for the production release; there
was no statistically significant change in crash rates on Windows, Mac, iOS, or Android. The net result
was that Word now has fewer untested (and security-exploitable) error code paths, clearer code, and
improvements to execution performance and binary size because of elimination of “dead code” logging
and recovery logic (without loss of functionality because that code was already unused and nonworking
in practice).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we already have that hook in the allocator implementation? want one? define that allocator and use it. done

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree, no reason to add more callbacks to set.

Comment on lines +29 to +36
/**
* Absolute path to the entry from the current process root.
*/
struct aws_byte_cursor path;
/**
* Path to the entry relative to the current working directory.
*/
struct aws_byte_cursor relative_path;
Copy link
Contributor

@graebm graebm Aug 13, 2021

Choose a reason for hiding this comment

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

if we're going to require users to pass aws_string* or const char * to our file APIs, we may as well make path and relative_path either aws_string * or const char * too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

don't need to though. I can guarantee they're properly constructed. This does nothing except for increase allocaton overhead for no good reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the api and type system will already force users to pass an aws_string to turn around and call the other apis. I don't know, I see the argument on ergonomics, but I don't think the ergonomics make practical sense here unless we go rewrite the aws_string implementation.

# define AWS_PANIC_OOM(mem, msg) \
do { \
if (!(mem)) { \
fprintf(stderr, "%s: %s, line %d", msg, __FILE__, __LINE__); \
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't help anything with CBMC traces, we can remove it from here. Developer will be able to see the error message in the value of msg.

source/allocator.c Outdated Show resolved Hide resolved
source/allocator.c Outdated Show resolved Hide resolved
source/string.c Show resolved Hide resolved
source/string.c Outdated Show resolved Hide resolved
source/string.c Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
source/allocator.c Show resolved Hide resolved
* Returns at least `size` of memory ready for usage. In versions v0.6.8 and prior, this function was allowed to return
* NULL. In later versions, if allocator->mem_acquire() returns NULL, this function will assert and exit. To handle
* conditions where OOM is not a fatal error, allocator->mem_acquire() is responsible for finding/reclaiming/running a
* GC etc...before returning.
*/
AWS_COMMON_API
void *aws_mem_acquire(struct aws_allocator *allocator, size_t size);
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree, no reason to add more callbacks to set.

include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/file.h Outdated Show resolved Hide resolved
include/aws/common/string.h Outdated Show resolved Hide resolved
source/allocator_sba.c Outdated Show resolved Hide resolved
source/allocator_sba.c Outdated Show resolved Hide resolved
source/posix/file.c Show resolved Hide resolved
*
* returns NULL on failure.
*/
AWS_COMMON_API struct aws_string *aws_string_convert_to_wchar_str(
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like a bad idea to SOMETIMES put UTF-16 in an aws_string.

I'd prefer we add a new type like aws_wstring or aws_string16 or aws_utf16. We wouldn't need to have the full suite of functions we have for vanilla aws_string, just add enough to get by

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added.


struct aws_string *w_file_path = aws_string_convert_to_wchar_str(aws_default_allocator(), file_path);
struct aws_string *w_mode = aws_string_convert_to_wchar_str(aws_default_allocator(), mode);
struct aws_wstring *w_file_path = aws_string_convert_to_wstring(aws_default_allocator(), file_path);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is devilish, but I get it. We're going to have to be super careful with path handling on windows, ensuring that we always utf-8 encode it ourselves.

@JonathanHenson JonathanHenson merged commit 8c51377 into main Oct 15, 2021
@JonathanHenson JonathanHenson deleted the directory_support branch October 15, 2021 02:34
ronakfof pushed a commit to ronakfof/aws-c-common that referenced this pull request Feb 21, 2022
mem_acquire no longer allows returning NULL, Windows unicode support in aws_string.h, file system and directory implementations for windows and posix.
graebm pushed a commit that referenced this pull request May 9, 2023
This function's implementation was removed in #830, but the declaration wasn't.
graebm added a commit to awslabs/aws-c-io that referenced this pull request Jul 10, 2024
**Issue:**

A C++ SDK user found a memory leak in the Windows TLS channel-handler code and submitted the following PR: #651

In evaluating this 2-line fix, I noticed that it sat in the middle of some (preexisting) sloppy error-handling.

**Description of changes:**
- Fix memory leak, as shown in @normanade's PR, by calling `FreeContextBuffer()`.
    - Change it so we **always** call `FreeContextBuffer()` after calling to `AcceptSecurityContext()`/`InitializeSecurityContextA()`. Previously we'd only free the buffer in certain circumstances, and were probably leaking.
- Remove (often sloppy) error-handling that tries to deal with allocation failures of `aws_io_message`. Officially declare that message allocations can't fail.
    - NOTE: Ever since [this change in 2021](awslabs/aws-c-common#830), our allocators will never return `NULL`. They deal with OOM by immediately terminating the program. This was done because error-handling code for allocation failure makes everything so much more complex, and it's seldom tested. We tried for years to handle it. It's not worth the effort.
- Fix some error-handling that forgot to delete the `aws_io_message` after checking its capacity
- In the Windows TLS code, replace some `AWS_ASSERT()` about buffers being large enough with `AWS_FATAL_ASSERT()`. Similarly, add an `AWS_FATAL_ASSERT()` in one place that never checked or asserted before doing the copy.
    - I don't know enough about TLS or Windows APIs to say whether or not these deserve real error-handling. So I'm just preserving the status quo (but crashing instead of doing undefined behavior).

Co-authored-by: @normanade
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.

4 participants