This issue was discovered by me while working on #463 and then confirmed by @bugaevc.
strncpy is doing its job and then returning NULL for some reason.
Darling [/Volumes/SystemRoot/home/me]$ lldb -- curl https://www.apple.com
(lldb) target create "curl"
Didn't find debug symbols at /System/Library/Caches/dsym/uuid/79C0D0C2-0CD2-37F3-A869-F82F65FDA0BB.dSYM based on UUID
Debug symbols not found at /usr/lib/dyld
Current executable set to 'curl' (x86_64).
(lldb) settings set -- target.run-args "https://www.apple.com"
(lldb) run
Process 117 launched: '/usr/bin/curl' (x86_64)
struct ccrng_state *ccDRBGGetRngState(int *) just putting this here until we build CommonCrypto
struct ccrng_state *ccDRBGGetRngState(int *) just putting this here until we build CommonCrypto
Process 117 stopped
* thread #1, name = 'curl', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x00007ffff5689bda libsystem_kernel.dylib`mig_strncpy(dest="", src="", len=128) at mig_strncpy.c:87
Target 0: (curl) stopped.
(lldb) bt
warning: could not find Objective-C class data in the process. This may reduce the quality of type information available.
* thread #1, name = 'curl', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
* frame #0: 0x00007ffff5689bda libsystem_kernel.dylib`mig_strncpy(dest="", src="", len=128) at mig_strncpy.c:87
frame #1: 0x00007ffff5319476 liblaunch.dylib`vproc_mig_look_up2(j=2055, servicename=0x0000000000000000, serviceport=0x00007fffffdfc48c, servercreds=0x00007fffffdfc3c0, targetpid=0, instanceid="", flags=8) at jobUser.c:892
frame #2: 0x00007ffff5312293 liblaunch.dylib`bootstrap_look_up3(bp=2055, service_name=0x0000000000000000, sp=0x00007fffffdfc48c, target_pid=0, instance_id="", flags=8) at libbootstrap.c:204
frame #3: 0x00007ffff5312206 liblaunch.dylib`bootstrap_look_up2(bp=2055, service_name=0x0000000000000000, sp=0x00007fffffdfc48c, target_pid=0, flags=8) at libbootstrap.c:191
frame #4: 0x00007ffff789c5fc Security`Security::MachPlusPlus::Bootstrap::lookup2(this=0x00007fffffdfc4e0, name="com.apple.SecurityServer") const at mach++.cpp:250
frame #5: 0x00007ffff78be13d Security`Security::SecurityServer::ClientSession::findSecurityd() at ssclient.cpp:183
frame #6: 0x00007ffff78bddb1 Security`Security::SecurityServer::ClientSession::Global::Global(this=0x00007fdbd640db60) at ssclient.cpp:131
frame #7: 0x00007ffff78be235 Security`Security::SecurityServer::ClientSession::Global::Global(this=0x00007fdbd640db60) at ssclient.cpp:129
frame #8: 0x00007ffff78c75a8 Security`Security::ModuleNexus<Security::SecurityServer::ClientSession::Global>::make() at globalizer.h:122
frame #9: 0x00007ffff78af4ae Security`Security::ModuleNexusCommon::do_create(this=0x00007ffff7a53d88, make=(Security`Security::ModuleNexus<Security::SecurityServer::ClientSession::Global>::make() at globalizer.h:122))()) at globalizer.cpp:53
frame #10: 0x00007ffff78af5d3 Security`::___ZN8Security17ModuleNexusCommon6createEPFPvvE_block_invoke(.block_descriptor=0x00007fffffdfc8a0) at globalizer.cpp:65
frame #11: 0x00007ffff5549fba libdispatch.dylib`_dispatch_client_callout(ctxt=0x00007fffffdfc8a0, f=(Security`::___ZN8Security17ModuleNexusCommon6createEPFPvvE_block_invoke() at globalizer.cpp:65)) at objectm.m:434
frame #12: 0x00007ffff554a2ac libdispatch.dylib`dispatch_once_f(val=0x00007ffff7a53d90, ctxt=0x00007fffffdfc8a0, func=(Security`::___ZN8Security17ModuleNexusCommon6createEPFPvvE_block_invoke() at globalizer.cpp:65)) at once.c:51
frame #13: 0x00007ffff554a15b libdispatch.dylib`dispatch_once(val=0x00007ffff7a53d90, block=0x00007ffff78af5b0) at once.c:39
frame #14: 0x00007ffff78af584 Security`Security::ModuleNexusCommon::create(void* (*)()) [inlined] _dispatch_once(predicate=0x00007ffff7a53d90, block=0x00007ffff78af5b0) block_pointer) at once.h:75
frame #15: 0x00007ffff78af565 Security`Security::ModuleNexusCommon::create(this=0x00007ffff7a53d88, make=(Security`Security::ModuleNexus<Security::SecurityServer::ClientSession::Global>::make() at globalizer.h:122))()) at globalizer.cpp:65
frame #16: 0x00007ffff78bf4fd Security`Security::ModuleNexus<Security::SecurityServer::ClientSession::Global>::operator(this=0x00007ffff7a53d88)() at globalizer.h:84
frame #17: 0x00007ffff78bda86 Security`Security::SecurityServer::ClientSession::activate(this=0x00007fffffdfca08) at ssclient.cpp:87
frame #18: 0x00007ffff77edbec Security`Security::MDSSession::DbOpen(this=0x00007fdbd640d470, DbName="MDS CDSA Directory", DbLocation=0x0000000000000000, AccessRequest=1, AccessCred=0x0000000000000000, OpenParameters=0x0000000000000000, DbHandle=0x00007fdbd640d3e8) at MDSSession.cpp:693
frame #19: 0x00007ffff77fa5b6 Security`mds_DbOpen(DLHandle=140582169138402, DbName="MDS CDSA Directory", DbLocation=0x0000000000000000, AccessRequest=1, AccessCred=0x0000000000000000, OpenParameters=0x0000000000000000, DbHandle=0x00007fdbd640d3e8) at mdsapi.cpp:196
frame #20: 0x00007ffff748889e Security`Security::MDSClient::Directory::cdsa(this=0x00007fdbd640d360) const at mdsclient.cpp:68
frame #21: 0x00007ffff7488933 Security`Security::MDSClient::Directory::dlGetFirst(this=0x00007fdbd640d360, query=0x00007fffffdfd200, attributes=0x00007fdbd640d810, data=0x00007fffffdfd138, id=0x00007fffffdfd148) at mdsclient.cpp:86
frame #22: 0x00007ffff7497efe Security`Security::CssmClient::Table<Security::MDSClient::Common>::startQuery(this=0x00007fffffdfd4a0, query=0x00007fffffdfd200, getData=true) at dliterators.h:251
frame #23: 0x00007ffff7497b69 Security`Security::CssmClient::Table<Security::MDSClient::Common>::find(this=0x00007fffffdfd4a0, query=0x00007fffffdfd430) at dliterators.h:229
frame #24: 0x00007ffff74972a4 Security`Security::CssmClient::Table<Security::MDSClient::Common>::fetch(this=0x00007fffffdfd4a0, query=0x00007fffffdfd430, err=-2147418109) at dliterators.h:195
frame #25: 0x00007ffff7605bab Security`MdsComponent::MdsComponent(this=0x00007fffffdfdb48, guid=0x00007fdbd640cbe4) at cssmmds.cpp:41
frame #26: 0x00007ffff7605d0d Security`MdsComponent::MdsComponent(this=0x00007fffffdfdb48, guid=0x00007fdbd640cbe4) at cssmmds.cpp:38
frame #27: 0x00007ffff7627952 Security`CssmManager::loadModule(this=0x00007fdbd640cc90, guid=0x00007fdbd640cbe4, (null)=0, callback=0x00007fffffdfdc08) at manager.cpp:135
frame #28: 0x00007ffff7620154 Security`::CSSM_ModuleLoad(ModuleGuid=0x00007fdbd640cbe4, KeyHierarchy=0, AppNotifyCallback=0x0000000000000000, AppNotifyCallbackCtx=0x0000000000000000) at cssm.cpp:85
frame #29: 0x00007ffff748b21e Security`Security::CssmClient::ModuleImpl::activate(this=0x00007fdbd640cb00) at cssmclient.cpp:414
frame #30: 0x00007ffff748bb49 Security`Security::CssmClient::ModuleImpl::load(this=0x00007fdbd640cb00) at cssmclient.h:204
frame #31: 0x00007ffff748b945 Security`Security::CssmClient::AttachmentImpl::activate(this=0x00007fdbd640c7d0) at cssmclient.cpp:482
frame #32: 0x00007ffff7727ad9 Security`Security::CssmClient::AttachmentImpl::attach(this=0x00007fdbd640c7d0) at cssmclient.h:257
frame #33: 0x00007ffff772767c Security`Security::CssmClient::AttachmentImpl::handle(this=0x00007fdbd640c7d0) at cssmclient.h:263
frame #34: 0x00007ffff7690ad7 Security`Security::KeychainCore::Certificate::clHandle(this=0x00007fdbd640c578) at Certificate.cpp:1107
frame #35: 0x00007ffff769125a Security`Security::KeychainCore::Certificate::copyFirstFieldValue(this=0x00007fdbd640c578, field=0x00007ffff7a2d2f8) at Certificate.cpp:292
frame #36: 0x00007ffff76960fd Security`Security::KeychainCore::Certificate::publicKey(this=0x00007fdbd640c578) at Certificate.cpp:1206
frame #37: 0x00007ffff77115d8 Security`::SecCertificateCopyPublicKey(certificate=0x00007fdbd640b000, key=0x00007fffffdfe200) at SecCertificate.cpp:306
frame #38: 0x00007ffff777e4e2 Security`::SecTrustCopyPublicKey(trust=0x00007fdbd640c1e0) at SecTrust.cpp:686
frame #39: 0x00007ffff7322f96 Security`tls_helper_set_peer_pubkey(hdsk=0x00007fdbc6805000) at tls_helpers.c:199
frame #40: 0x00007ffff783b402 Security`tls_handshake_message_callback(ctx=0x00007fdbd6407d90, event=tls_handshake_message_certificate) at tlsCallbacks.c:96
frame #41: 0x00007ffff54d60bf libsystem_coretls.dylib`SSLProcessHandshakeRecordInner(rec=(length = 3024, data = "\v"), ctx=0x00007fdbc6805000) at sslHandshake.c:241
frame #42: 0x00007ffff54d6936 libsystem_coretls.dylib`SSLProcessHandshakeRecord(rec=(length = 3024, data = "\v"), ctx=0x00007fdbc6805000) at sslHandshake.c:491
frame #43: 0x00007ffff54e0525 libsystem_coretls.dylib`tls_handshake_process(filter=0x00007fdbc6805000, message=(length = 3024, data = "\v"), contentType='\x16') at tls_handshake.c:298
frame #44: 0x00007ffff783c6e5 Security`SSLHandshakeProceed(ctx=0x00007fdbd6407d90) at sslTransport.c:508
frame #45: 0x00007ffff783cfcb Security`SSLHandshake(ctx=0x00007fdbd6407d90) at sslTransport.c:430
frame #46: 0x00007ffff7f85d72 libcurl.4.dylib`darwinssl_connect_step2(conn=0x00007fdbc6804800, sockindex=0) at darwinssl.c:1828
frame #47: 0x00007ffff7f83f29 libcurl.4.dylib`darwinssl_connect_common(conn=0x00007fdbc6804800, sockindex=0, nonblocking=true, done=0x00007fffffdfe87d) at darwinssl.c:2156
frame #48: 0x00007ffff7f83c48 libcurl.4.dylib`Curl_darwinssl_connect_nonblocking(conn=0x00007fdbc6804800, sockindex=0, done=0x00007fffffdfe87d) at darwinssl.c:2192
frame #49: 0x00007ffff7f82ace libcurl.4.dylib`Curl_ssl_connect_nonblocking(conn=0x00007fdbc6804800, sockindex=0, done=0x00007fffffdfe87d) at vtls.c:322
frame #50: 0x00007ffff7f40084 libcurl.4.dylib`https_connecting(conn=0x00007fdbc6804800, done=0x00007fffffdfe87d) at http.c:1403
frame #51: 0x00007ffff7f7b9d8 libcurl.4.dylib`Curl_protocol_connecting(conn=0x00007fdbc6804800, done=0x00007fffffdfe87d) at url.c:3537
frame #52: 0x00007ffff7f520e0 libcurl.4.dylib`multi_runsingle(multi=0x00007fdbd6405d10, now=(tv_sec = 1583943185, tv_usec = 59360), data=0x00007fdbc6809800) at multi.c:1251
frame #53: 0x00007ffff7f516a2 libcurl.4.dylib`curl_multi_perform(multi_handle=0x00007fdbd6405d10, running_handles=0x00007fffffdfe978) at multi.c:1788
frame #54: 0x00007ffff7f2948f libcurl.4.dylib`easy_transfer(multi=0x00007fdbd6405d10) at easy.c:715
frame #55: 0x00007ffff7f28901 libcurl.4.dylib`easy_perform(data=0x00007fdbc6809800, events=false) at easy.c:803
frame #56: 0x00007ffff7f287aa libcurl.4.dylib`curl_easy_perform(easy=0x00007fdbc6809800) at easy.c:822
frame #57: 0x00007ffff7fd930d curl`operate_do(global=0x00007fffffdff0b8, config=0x00007fdbd6405070) at tool_operate.c:1400
frame #58: 0x00007ffff7fd3be1 curl`operate(config=0x00007fffffdff0b8, argc=2, argv=0x00007fffffdff150) at tool_operate.c:1881
frame #59: 0x00007ffff7fd2eb4 curl`main(argc=2, argv=0x00007fffffdff150) at tool_main.c:252
frame #60: 0x00007ffff7fc92b4 curl`start + 52
(lldb) f 4
frame #4: 0x00007ffff789c5fc Security`Security::MachPlusPlus::Bootstrap::lookup2(this=0x00007fffffdfc4e0, name="com.apple.SecurityServer") const at mach++.cpp:250
(lldb) p nameBuffer
(char [128]) $0 = "com.apple.SecurityServer"
Key lines:
frame #3: 0x00007ffff5312206 liblaunch.dylib`bootstrap_look_up2(bp=2055, service_name=0x0000000000000000, sp=0x00007fffffdfc48c, target_pid=0, flags=8) at libbootstrap.c:191
frame #4: 0x00007ffff789c5fc Security`Security::MachPlusPlus::Bootstrap::lookup2(this=0x00007fffffdfc4e0, name="com.apple.SecurityServer") const at mach++.cpp:250
mach++.cppmach_port_t Bootstrap::lookup2(const char *name) const
{
mach_port_t port;
check(::bootstrap_look_up2(mPort, makeName(name), &port, 0, BOOTSTRAP_PRIVILEGED_SERVER));
return port;
}
mach++.hpp char *makeName(const char *s) const
{ return strncpy(nameBuffer, s, BOOTSTRAP_MAX_NAME_LEN); }
libbootstrap.ckern_return_t
bootstrap_look_up2(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, uint64_t flags)
{
uuid_t instance_id;
return bootstrap_look_up3(bp, service_name, sp, target_pid, instance_id, flags);
}
We can see that Bootstrap::lookup2 is receiving "com.apple.SecurityServer" for name, so we're good up to there. Then it passes the name to Bootstrap::makeName which in turn uses strncpy to copy the name into nameBuffer and return the result of strncpy. Something happens inside strncpy that causes it to return NULL, because the argument to bootstrap_look_up2 that makeName was used for (service_name) is NULL (0x0000000000000000).
And yet, strncpy is doing its job. As @bugaevc pointed out, if we inspect nameBuffer after the segfault, we can see that it does in fact contain the service name ("com.apple.SecurityServer"):
(lldb) f 4
frame #4: 0x00007ffff789c5fc Security`Security::MachPlusPlus::Bootstrap::lookup2(this=0x00007fffffdfc4e0, name="com.apple.SecurityServer") const at mach++.cpp:250
(lldb) p nameBuffer
(char [128]) $0 = "com.apple.SecurityServer"
So, strncpy is working as intended, except that it returns NULL, for some reason.
The next logical step in investigating this would be to set up a breakpoint in mach++.h when strncpy is called and step into it and see what's going on. It would probably also be a good idea to see if this issue occurs with any other uses of strncpy.
Not sure if strncpy() actually returns NULL or its return value is somehow improperly passed to liblaunch. If only LLDB wasn't as buggy when stepping... @LubosD
Upon further debugging, it appears that the problem lies with makeName:
(lldb) settings set target.source-map "/home/me" "/Users/me/LinuxHome"
(lldb) breakpoint set --file "mach++.cpp" --line 250
Breakpoint 4: where = Security`Security::MachPlusPlus::Bootstrap::lookup2(char const*) const + 20 at mach++.cpp:250, address = 0x000000000057e5d4
(lldb) run
Process 253 launched: '/usr/bin/curl' (x86_64)
struct ccrng_state *ccDRBGGetRngState(int *) just putting this here until we build CommonCrypto
struct ccrng_state *ccDRBGGetRngState(int *) just putting this here until we build CommonCrypto
Process 253 stopped
* thread #1, name = 'curl', stop reason = breakpoint 4.1
frame #0: 0x00007ffff789c5d4 Security`Security::MachPlusPlus::Bootstrap::lookup2(this=0x00007fffffdfc4e0, name="com.apple.SecurityServer") const at mach++.cpp:250
247 mach_port_t Bootstrap::lookup2(const char *name) const
248 {
249 mach_port_t port;
-> 250 check(::bootstrap_look_up2(mPort, makeName(name), &port, 0, BOOTSTRAP_PRIVILEGED_SERVER));
251 return port;
252 }
253
Target 0: (curl) stopped.
(lldb) p strncpy(nameBuffer, name, BOOTSTRAP_MAX_NAME_LEN)
warning: could not find Objective-C class data in the process. This may reduce the quality of type information available.
error: use of undeclared identifier 'BOOTSTRAP_MAX_NAME_LEN'
(lldb) p strncpy(nameBuffer, name, 128)
error: 'strncpy' has unknown return type; cast the call to its declared return type
(lldb) p (const char*)strncpy(nameBuffer, name, 128)
(const char *) $0 = 0x00007fffffdfc4e4 "com.apple.SecurityServer"
(lldb) p makeName(name)
(char *) $1 = 0x0000000000000000 <no value available>
(lldb) p nameBuffer
(char [128]) $2 = "com.apple.SecurityServer"
(lldb) p &nameBuffer
(char (*)[128]) $3 = 0x00007fffffdfc4e4
This shows that strncpy is in fact returning the proper value, but somehow makeName isn't.
The problem is definitely in makeName, and it makes no sense.
A simple modification shown in the patch below causes it to function correctly: just return nameBuffer directly instead of returning the result of strncpy. This simple workaround causes it to function as expected: it returns nameBuffer, not a NULL pointer.
diff --git OSX/libsecurity_utilities/lib/mach++.h OSX/libsecurity_utilities/lib/mach++.h
index 8423676..08cb95b 100644
--- OSX/libsecurity_utilities/lib/mach++.h
+++ OSX/libsecurity_utilities/lib/mach++.h
@@ -192,7 +192,7 @@ private:
protected:
char *makeName(const char *s) const
- { return strncpy(nameBuffer, s, BOOTSTRAP_MAX_NAME_LEN); }
+ { strncpy(nameBuffer, s, BOOTSTRAP_MAX_NAME_LEN); return nameBuffer; }
};
With this patch applied, cURL now functions as expected:
Darling [/Volumes/SystemRoot/home/me/git/darling/build]$ curl https://www.apple.com
struct ccrng_state *ccDRBGGetRngState(int *) just putting this here until we build CommonCrypto
struct ccrng_state *ccDRBGGetRngState(int *) just putting this here until we build CommonCrypto
DARLING CRYPTO IMPL: void ccrsa_init_pub(ccrsa_pub_ctx_t, const cc_unit *, const cc_unit *)
DARLING CRYPTO IMPL: int ccrsa_verify_pkcs1v15(ccrsa_pub_ctx_t, const uint8_t *, size_t, const uint8_t *, size_t, const uint8_t *, _Bool *)
oid: 6
lengths: digest: 32, signature: 256
mod size: 33
DARLING CRYPTO IMPL: void cczp_init(cczp_t)
DARLING CRYPTO IMPL: void cczp_power(cczp_const_t, cc_unit *, const cc_unit *, const cc_unit *)
DARLING CRYPTO IMPL: void cczp_mod(cczp_const_t, cc_unit *, const cc_unit *, cc_ws_t)
we get here
curl: (35) Unknown SSL protocol error in connection to www.apple.com:32767
I've opened a PR with this fix in darlinghq/darling-security#1, but I personally don't feel comfortable not knowing why perfectly valid code doesn't work as it should. :tada: but at the same time :confused:.
Hold on; before we apply the workaround, let's try to figure out why this happens. What assembly code is makeName() compiled to? Is this reproducible on a simpler example, without all of Security?
What assembly code is
makeName()compiled to?
(lldb) disas -n Security::MachPlusPlus::Bootstrap::makeName
Security`Security::MachPlusPlus::Bootstrap::makeName:
0x7ffff789d580 <+0>: pushq %rbp
0x7ffff789d581 <+1>: movq %rsp, %rbp
0x7ffff789d584 <+4>: subq $0x10, %rsp
0x7ffff789d588 <+8>: movq %rdi, -0x8(%rbp)
0x7ffff789d58c <+12>: movq %rsi, -0x10(%rbp)
0x7ffff789d590 <+16>: movq -0x8(%rbp), %rax
0x7ffff789d594 <+20>: addq $0x4, %rax
0x7ffff789d59a <+26>: movq -0x10(%rbp), %rsi
0x7ffff789d59e <+30>: movq %rax, %rdi
0x7ffff789d5a1 <+33>: movl $0x80, %edx
0x7ffff789d5a6 <+38>: callq 0x7ffff78e1442 ; symbol stub for: strncpy
0x7ffff789d5ab <+43>: addq $0x10, %rsp
0x7ffff789d5af <+47>: popq %rbp
0x7ffff789d5b0 <+48>: retq
Looks fine to me. Here's how strncpy() looks though:
libsystem_c.dylib`strncpy:
0x7ffff58cb2a0 <+0>: movq %rdi, %r8
<snip>
0x7ffff58cb37f <+223>: subq $0x8, %rsp
0x7ffff58cb383 <+227>: callq 0x7ffff58d95ec ; symbol stub for: bzero
0x7ffff58cb388 <+232>: addq $0x8, %rsp
0x7ffff58cb38c <+236>: movq %r8, %rax
0x7ffff58cb38f <+239>: retq
I can confirm that right before bzero call, r8 holds the right address, and right after it it's reset to 0. According to x86-64 calling convention, r8 is caller-saved, so it's fine that bzero overwrites it; it's not fine that strncpy doesn't save it. A compiler bug?
And here's a much simpler way to reproduce it:
#include <string.h>
#include <stdio.h>
int main() {
char buffer[8];
char *(*real_strncpy)(char *dest, const char *src, size_t len) = strncpy;
char *ptr = real_strncpy(buffer, "test", sizeof(buffer));
printf("%p\n", ptr);
}
(the pointer trick is to workaround Clang replacing strncpy() call with __strncpy_chk(), which doesn't exhibit the issue)
Darling [/tmp]$ clang test-strncpy.c -o test-strncpy
Darling [/tmp]$ ./test-strncpy
0x0
It seems the actual source for strncpy() we get is this hand-written assembly file: https://github.com/darlinghq/darling/blob/master/src/libc/x86_64/string/strncpy.S
And looking at the latest libc from Apple, this file is not there.
Huh, interesting. I can confirm that modifying file to:
diff --git src/libc/x86_64/string/strncpy.S src/libc/x86_64/string/strncpy.S
index f18ca345..8d9eb888 100644
--- src/libc/x86_64/string/strncpy.S
+++ src/libc/x86_64/string/strncpy.S
@@ -49,7 +49,7 @@
.align 4
_strncpy: // char *strncpy(const char *dst, const char *src, size_t n);
- movq %rdi,%r8 // preserve destination pointer so we can return it
+ pushq %rdi // preserve destination pointer so we can return it
movl %edi,%ecx // copy low 4 bytes of dest ptr
negl %ecx
andl $15,%ecx // how many bytes to align dest ptr?
@@ -179,5 +179,5 @@ LZeroBuffer:
addq $8,%rsp // restore stack
LDone:
- movq %r8,%rax // original dest ptr is return value
+ popq %rax // original dest ptr is return value
ret
...fixes the issue. I can also confirm that removing the file altogether (and modifying the CMakeLists appropriately to use the C version) also eliminates the issue.
If I had to guess, I'd say that in my testing, p strncpy(...) makes LLDB call its own version of strncpy, which is why it was working correctly, while p makeName(...) was still calling the broken version of strncpy.
This definitely feels like a real fix :tada:. How do you want to implement the fix, though? Remove the custom assembly file to keep on par with Apple's libc or just fix the assembly file?
How do you want to implement the fix, though? Remove the custom assembly file to keep on par with Apple's libc or just fix the assembly file?
I'd wait for @LubosD to return and ask him to update our libc :smile:, which would eliminate that file as a side effect.
It seems that bzero clobbers r8 now but at the time the assembly was written it wasn't clobbering r8. Either push %r8; call _bzero; pop %rax or push %rdi at the beginning of the function and pop %rax at the end work. I suggest the former as it serves the purpose of both aligning the stack and saving/moving the value.
Depending on how good the C implementation is it might be better to just use the assembly one. They look similar to me but I can't be sure.
I chose the push/pop approach, because I don't feel like updating libc right now.
Most helpful comment
I'd wait for @LubosD to return and ask him to update our libc :smile:, which would eliminate that file as a side effect.