CFURLCopyResourcePropertiesForKeys with kCFURLIsExcludedFromBackupKey (or CSBackupIsItemExcluded) on relative path overreleases
| Originator: | nriley | ||
| Number: | rdar://15772932 | Date Originated: | 08-Jan-2014 12:26 PM |
| Status: | Open | Resolved: | |
| Product: | OS X | Product Version: | 10.9.1/13B42 |
| Classification: | Crash/Hang/Data Loss | Reproducible: | Always |
Summary:
In CFURLCopyResourcePropertiesForKeys, if the key kCFURLIsExcludedFromBackupKey is provided and the CFURLRef encodes a relative path, the CFURLRef's embedded NSString is released, which may trigger a crash later in the program.
Steps to Reproduce:
Compile and run the attached source file as follows:
% clang -framework CoreFoundation -o sample sample.c
% ./sample sample.c
Expected Results:
The URL's string's retain count is the same before and after the call to CFURLCopyResourcePropertiesForKeys.
before - URL retain count: 1; string retain count: 1
[...]
after - URL retain count: 1; string retain count: 1
Actual Results:
The URL's string is released by CFURLCopyResourcePropertiesForKeys:
before - URL retain count: 1; string retain count: 1
[...]
after - URL retain count: 1; string retain count: 1152921504606846975
Version:
10.9.1/13B42
Notes:
Workaround: Explicitly retain the CFURLRef's string, e.g. CFRetain(CFURLGetString(url));
Configuration:
This problem exists on OS X 10.9.1 and OS X 10.8.5 in both 32 and 64-bit.
It does not occur if you pass an absolute path to CFStringCreateWithFileSystemRepresentation.
It does not occur if you supply other keys with CFURLCopyResourcePropertiesForKeys. That is, any combination of keys which includes kCFURLIsExcludedFromBackupKey has triggered the problem.
[Attached file is uploaded to <http://sabi.net/temp/15772932.c>.]
Update:
If you pass a relative path to an item within a package, even the workaround described in my initial report does not work, and the application crashes.
The issue is actually in CSBackupIsItemExcluded.
See the attachment 'excluded.c'; compile with 'clang -framework CoreServices -o excluded excluded.c'.
% cd /Applications
% /path/to/excluded Safari.app
<CFURL 0x7fdd4bc08120 [0x7fff71428110]>{string = Safari.app, encoding = 134217984
base = <CFURL 0x7fdd4bc080b0 [0x7fff71428110]>{string = file://localhost/Applications/, encoding = 134217984, base = (null)}}
before - URL retain count: 2; string retain count: 2
after - URL retain count: 2; string retain count: 1
But even overretaining the URL and its string when passing a relative path to an item within a package, another CFURL's embedded CFString is overreleased:
% NSZombieEnabled=YES lldb -- /path/to/excluded Safari.app/Contents
Current executable set to '/path/to/excluded' (x86_64).
(lldb) run
Process 83022 launched: '/path/to/excluded' (x86_64)
<CFURL 0x10010a3b0 [0x7fff71428110]>{string = Safari.app/Contents, encoding = 134217984
base = <CFURL 0x1001080d0 [0x7fff71428110]>{string = file://localhost/Applications/, encoding = 134217984, base = (null)}}
before - URL retain count: 2; string retain count: 2
2014-01-25 11:05:28.436 excluded[83022:f0b] *** -[CFString release]: message sent to deallocated instance 0x10030a870
Process 83022 stopped
* thread #1: tid = 0x1c03, 0x00007fff86381f2e CoreFoundation`___forwarding___ + 158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x00007fff86381f2e CoreFoundation`___forwarding___ + 158
CoreFoundation`___forwarding___ + 158:
-> 0x7fff86381f2e: callq 0x7fff8647c780 ; symbol stub for: getpid
0x7fff86381f33: movl %eax, %edi
0x7fff86381f35: movl $9, %esi
0x7fff86381f3a: callq 0x7fff8647c7d4 ; symbol stub for: kill
(lldb) bt
* thread #1: tid = 0x1c03, 0x00007fff86381f2e CoreFoundation`___forwarding___ + 158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x00007fff86381f2e CoreFoundation`___forwarding___ + 158
frame #1: 0x00007fff86381e18 CoreFoundation`_CF_forwarding_prep_0 + 232
frame #2: 0x00007fff8630928a CoreFoundation`CFRelease + 170
frame #3: 0x00007fff86311313 CoreFoundation`__CFURLDeallocate + 35
frame #4: 0x00007fff863093df CoreFoundation`CFRelease + 511
frame #5: 0x00007fff87bea9d3 CarbonCore`CSBackupIsItemExcluded + 887
frame #6: 0x0000000100000e24 excluded`main + 212
frame #7: 0x00007fff8a7b67e1 libdyld.dylib`start + 1
Again, if you use absolute paths, there are no problems in either scenario.
[Attached file is uploaded to <http://sabi.net/temp/15772932-excluded.c>.]
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!