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

feat(os): add copy_argv() function #281

Merged
merged 5 commits into from
Sep 20, 2022
Merged

Conversation

aloisklink
Copy link
Contributor

C programs such as run_command() accept argv as an char *, not a const char *. This is because the main() function of programs is explicitly allowed to modify the data in argv().

This can cause issues, since we declare arrays using string literals, (e.g. char * argv[] = {"hello", "world", NULL};), and modifying string literals is undefined behaviour.

To get around this, we can just make a mofiiable copy of argv before passing it to run_command().

There is a warning we can enable that will check for this (-Wwrite-strings), but it creates 100s of warnings throughout our code-base, so it's something we should slowly fix.

C programs such as run_command() accept argv as an `char *`, not
a `const char *`. This is because the `main()` function of programs
is explicitly allowed to modify the data in `argv()`.

This can cause issues, since we declare arrays using string literals,
(e.g. `char * argv[] = {"hello", "world", NULL};`), and modifying
string literals is undefined behaviour.

To get around this, we can just make a mofiiable copy of argv before
passing it to run_command().

There is a warning we can enable that will check for this
(`-Wwrite-strings`), but it creates 100s of warnings throughout our
code-base, so it's something we should slowly fix.
@aloisklink aloisklink added enhancement New feature or request refactor Refactoring code labels Sep 19, 2022
@codecov
Copy link

codecov bot commented Sep 19, 2022

Codecov Report

Merging #281 (430604f) into main (654ff69) will increase coverage by 0.10%.
The diff coverage is 96.77%.

❗ Current head 430604f differs from pull request most recent head df07c7b. Consider uploading reports for the commit df07c7b to get more accurate results

@@            Coverage Diff             @@
##             main     #281      +/-   ##
==========================================
+ Coverage   49.04%   49.14%   +0.10%     
==========================================
  Files         116      116              
  Lines       18519    18542      +23     
==========================================
+ Hits         9083     9113      +30     
+ Misses       9436     9429       -7     
Impacted Files Coverage Δ
src/utils/os.h 100.00% <ø> (ø)
src/utils/os.c 46.67% <92.30%> (+1.37%) ⬆️
tests/utils/test_os.c 97.79% <100.00%> (-0.45%) ⬇️
tests/ap/test_hostapd.c 92.42% <0.00%> (-0.44%) ⬇️
tests/capture/middlewares/test_packet_queue.c 100.00% <0.00%> (ø)
src/utils/nl.c 10.71% <0.00%> (+0.02%) ⬆️
tests/capture/middlewares/test_sqlite_header.c 100.00% <0.00%> (+24.32%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

src/utils/os.c Outdated Show resolved Hide resolved
Copy link
Contributor

@mereacre mereacre left a comment

Choose a reason for hiding this comment

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

Need tests for copy_argv

log_errno("Failed to malloc %d bytes", argv_array_size + strings_length);
return NULL;
}
char *const argv_string_buffer = &((char *)argv_copy)[argv_array_size];
Copy link
Contributor

Choose a reason for hiding this comment

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

Not clear where argv_copy[0] is assigned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

argv_copy[0] is assigned a few lines down:

argv_copy[i] = &(argv_string_buffer[string_bytes]);

The first half of the malloc()-ed data is filled char* (string pointers).
The second half of the malloc()-ed data is where the string buffer/contents are.

Essentially, if you copy const char * argv[] = {"Hello", "World!", NULL};, the data structure of argv_copy looks something like the following:

Address 0-7 8-15 16-23 24-29 30-36
CType char* char* char* char[] char[]
Value 24 30 NULL "Hello" "World!"

I've added some more comments, since I had to make the data structure a bit confusing so that a single free() will delete all the data, see

edgesec/src/utils/os.c

Lines 332 to 336 in 430604f

/**
* Pointer to beginning of string buffer within argv_copy.
* This is a separate variable as it's a different type to `copy_argv[0]`
* (char vs char *), and therefore pointer arthmetic gets complicated.
*/

aloisklink and others added 3 commits September 20, 2022 13:47
Co-authored-by: Alexandru Mereacre <mereacre@gmail.com>
Adds some additional comments on what certain confusing variables do.
@aloisklink
Copy link
Contributor Author

Tests added in 430604f!

Copy link
Contributor

@mereacre mereacre left a comment

Choose a reason for hiding this comment

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

Thanks. That's clear.

@aloisklink aloisklink merged commit abdfe16 into main Sep 20, 2022
@aloisklink aloisklink deleted the feat/add-copy-argv-func branch September 20, 2022 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request refactor Refactoring code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants