Open ibara opened 5 years ago
This is exactly the sort of feedback I want, thank you very much! I'll try to get to these ASAP. Did you run anything in specific or just the Makefile as-is?
I had to modify the Makefile since fmake and omake have diverged significantly. But the build steps are (mostly) the same (I wrote the omake Makefile in a way that it doesn't do the depends generation).
I had to port libfetch too; wasn't particularly difficult.
Finally found time, pardon the lengthy delay. Please review d0fcca8a0250ef5a8826137ba4bcf5fc149bf4ec to see if the issues have been resolved. Additionally, I recognize code-quality issues in general with the ini code, which I plan to refactor and clean up.
Here is a diff that fixes things. It also has some additional tweaks to cope with the differences between FreeBSD and OpenBSD. I hope the intent is clear. ogit-fix-buffers.txt
Also errors found by -fsanitize=address
e.g.
% ./ogit log
=================================================================
==36769==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61900000182f at pc 0x0000002c8c78 bp 0x7fffffff5590 sp 0x7fffffff4d30
READ of size 944 at 0x61900000182f thread T0
#0 0x2c8c77 in __interceptor_strdup /usr/home/emaste/src/freebsd/contrib/compiler-rt/lib/asan/asan_interceptors.cc:445:5
#1 0x2fc373 in log_print_commit_headers /usr/home/emaste/src/opengit/log.c:76:17
#2 0x2fcbea in log_display_cb /usr/home/emaste/src/opengit/log.c:122:4
#3 0x2f687f in deflate_caller /usr/home/emaste/src/opengit/lib/zlib-handler.c:153:8
#4 0x2fdbfb in log_get_pack_object /usr/home/emaste/src/opengit/log.c:218:2
#5 0x2fdf51 in log_display_commits /usr/home/emaste/src/opengit/log.c:235:42
#6 0x2fe335 in log_main /usr/home/emaste/src/opengit/log.c:272:2
#7 0x2e7847 in main /usr/home/emaste/src/opengit/ogit.c:81:2
#8 0x24011f in _start /usr/home/emaste/src/freebsd/lib/csu/amd64/crt1.c:76:7
0x61900000182f is located 0 bytes to the right of 943-byte region [0x619000001480,0x61900000182f)
allocated by thread T0 here:
#0 0x2d69ff in __interceptor_realloc /usr/home/emaste/src/freebsd/contrib/compiler-rt/lib/asan/asan_malloc_linux.cc:165:3
#1 0x2fc9c3 in log_display_cb /usr/home/emaste/src/opengit/log.c:114:21
#2 0x2f687f in deflate_caller /usr/home/emaste/src/opengit/lib/zlib-handler.c:153:8
#3 0x2fdbfb in log_get_pack_object /usr/home/emaste/src/opengit/log.c:218:2
#4 0x2fdf51 in log_display_commits /usr/home/emaste/src/opengit/log.c:235:42
#5 0x2fe335 in log_main /usr/home/emaste/src/opengit/log.c:272:2
#6 0x2e7847 in main /usr/home/emaste/src/opengit/ogit.c:81:2
#7 0x24011f in _start /usr/home/emaste/src/freebsd/lib/csu/amd64/crt1.c:76:7
#8 0x80032cfff (<unknown module>)
SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/home/emaste/src/freebsd/contrib/compiler-rt/lib/asan/asan_interceptors.cc:445:5 in __interceptor_strdup
Shadow bytes around the buggy address:
0x4c32000002b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x4c32000002c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x4c32000002d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x4c32000002e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x4c32000002f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x4c3200000300: 00 00 00 00 00[07]fa fa fa fa fa fa fa fa fa fa
0x4c3200000310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x4c3200000320: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x4c3200000330: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x4c3200000340: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x4c3200000350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==36769==ABORTING
Mostly for my reference:
Compile for ASAN using -fsanitize=address
Symbolize the reports with llvm-symbolizer
; on FreeBSD, buildworld installworld with WITH_CLANG_EXTRAS=yes. Alternatively, set ASAN_SYMBOLIZER_PATH env var to an llvm-symbolizer
binary.
Thanks for the assistance everyone. @ibara provided the initial feedback, which I incorporated and I have since incorporated @kevans91's changes. Going forward, I am not familiar with the tooling that Kevin and @emaste suggested. I addeded "-fsanitize=address" to CFLAGS, but do not receive the output when running './ogit log'. Is this the result of the issue having been eliminated or am I using the tooling incorrectly?
gcc-8.3.0 still has a lot to say about things. Build log without -Wall:
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/ogit.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/lib/ini.c
/home/brian/opengit/lib/ini.c: In function 'ini_get_config':
/home/brian/opengit/lib/ini.c:170:2: warning: 'strncat' specified bound 12 equals source length [-Wstringop-overflow=]
strncat(path, "/.git/config", 12);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/lib/index.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/lib/common.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/lib/pack.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/remote.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/init.c
/home/brian/opengit/init.c: In function 'init_dirinit':
/home/brian/opengit/init.c:106:4: warning: 'strncat' specified bound 1024 equals destination size [-Wstringop-overflow=]
strncat(path, "/", PATH_MAX);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/lib/zlib-handler.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/lib/buffering.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/lib/loose.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/hash-object.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/update-index.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/cat-file.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/log.c
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/clone.c
/home/brian/opengit/clone.c: In function 'clone_initial_config':
/home/brian/opengit/clone.c:548:2: warning: 'strncat' specified bound 12 equals source length [-Wstringop-overflow=]
strncat(path, "/.git/config", 12);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O0 -pipe -I/usr/local/include -c /home/brian/opengit/index-pack.c
egcc -lz -L/usr/local/lib -lfetch -o ogit ogit.o ini.o index.o common.o pack.o remote.o init.o zlib-handler.o buffering.o loose.o hash-object.o update-index.o cat-file.o log.o clone.o index-pack.o
and with -Wall
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/ogit.c
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/lib/ini.c
/home/brian/opengit/lib/ini.c: In function 'ini_get_config':
/home/brian/opengit/lib/ini.c:170:2: warning: 'strncat' specified bound 12 equals source length [-Wstringop-overflow=]
strncat(path, "/.git/config", 12);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/lib/ini.c:169:2: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
strncpy(path, repodir, strlen(repodir));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/lib/ini.c: In function 'config_parser':
/home/brian/opengit/lib/ini.c:64:42: warning: '/config' directive output may be truncated writing 7 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(ini_file, sizeof(ini_file), "%s/config", dotgitpath);
^~~~~~~
/home/brian/opengit/lib/ini.c:64:2: note: 'snprintf' output between 8 and 1031 bytes into a destination of size 1024
snprintf(ini_file, sizeof(ini_file), "%s/config", dotgitpath);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/lib/index.c
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/lib/common.c
In file included from /home/brian/opengit/lib/common.c:39:
/home/brian/opengit/lib/pack.h:55:20: warning: 'object_name' defined but not used [-Wunused-variable]
static const char *object_name[] = {
^~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/lib/pack.c
/home/brian/opengit/lib/pack.c: In function 'pack_find_sha_offset':
/home/brian/opengit/lib/pack.c:651:19: warning: variable 'checksums' set but not used [-Wunused-but-set-variable]
struct checksum *checksums;
^~~~~~~~~
/home/brian/opengit/lib/pack.c: In function 'pack_get_packfile_offset':
/home/brian/opengit/lib/pack.c:455:40: warning: '/objects/pack' directive output may be truncated writing 13 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(packdir, sizeof(packdir), "%s/objects/pack", dotgitpath);
^~~~~~~~~~~~~
/home/brian/opengit/lib/pack.c:455:2: note: 'snprintf' output between 14 and 1037 bytes into a destination of size 1024
snprintf(packdir, sizeof(packdir), "%s/objects/pack", dotgitpath);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/lib/pack.c:465:36: warning: '/objects/pack/' directive output may be truncated writing 14 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(filename, PATH_MAX, "%s/objects/pack/%s", dotgitpath,
^~~~~~~~~~~~~~
/home/brian/opengit/lib/pack.c:465:4: note: 'snprintf' output between 15 and 1293 bytes into a destination of size 1024
snprintf(filename, PATH_MAX, "%s/objects/pack/%s", dotgitpath,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dir->d_name);
~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/remote.c
/home/brian/opengit/remote.c: In function 'remote_remove':
/home/brian/opengit/remote.c:92:44: warning: '/.config.XXXXXX' directive output may be truncated writing 15 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(tmpconfig, sizeof(tmpconfig), "%s/.config.XXXXXX", dotgitpath);
^~~~~~~~~~~~~~~
/home/brian/opengit/remote.c:92:2: note: 'snprintf' output between 16 and 1039 bytes into a destination of size 1024
snprintf(tmpconfig, sizeof(tmpconfig), "%s/.config.XXXXXX", dotgitpath);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/init.c
/home/brian/opengit/init.c: In function 'init_main':
/home/brian/opengit/init.c:162:10: warning: variable 'flags' set but not used [-Wunused-but-set-variable]
uint8_t flags = 0;
^~~~~
/home/brian/opengit/init.c: In function 'init_dirinit':
/home/brian/opengit/init.c:106:4: warning: 'strncat' specified bound 1024 equals destination size [-Wstringop-overflow=]
strncat(path, "/", PATH_MAX);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/init.c: In function 'init_main':
/home/brian/opengit/init.c:196:4: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
strncpy(path, repodir, strlen(repodir));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/lib/zlib-handler.c
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/lib/buffering.c
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/lib/loose.c
In file included from /home/brian/opengit/lib/loose.c:40:
/home/brian/opengit/lib/pack.h:55:20: warning: 'object_name' defined but not used [-Wunused-variable]
static const char *object_name[] = {
^~~~~~~~~~~
/home/brian/opengit/lib/loose.c: In function 'loose_content_handler':
/home/brian/opengit/lib/loose.c:53:46: warning: '/objects/' directive output may be truncated writing 9 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c/%s", dotgitpath, sha[0], sha[1], sha+2);
^~~~~~~~~
/home/brian/opengit/lib/loose.c:53:2: note: 'snprintf' output 13 or more bytes (assuming 1036) into a destination of size 1024
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c/%s", dotgitpath, sha[0], sha[1], sha+2);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/hash-object.c
/home/brian/opengit/hash-object.c: In function 'hash_object_create_zlib':
/home/brian/opengit/hash-object.c:114:42: warning: '/objects/' directive output may be truncated writing 9 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(filepath, sizeof(filepath), "%s/objects/%c%c", dotgitpath,
^~~~~~~~~
/home/brian/opengit/hash-object.c:114:2: note: 'snprintf' output between 12 and 1035 bytes into a destination of size 1024
snprintf(filepath, sizeof(filepath), "%s/objects/%c%c", dotgitpath,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
checksum[0], checksum[1]);
~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/hash-object.c: In function 'hash_object_create_file':
/home/brian/opengit/hash-object.c:172:46: warning: '/objects/' directive output may be truncated writing 9 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c",
^~~~~~~~~
/home/brian/opengit/hash-object.c:172:2: note: 'snprintf' output between 12 and 1035 bytes into a destination of size 1024
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dotgitpath, checksum[0], checksum[1]);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/hash-object.c:178:46: warning: '/objects/' directive output may be truncated writing 9 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c/%s",
^~~~~~~~~
/home/brian/opengit/hash-object.c:178:2: note: 'snprintf' output 13 or more bytes (assuming 1036) into a destination of size 1024
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c/%s",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dotgitpath, checksum[0], checksum[1], checksum+2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/update-index.c
/home/brian/opengit/update-index.c: In function 'update_index_open_index':
/home/brian/opengit/update-index.c:62:44: warning: '/index' directive output may be truncated writing 6 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(indexpath, sizeof(indexpath), "%s/index", dotgitpath);
^~~~~~
/home/brian/opengit/update-index.c:62:2: note: 'snprintf' output between 7 and 1030 bytes into a destination of size 1024
snprintf(indexpath, sizeof(indexpath), "%s/index", dotgitpath);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/cat-file.c
/home/brian/opengit/cat-file.c: In function 'cat_file_main':
/home/brian/opengit/cat-file.c:223:4: warning: 'sha_str' may be used uninitialized in this function [-Wmaybe-uninitialized]
cat_file_get_content(sha_str, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/log.c
/home/brian/opengit/log.c: In function 'log_print_commit_headers':
/home/brian/opengit/log.c:78:7: warning: unused variable 'author' [-Wunused-variable]
char author[255];
^~~~~~
/home/brian/opengit/log.c: In function 'log_display_cb':
/home/brian/opengit/log.c:135:18: warning: variable 'oldsize' set but not used [-Wunused-but-set-variable]
int offset = 0, oldsize;
^~~~~~~
In file included from /home/brian/opengit/log.c:41:
At top level:
/home/brian/opengit/lib/pack.h:55:20: warning: 'object_name' defined but not used [-Wunused-variable]
static const char *object_name[] = {
^~~~~~~~~~~
/home/brian/opengit/log.c: In function 'log_get_start_sha':
/home/brian/opengit/log.c:175:42: warning: '/HEAD' directive output may be truncated writing 5 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(headfile, sizeof(headfile), "%s/HEAD", dotgitpath);
^~~~~
/home/brian/opengit/log.c:175:2: note: 'snprintf' output between 6 and 1029 bytes into a destination of size 1024
snprintf(headfile, sizeof(headfile), "%s/HEAD", dotgitpath);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/log.c:188:42: warning: '%s' directive output may be truncated writing up to 39 bytes into a region of size between 0 and 1023 [-Wformat-truncation=]
snprintf(refpath, sizeof(refpath), "%s/%s", dotgitpath, ref);
^~ ~~~
/home/brian/opengit/log.c:188:3: note: 'snprintf' output between 2 and 1064 bytes into a destination of size 1024
snprintf(refpath, sizeof(refpath), "%s/%s", dotgitpath, ref);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/log.c: In function 'log_get_loose_object':
/home/brian/opengit/log.c:214:46: warning: '/objects/' directive output may be truncated writing 9 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c/%s",
^~~~~~~~~
/home/brian/opengit/log.c:214:2: note: 'snprintf' output 13 or more bytes (assuming 1036) into a destination of size 1024
snprintf(objectpath, sizeof(objectpath), "%s/objects/%c%c/%s",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dotgitpath, logarg->sha[0], logarg->sha[1],
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
logarg->sha+2);
~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/clone.c
/home/brian/opengit/clone.c: In function 'clone_pack_protocol_process':
/home/brian/opengit/clone.c:267:6: warning: variable 'check' set but not used [-Wunused-but-set-variable]
int check;
^~~~~
/home/brian/opengit/clone.c: In function 'clone_http_get_sha':
/home/brian/opengit/clone.c:352:6: warning: variable 'content_length' set but not used [-Wunused-but-set-variable]
int content_length;
^~~~~~~~~~~~~~
/home/brian/opengit/clone.c: In function 'generate_tree_item':
/home/brian/opengit/clone.c:606:19: warning: variable 'loosearg' set but not used [-Wunused-but-set-variable]
struct loosearg loosearg;
^~~~~~~~
/home/brian/opengit/clone.c: In function 'clone_http':
/home/brian/opengit/clone.c:452:2: warning: 'strncpy' output truncated before terminating nul copying 24 bytes from a string of the same length [-Wstringop-truncation]
strncpy(suffix, "/.git/objects/pack/pack-", 24);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/clone.c: In function 'clone_initial_config':
/home/brian/opengit/clone.c:548:2: warning: 'strncat' specified bound 12 equals source length [-Wstringop-overflow=]
strncat(path, "/.git/config", 12);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/brian/opengit/clone.c:46:
At top level:
/home/brian/opengit/lib/pack.h:55:20: warning: 'object_name' defined but not used [-Wunused-variable]
static const char *object_name[] = {
^~~~~~~~~~~
/home/brian/opengit/clone.c: In function 'clone_http':
/home/brian/opengit/clone.c:409:2: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
strncpy(path, repodir, pathlen);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/clone.c:408:12: note: length computed here
pathlen = strlen(repodir);
^~~~~~~~~~~~~~~
/home/brian/opengit/clone.c:410:2: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
strncpy(srcpath, repodir, pathlen);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/clone.c:408:12: note: length computed here
pathlen = strlen(repodir);
^~~~~~~~~~~~~~~
/home/brian/opengit/clone.c: In function 'clone_initial_config':
/home/brian/opengit/clone.c:547:2: warning: 'strncpy' specified bound depends on the length of the source argument [-Wstringop-overflow=]
strncpy(path, repodir, strlen(repodir)+1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/brian/opengit/clone.c:547:25: note: length computed here
strncpy(path, repodir, strlen(repodir)+1);
^~~~~~~~~~~~~~~
egcc -O2 -pipe -Wall -I/usr/local/include -MD -MP -c /home/brian/opengit/index-pack.c
In file included from /home/brian/opengit/index-pack.c:46:
/home/brian/opengit/lib/pack.h:55:20: warning: 'object_name' defined but not used [-Wunused-variable]
static const char *object_name[] = {
^~~~~~~~~~~
egcc -lz -L/usr/local/lib -lfetch -o ogit ogit.o ini.o index.o common.o pack.o remote.o init.o zlib-handler.o buffering.o loose.o hash-object.o update-index.o cat-file.o log.o clone.o index-pack.o
With that said, I can successfully clone one of my own repos with:
$ ogit clone https://github.com/ibara/shuf.git
Thank you very much for the comments.
Can you please verify that this (f7eb0d21ebaa25af33c9238afab05c469ecd7922) is the right direction I should be headed? The problem I frequently ran into is, dotgitpath
's size is PATH_MAX
. When I construct path that appends to dotgitpath
, its size will also be PATH_MAX
, thus resulting in an overflow condition.
For example:
char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/foobar", dotgitpath);
If dotgitpath
is at or above PATH_MAX - strlen("/foobar")
, this will trigger an overflow condition.
Yes, the clone works, but I still need to produce the .git/index
file, but there is a good amount of cleanup left to do before I get there. It will also help me going forward to correct my style.
Thank you very much for the comments. Can you please verify that this (f7eb0d2) is the right direction I should be headed? The problem I frequently ran into is,
dotgitpath
's size isPATH_MAX
. When I construct path that appends todotgitpath
, its size will also bePATH_MAX
, thus resulting in an overflow condition.For example:
char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/foobar", dotgitpath);
If
dotgitpath
is at or abovePATH_MAX - strlen("/foobar")
, this will trigger an overflow condition.
To be pedantic, this will not trigger an overflow -- snprintf is documented to write size - 1
characters and null terminate on the size
th character. path
here will end up truncated and the return value of snprintf
will be >= PATH_MAX for you act appropriately on. snprintf should be fine for these cases as long as the source is properly null terminated.
Those strncpy/strncat should be converted to strlcpy/strlcat for a behavior that's a lot more sane if the destination is ever a string that could potentially be printed out somewhere or otherwise used in any way that's expecting proper null termination, because strn* won't guarantee it.
Yes, the clone works, but I still need to produce the
.git/index
file, but there is a good amount of cleanup left to do before I get there. It will also help me going forward to correct my style.
Thank you very much for the comments. Can you please verify that this (f7eb0d2) is the right direction I should be headed? The problem I frequently ran into is,
dotgitpath
's size isPATH_MAX
. When I construct path that appends todotgitpath
, its size will also bePATH_MAX
, thus resulting in an overflow condition. For example:char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/foobar", dotgitpath);
If
dotgitpath
is at or abovePATH_MAX - strlen("/foobar")
, this will trigger an overflow condition.To be pedantic, this will not trigger an overflow -- snprintf is documented to write
size - 1
characters and null terminate on thesize
th character.path
here will end up truncated and the return value ofsnprintf
will be >= PATH_MAX for you act appropriately on. snprintf should be fine for these cases as long as the source is properly null terminated.
Right. That's why in my original diff I suggested a single buffer size of 4096, and I made all the static buffers that size. In one hand, you could say it's wasteful. On the other hand, we're talking about kilobytes and I don't imagine that this would ever be a problem in a practical setting. 4096 is guaranteed to be larger than could be used, and it shuts up a potentially overzealous gcc.
Those strncpy/strncat should be converted to strlcpy/strlcat for a behavior that's a lot more sane if the destination is ever a string that could potentially be printed out somewhere or otherwise used in any way that's expecting proper null termination, because strn* won't guarantee it.
Yes, the clone works, but I still need to produce the
.git/index
file, but there is a good amount of cleanup left to do before I get there. It will also help me going forward to correct my style.
Just to be clear, would this entail something like: #define LARGEST_FILE_PATH 4096
and then replacing PATH_MAX
with LARGEST_FILE_PATH
? I don't see how that changes the overflow condition or why gcc would not complain (does it stop after a number of bytes?), other than making it less likely to accidentally trigger.
Not quite. It's not a blind replacement. See the ogit-fix-buffers.txt file earlier in the thread for a diff. Note where I choose to use OGIT_BUFSIZE. And, more importantly, where I do not.
By the way, you need to check and cap the repodir
variable in init.c
.
gcc-8.2.0 on OpenBSD/amd64 flags a large number of potential buffer overflows. Complete build log: