[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#40555: 27.0.90; out of bound array access in setup_process_coding_sy
From: |
Matthieu Hauglustaine |
Subject: |
bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems |
Date: |
Sat, 11 Apr 2020 17:24:16 +0200 |
Hello,
I've experienced a EXC_BAD_ACCESS when using Emacs 27.0.90 on OS X
10.15.
The root cause appears to be an out of bound access on
proc_decode_coding_system (src/process.c:7988), in
setup_process_coding_systems() when calling setup_coding_system(). This
results in an invalid write to coding->id from
CHECK_CODING_SYSTEM_GET_ID (src/coding.c:5678). [1] for the stacktrace.
On Emacs initialization (init_process_emacs(), src/emacs.c:8234),
RLIMIT_NOFILE.rlim_cur is set to FD_SETSIZE, and the assumption seem to
be that this limit will never change for the lifetime of the
process. proc_decode_coding_system and proc_encode_coding_system are
declared with a size of FD_SETSIZE (src/process.c:311).
However, on OS X systems, the call to NSURL.getResourceValue:forKey:
(src/nsfns.c:497), when opening a file, apparently result in a call to
setrlimit with RLIMIT_NOFILE.rlim_cur > FD_SETSIZE.
Thus, when the number of FDs opened by Emacs is greater than FD_SETSIZE,
an illegal access is done when make-process is called.
I've experienced this consistently when using lsp-mode along with
lsp-java, as by default this mode will set kqueue watches on all
directories of the workspace, which can result in a lot of open
files. Fkqueue_add_watch relies on RLIMIT_NOFILE.rlim_cur to limit the
number of watches created, and not on FD_SETSIZE
(src/kqueue.c:391). Disabling file watching works as a workaround.
To reproduce, without lsp, I have been doing the following:
1. Run Emacs with lldb:
% lldb Emacs-x86_64-10_14
(lldb) target create "Emacs-x86_64-10_14"
Current executable set to
'/Applications/Emacs.app/Contents/MacOS/Emacs-x86_64-10_14' (x86_64).
(lldb) run -Q --dump-file=/Applications/Emacs.app/Contents/MacOS/Emacs.pdmp
Process 50395 launched:
'/Applications/Emacs.app/Contents/MacOS/Emacs-x86_64-10_14' (x86_64)
2. Assert RLIMIT_NOFILE.rlim_cur is at FD_SETSIZE (1024):
(lldb) expression struct rlimit { uint64_t cur, max; } $lims
(lldb expression (void)getrlimit(8, &$lims)
(lldb) memory read &$lims -s 8 -c 2 -fu
0x100ec5190: 1024
0x100ec5198: 9223372036854775807
3. Open a file. If a breakpoint on setrlimit was set, we can see a call
is made, [2] for the stacktrace.
4. Observe RLIMIT_NOFILE.rlim_cur has been changed:
(lldb) expression (void)getrlimit(8, &$lims)
(lldb) memory read &$lims -s 8 -c 2 -fu
0x100ec5190: 3328
0x100ec5198: 9223372036854775807
5. Create > FD_SETSIZE file descriptors (I've been using
file-notify-add-watch, as lsp-mode does):
(require 'filenotify)
(dotimes (_ 1900)
(let ((dir (make-temp-file "foo" t)))
(file-notify-add-watch dir '(change) 'prin1)))
6. Assert process has > FD_SETSIZE open files:
% lsof -p 50395|wc -l
1958
7. Call make-process, resulting in SEGV:
(make-process :name "test" :buffer "test" :command '("echo" "hello"))
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=1, address=0xffffffffffffffff)
frame #0: 0x000000010007a1b5 Emacs-x86_64-10_14`setup_coding_system + 53
Emacs-x86_64-10_14`setup_coding_system:
-> 0x10007a1b5 <+53>: movq %rax, (%r15)
0x10007a1b8 <+56>: testq %rax, %rax
0x10007a1bb <+59>: jns 0x10007a1e2 ; <+98>
0x10007a1bd <+61>: movq %rbx, %rdi
I would love to help out with a patch. I'm am, however, unfamiliar with
Emacs' internals and uncertain about the best course of action.
I have the following ideas:
1. Report an error in create_process (src/process.c:2033) if in/out
channel FDs > FD_SETSIZE.
2. Use min(FD_SETSIZE, RLIMIT_NOFILE.rlim_cur) as maxfd in
Fkqueue_add_watch, src/kqueue.c:390. Although there is probably
other scenarios in which the Emacs process end up having more than
FD_SETSIZE open file descriptors?
3. Ensure RLIMIT_NOFILE.rlim_cur is at FD_SETSIZE periodically, in case
some subroutine we don't know about changed it (where could that
happen? Should it be in command_loop, src/keyboard.c:1042?).
Thanks,
Matthieu
In GNU Emacs 27.0.90 (build 1, x86_64-apple-darwin18.7.0, NS appkit-1671.60
Version 10.14.6 (Build 18G95))
of 2020-03-03 built on builder10-14.porkrind.org
Windowing system distributor 'Apple', version 10.3.1894
System Description: Mac OS X 10.15.3
Configured using:
'configure --with-ns '--enable-locallisppath=/Library/Application
Support/Emacs/${version}/site-lisp:/Library/Application
Support/Emacs/site-lisp' --with-modules'
Configured features:
NOTIFY KQUEUE ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES
THREADS PDUMPER
Important settings:
value of $LANG: en_FR.UTF-8
locale-coding-system: utf-8
[1] Stacktrace, disassembled code and registers on EXC_BAD_ACCESS
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=EXC_I386_GPFLT)
frame #0: 0x000000010007a1b5 Emacs-x86_64-10_14`setup_coding_system + 53
* frame #1: 0x00000001001916c8
Emacs-x86_64-10_14`setup_process_coding_systems + 152
frame #2: 0x0000000100193752 Emacs-x86_64-10_14`create_process + 546
frame #3: 0x0000000100192dcf Emacs-x86_64-10_14`Fmake_process + 2767
frame #4: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #5: 0x000000010014b07c Emacs-x86_64-10_14`Fapply + 588
frame #6: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #7: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #8: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #9: 0x000000010014b07c Emacs-x86_64-10_14`Fapply + 588
frame #10: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #11: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #12: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #13: 0x000000010014b07c Emacs-x86_64-10_14`Fapply + 588
frame #14: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #15: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #16: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #17: 0x000000010014b07c Emacs-x86_64-10_14`Fapply + 588
frame #18: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #19: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #20: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #21: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #22: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #23: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #24: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #25: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #26: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #27: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #28: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #29: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #30: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #31: 0x000000010014c355 Emacs-x86_64-10_14`funcall_lambda + 773
frame #32: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #33: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #34: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #35: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #36: 0x0000000100144b19 Emacs-x86_64-10_14`Ffuncall_interactively
+ 73
frame #37: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #38: 0x0000000100146008 Emacs-x86_64-10_14`Fcall_interactively +
5336
frame #39: 0x000000010014bf61 Emacs-x86_64-10_14`funcall_subr + 289
frame #40: 0x000000010014b52b Emacs-x86_64-10_14`Ffuncall + 843
frame #41: 0x000000010018ea47 Emacs-x86_64-10_14`exec_byte_code + 1815
frame #42: 0x000000010014b4c9 Emacs-x86_64-10_14`Ffuncall + 745
frame #43: 0x000000010014bb9c Emacs-x86_64-10_14`call1 + 44
frame #44: 0x00000001000c3249 Emacs-x86_64-10_14`command_loop_1 + 2009
frame #45: 0x0000000100149b87
Emacs-x86_64-10_14`internal_condition_case + 263
frame #46: 0x00000001000d3120 Emacs-x86_64-10_14`command_loop_2 + 48
frame #47: 0x00000001001493ab Emacs-x86_64-10_14`internal_catch + 267
frame #48: 0x0000000100215385 Emacs-x86_64-10_14`command_loop.cold.1 +
69
frame #49: 0x00000001000c2073 Emacs-x86_64-10_14`command_loop + 131
frame #50: 0x00000001000c1fa3 Emacs-x86_64-10_14`recursive_edit_1 + 115
frame #51: 0x00000001000c21fb Emacs-x86_64-10_14`Frecursive_edit + 347
frame #52: 0x00000001000c0dd7 Emacs-x86_64-10_14`main + 7431
frame #53: 0x00007fff6c9c97fd libdyld.dylib`start + 1
frame #54: 0x00007fff6c9c97fd libdyld.dylib`start + 1
Emacs-x86_64-10_14`setup_coding_system:
-> 0x10007a1b5 <+53>: movq %rax, (%r15)
0x10007a1b8 <+56>: testq %rax, %rax
0x10007a1bb <+59>: jns 0x10007a1e2 ; <+98>
0x10007a1bd <+61>: movq %rbx, %rdi
General Purpose Registers:
rax = 0x0000000000000022
rbx = 0x000000000000d0b0
rcx = 0x0000000000000220
rdx = 0x00000000000004bf
rdi = 0x000000000000d0b0
rsi = 0x000000000000d0b0
rbp = 0x00007ffeefbfe5d0
rsp = 0x00007ffeefbfe5a0
r8 = 0x0000000103b235b4
r9 = 0x00007ffeefbfe687
r10 = 0x0000000000000018
r11 = 0x0000000000000202
r12 = 0x0000000100679c40 Emacs-x86_64-10_14`proc_decode_coding_system
r13 = 0x00007ffeefbfe601
r14 = 0x000000010067e698 Emacs-x86_64-10_14`Vcoding_system_hash_table
r15 = 0xffffffffffffffff
rip = 0x000000010007a1b5 Emacs-x86_64-10_14`setup_coding_system + 53
rflags = 0x0000000000010246
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
[2] Stacktrace of call to setrlimit resulting in RLIMIT_NOFILE.rlim_cur
greater than FD_SETSIZE
* thread #1, queue = 'com.apple.clouddocs.xpc', stop reason = breakpoint 1.1
* frame #0: 0x00007fff6cb0c4cd libsystem_kernel.dylib`setrlimit
frame #1: 0x00007fff37b22162 Foundation`+[NSFileHandle initialize] + 200
frame #2: 0x00007fff6b65d985
libobjc.A.dylib`CALLING_SOME_+initialize_METHOD + 17
frame #3: 0x00007fff6b65e2bc libobjc.A.dylib`initializeNonMetaClass +
638
frame #4: 0x00007fff6b65e991
libobjc.A.dylib`initializeAndMaybeRelock(objc_class*, objc_object*,
mutex_tt<false>&, bool) + 214
frame #5: 0x00007fff6b6503db libobjc.A.dylib`lookUpImpOrForward + 969
frame #6: 0x00007fff6b64fb99 libobjc.A.dylib`_objc_msgSend_uncached + 73
frame #7: 0x00007fff3549e353 CoreFoundation`-[__NSSetI containsObject:]
+ 156
frame #8: 0x00007fff37b1ab04
Foundation`setProtocolMetadataWithSignature + 416
frame #9: 0x00007fff37b1a8ad Foundation`setProtocolMetdataWithMethods +
699
frame #10: 0x00007fff37b1a571 Foundation`setProtocolMetadata + 214
frame #11: 0x00007fff37b1a40e Foundation`-[NSXPCInterface setProtocol:]
+ 299
frame #12: 0x00007fff4acee054 CloudDocs`__BRCXPCInterface_block_invoke
+ 101
frame #13: 0x00007fff6c97050e
libdispatch.dylib`_dispatch_client_callout + 8
frame #14: 0x00007fff6c971686 libdispatch.dylib`_dispatch_once_callout
+ 20
frame #15: 0x00007fff4acedfec CloudDocs`BRCXPCInterface + 45
frame #16: 0x00007fff4aceca41 CloudDocs`-[BRDaemonConnection
_setupAndResume] + 111
frame #17: 0x00007fff4acedf9b CloudDocs`-[BRDaemonConnection
initUsingUserLocalDaemon] + 104
frame #18: 0x00007fff4acedef7 CloudDocs`__39+[BRDaemonConnection
defaultConnection]_block_invoke + 83
frame #19: 0x00007fff6c97050e
libdispatch.dylib`_dispatch_client_callout + 8
frame #20: 0x00007fff6c97c567
libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 60
frame #21: 0x00007fff4acede6c CloudDocs`+[BRDaemonConnection
defaultConnection] + 136
frame #22: 0x00007fff4acfbf05 CloudDocs`-[BRFrameworkSyncedRootURLCache
_fetchSyncedRootURLs] + 45
frame #23: 0x00007fff4acfbeb9
CloudDocs`__47-[BRFrameworkSyncedRootURLCache syncedRootURLs]_block_invoke + 35
frame #24: 0x00007fff6c97050e
libdispatch.dylib`_dispatch_client_callout + 8
frame #25: 0x00007fff6c97c567
libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 60
frame #26: 0x00007fff4acfbe5e CloudDocs`-[BRFrameworkSyncedRootURLCache
syncedRootURLs] + 140
frame #27: 0x00007fff4acf2d55 CloudDocs`-[NSURL(BRAdditions)
_br_isInSyncedLocationStrictly:] + 135
frame #28: 0x0000000100ec5eaa
CloudDocsFileProvider`___lldb_unnamed_symbol13$$CloudDocsFileProvider + 81
frame #29: 0x00007fff3549ffec CoreFoundation`__invoking___ + 140
frame #30: 0x00007fff3549fe83 CoreFoundation`-[NSInvocation invoke] +
305
frame #31: 0x00007fff354d3d7e CoreFoundation`-[NSInvocation
invokeWithTarget:] + 70
frame #32: 0x00007fff379c3f82
FileProvider`-[FPFrameworkOverridesIterator callNextOverrides] + 556
frame #33: 0x00007fff379c3ced
FileProvider`-[FPFrameworkOverridesIterator forwardInvocation:] + 81
frame #34: 0x00007fff3549e889 CoreFoundation`___forwarding___ + 829
frame #35: 0x00007fff3549e4b8 CoreFoundation`_CF_forwarding_prep_0 + 120
frame #36: 0x00007fff379c2e23
FileProvider`FPCFCopyAttributeValuesForItem + 292
frame #37: 0x00007fff4de231ad
CoreServicesInternal`CopyFromFileProvider(__CFURL const*, void const*, void
const**, __CFError**) + 70
frame #38: 0x00007fff4de230d6
CoreServicesInternal`ExternalProviderPrepareValues(__CFURL const*,
__FileCache*, __CFString const* const*, void const**, long, void const*,
__CFError**) + 358
frame #39: 0x00007fff4de087e4
CoreServicesInternal`prepareValuesForBitmap(__CFURL const*, __FileCache*,
_FilePropertyBitmap*, __CFError**) + 363
frame #40: 0x00007fff4de04eba
CoreServicesInternal`_FSURLCopyResourcePropertyForKeyInternal(__CFURL const*,
__CFString const*, void*, void*, __CFError**, unsigned char) + 221
frame #41: 0x00007fff35491958
CoreFoundation`CFURLCopyResourcePropertyForKey + 119
frame #42: 0x00007fff354a84ff CoreFoundation`-[NSURL
getResourceValue:forKey:error:] + 110
frame #43: 0x00000001001f0dcf Emacs-x86_64-10_14`ns_implicitly_set_name
+ 287
frame #44: 0x0000000100053531
Emacs-x86_64-10_14`gui_consider_frame_title + 609
frame #45: 0x00000001000289fc Emacs-x86_64-10_14`redisplay_internal +
1324
frame #46: 0x00000001000c6be5 Emacs-x86_64-10_14`read_char + 2213
frame #47: 0x00000001000c47aa Emacs-x86_64-10_14`read_key_sequence +
1722
frame #48: 0x00000001000c2fac Emacs-x86_64-10_14`command_loop_1 + 1340
frame #49: 0x0000000100149b87
Emacs-x86_64-10_14`internal_condition_case + 263
frame #50: 0x00000001000d3120 Emacs-x86_64-10_14`command_loop_2 + 48
frame #51: 0x00000001001493ab Emacs-x86_64-10_14`internal_catch + 267
frame #52: 0x0000000100215385 Emacs-x86_64-10_14`command_loop.cold.1 +
69
frame #53: 0x00000001000c2073 Emacs-x86_64-10_14`command_loop + 131
frame #54: 0x00000001000c1fa3 Emacs-x86_64-10_14`recursive_edit_1 + 115
frame #55: 0x00000001000c21fb Emacs-x86_64-10_14`Frecursive_edit + 347
frame #56: 0x00000001000c0dd7 Emacs-x86_64-10_14`main + 7431
frame #57: 0x00007fff6c9c97fd libdyld.dylib`start + 1
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems,
Matthieu Hauglustaine <=
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems, Eli Zaretskii, 2020/04/11
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems, Matthieu Hauglustaine, 2020/04/11
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems, Robert Pluim, 2020/04/14
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems, Eli Zaretskii, 2020/04/14
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems, Robert Pluim, 2020/04/15
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems, Eli Zaretskii, 2020/04/15
- bug#40555: 27.0.90; out of bound array access in setup_process_coding_systems, Robert Pluim, 2020/04/15