hotfuzz icon indicating copy to clipboard operation
hotfuzz copied to clipboard

Segfault in c module on invalid characters with consult-buffer

Open Alan-Chen99 opened this issue 1 year ago • 4 comments

Consult apparently tags strings with invalid character; see https://www.reddit.com/r/emacs/comments/n43mdo/problem_with_narrowing_minibuffer_items_with/

Minimal example: (hotfuzz--filter-c "tet" (list (concat "test" (char-to-string #x200000))))

Alan-Chen99 avatar Mar 18 '23 14:03 Alan-Chen99

Thanks for reporting this issue. It is caused by the code not handling errors raised by copy_string_contents due to strings not being representable as valid UTF-8. This should of course be fixed, but the larger issue is that there is no way at all for dynamic modules to access non-UTF-8 Emacs Lisp string values.

axelf4 avatar Mar 19 '23 15:03 axelf4

I am now using this code:


(defadvice! hotfuzz--filter-c-simple-string (orig-fun string candidates &optional ignore-case)
    :around #'hotfuzz--filter-c
    (with-demoted-errors "Error in hotfuzz--filter-c-simple-string: %S"
        (let*
            (
                (table (make-hash-table :test #'eq :size (length candidates)))
                (cands
                    (--keep
                        (when (stringp it)
                            (let ((encoded (encode-coding-string it 'no-conversion 'nocopy)))
                                (setf (gethash encoded table) it)
                                (and (< (length encoded) hotfuzz--max-haystack-len) encoded)))
                        candidates))
                (raw-str (encode-coding-string string 'no-conversion 'nocopy))
                (ans
                    (let
                        (
                            (gc-cons-threshold most-positive-fixnum)
                            (gc-cons-percentage 1.0))
                        (funcall orig-fun raw-str cands ignore-case))))
            (--keep (gethash it table) ans))))
(defadvice! hotfuzz-filter-advice (string _candidates)
    :before-while #'hotfuzz-filter
    (and
        (not (string= string ""))
        (< (length (encode-coding-string string 'no-conversion 'nocopy)) hotfuzz--max-needle-len)))

Nonetheless, I get segfaults every so often. ASAN has this to say:

=================================================================
==291197==ERROR: AddressSanitizer: requested allocation size 0x7ffebec61f28 (0x7ffebec62f28 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T0)
    #0 0x7f4f0aa23867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x7f4efb9d3acb in bump_alloc /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:155
    #2 0x7f4efb9d3acb in copy_emacs_string /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:185
    #3 0x7f4efb9d4b35 in hotfuzz_filter /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:288
    #4 0x55fed5e6d459 in funcall_module ../../emacs_src/src/emacs-module.c:1183
    #5 0x55fed5e30d86 in Ffuncall ../../emacs_src/src/eval.c:2995

==291197==HINT: if you don't care about these errors you may set allocator_may_return_null=1
SUMMARY: AddressSanitizer: allocation-size-too-big ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145 in __interceptor_malloc
==291197==ABORTING

Miraculously I have yet to get a segfault/error under ASAN + allocator_may_return_null=1

Alan-Chen99 avatar Apr 09 '23 13:04 Alan-Chen99

if this helps

(gdb) frame 13
#13 copy_emacs_string (env=0x7fffffffad60, bump=0x7fffffffabb0, value=<optimized out>)
    at /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:185
185             if (!(result = bump_alloc(bump, sizeof *result + len
(gdb) print **bump
$1 = {next = 0x62d001220400, index = 6984, capacity = 65536, b = 0x63100170c818 "\230\032&\002\020b"}
(gdb) print len
$2 = <optimized out>
(gdb) print value
$3 = <optimized out>
(gdb) frame 14
#14 0x00007fffe84e4b36 in hotfuzz_filter (env=0x7fffffffad60, nargs=<optimized out>, args=<optimized out>, data_ptr=<optimized out>)
    at /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:288
288                     if (!(b->xs[b->len++].s = copy_emacs_string(env, &bump, value)))
(gdb) print value
$4 = <optimized out>
(gdb) print list
$5 = (emacs_value) 0x6210022601b8
(gdb) print env->is_not_nil(env, list)
$6 = false

Alan-Chen99 avatar Apr 09 '23 14:04 Alan-Chen99

See also #12 and #13

minad avatar Jul 01 '23 07:07 minad

This should now be fixed by commits f91c0972cc8887f8e2a123feb96bb5120d2b77c3 and 622329477d893a9fc2528a75935cfe1f8614f4bc.

axelf4 avatar Apr 21 '24 08:04 axelf4