bugGNU nano - Bugs: bug #64465, segfault when the folder...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #64465: segfault when the folder disappears during a call of `read_the_list()`

Submitter:  Jerry Meng <jerrymeng>
Submitted:  Mon 24 Jul 2023 05:32:16 AM UTC
   
 
Severity:  4 - Important Status:  Fixed
Assigned to:  bens Open/Closed:  Open

Mon 31 Jul 2023 05:28:30 AM UTC, comment #2: 

Fixed in git, commit d3dd403d, by not trying to do anything with the produced list when it is empty.

Benno Schulenberg <bens>
Group administrator
Mon 24 Jul 2023 01:32:01 PM UTC, comment #1: 

Thanks for the detailed bug report, and especially for the perfect reproduction recipe!

Attached patch should avoid the crash.  When the directory disappears during the second series of readdir() calls, the error experience will be poorer, but I think it's good enough for such a rare issue.  What do you think?

(file #54959)

Benno Schulenberg <bens>
Group administrator
Mon 24 Jul 2023 05:32:16 AM UTC, original submission:  

While running nano-6.2 in Ubuntu 22.04, we found one crash and its stack trace is as follows.

#0  __strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex.S:450
#1  0x0000555555585b4b in copy_of (string=0x555000257ff3 <error: Cannot access memory at address 0x555000257ff3>) at ../../src/utils.c:334
#2  0x000055555555c436 in browse (path=0x555555703940 "/tmp/TEST/") at ../../src/browser.c:687
#3  0x000055555555c666 in browse_in (inpath=0x5555557028b0 "") at ../../src/browser.c:739
#4  0x0000555555563207 in insert_a_file_or (execute=false) at ../../src/files.c:1215
#5  0x000055555556346d in do_insertfile () at ../../src/files.c:1309
#6  0x0000555555572838 in process_a_keystroke () at ../../src/nano.c:1633
#7  0x0000555555574678 in main (argc=1, argv=0x7fffffffe698) at ../../src/nano.c:2575


From the code `read_the_list()` of `browser.c`, there is (1) an iteration over the directory using readdir(), (2) a rewind using rewinddir(), and (3) a second iteration using readdir() but with no error checking. The readdir() C library call uses the getdents64() call to read the actual entries, and after the rewind, the internal buffers are flushed meaning that the syscall will be called again at (3). So, inbetween (1) and (3) it is possible for the system state to change, such as the directory deletion, which will cause the second call to getdents64() to fail.

Steps to reproduce this bug:

To ease the reproduction, we make minor modifications to the source code to construct the scenario where the system state is changed (via deleting one directory).

(1) set it up so that the directory is deleted in between the two readdir() scans:

        /* Find the width of the widest filename in the current folder. */
        while ((entry =  readdir(dir)) != NULL) {
                ...
        }
        ...
        system("rm -rf /tmp/TEST"); // <--- add this code to delete the directory here
        rewinddir(dir);
        ...
        while ((entry =  readdir(dir)) != NULL && index < list_length) {
                ...
        }


(2) build the modified nano.
(3) set up the environment:

        $ mkdir /tmp/TEST
        $ cd /tmp/TEST
        $ /path/to/modified/nano

(4) in nano:

        1. Ctl-R
        2. Ctl-T
        3. Ctl-L

Then nano will crash.

Although the PoC is modifying nano, this crash can appear in the real execution environment without modification, where the directory is deleted at precisely the right moment.

Jerry Meng <jerrymeng>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by bens (Updated the item)
  • -email is unavailable- added by jerrymeng (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-07-31 bens StatusIn Progress Fixed
        SummarySIGSEGV if the system state is changed while calling `read_the_list()` of `browser.c` . segfault when the folder disappears during a call of `read_the_list()`
    2023-07-24 bens Attached File- Added 0001-browser-report-an-error-instead-of-crashing-when-the.patch, #54959
        Severity3 - Normal 4 - Important
        StatusNone In Progress
        Assigned toNone bens

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code