** Description changed:

+ [ Impact ]
+ 
+ The Files app (nautilus) crashes when trying to open a bookmark from the
+ context menu in the Ubuntu Desktop dock.
+ 
+ [ Test Plan ]
+ 
+ 1. Open Files
+ 2. Right click on the Files icon in the dock
+ 3. Select a bookmarked location, such as "Documents"
+ 4. Verify that the Files app did not crash
+ 5. Verify that a Files window was opened in the Documents location
+ 6. Repeat 10 times from step 2 (the invalid memory usage may not always 
trigger a crash)
+ 
+ [ Where problems could occur ]
+ 
+ Problems could manifest in the Files app, default file manager and file 
picker dialog provider in Ubuntu Desktop.
+ The patch is removing a single call to decrease the ref-count of an object in 
memory; in the worst case this would cause a memory leak.
+ 
+ [ Original report, dismissed as a security issue ]
+ 
  This is a security issue in Ubuntu downstream Nautilus integration
  (unity_launcher_support.patch), specifically src/unity-bookmarks-
  handler.c in activate_bookmark_by_quicklist().
  
  The function obtains a GFile* via
  nautilus_bookmark_get_location(bookmark) and later calls
  g_object_unref(location). Under current semantics this pointer is non-
  owning, so unref is invalid and can cause premature free. Reopening the
  same bookmark from quicklist later triggers invalid object use and
  crash.
  
  Ubuntu version: 26.04 LTS
  Kernel version: 7.0.0-22-generic
  Nautilus version: 1:50.0-0ubuntu2
  
  Affected version confirmed: nautilus 1:50.0-0ubuntu2
  Type: Use-After-Free
  Impact: Local DoS (Nautilus crash) While this is a local denial of service, 
it can be triggered repeatedly by any local user without authentication, 
causing loss of work and disruption to the desktop session.
  
  Reproducer:
  
  Open Nautilus
  
  Right-click dock icon
  
  Open bookmarked folder from quicklist
  
  Close window
  
  Repeat same quicklist open
  
  Crash occurs
  
  Crash signature:
  GLib-GObject-CRITICAL: g_object_ref: assertion 'G_IS_OBJECT (object)' failed, 
followed by SIGTRAP in GLib abort path.
  
  Root cause:
  activate_bookmark_by_quicklist() does:
  location = nautilus_bookmark_get_location(bookmark);
  g_application_open(... location ...)
  g_object_unref(location) <-- invalid for current non-owning semantics
  The function nautilus_bookmark_get_location() historically may have returned 
a GFile* with full ownership (transfer-full), but in the current version it 
returns a non-owning reference (transfer-none). The code still assumes the old 
semantics and calls g_object_unref(), causing premature free.
  
  Backtrace key frames:
  g_object_ref
  begin_location_change
  nautilus_application_open_location_full
  
  source code:
  static void
  activate_bookmark_by_quicklist (DbusmenuMenuitem *menu,
-                                 guint timestamp,
-                                 NautilusBookmark *bookmark)
+                                 guint timestamp,
+                                 NautilusBookmark *bookmark)
  {
-     GFile *location;
-     NautilusApplication *application;
+     GFile *location;
+     NautilusApplication *application;
  
-     g_return_if_fail (NAUTILUS_IS_BOOKMARK (bookmark));
+     g_return_if_fail (NAUTILUS_IS_BOOKMARK (bookmark));
  
-     location = nautilus_bookmark_get_location (bookmark);
+     location = nautilus_bookmark_get_location (bookmark);
  
-     application = NAUTILUS_APPLICATION (g_application_get_default ());
+     application = NAUTILUS_APPLICATION (g_application_get_default ());
  
-     g_application_open (G_APPLICATION (application),
-                         (GFile* []) { location, NULL }, 1, "new-window");
+     g_application_open (G_APPLICATION (application),
+                         (GFile* []) { location, NULL }, 1, "new-window");
  
-     g_object_unref (location); // UAF is here!
+     g_object_unref (location); // UAF is here!
  }
- 
  
  GDB(pwndbg) message:
  (org.gnome.Nautilus:150660): GLib-GObject-CRITICAL **: 16:54:18.360: 
g_object_ref: assertion 'G_IS_OBJECT (object)' failed
  
  Thread 1 "nautilus" received signal SIGTRAP, Trace/breakpoint trap.
  _g_log_abort (breakpoint=breakpoint@entry=0x1) at 
../../../glib/gmessages.c:452
  LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
  
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 LAST SIGNAL 
]────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Breakpoint hit at 0x7ffff7c625e9
  
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 REGISTERS / show-flags off / show-compact-regs off 
]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
-  RAX  0xfffffffffffffcd0
-  RBX  1
-  RCX  0x51d1
-  RDX  0x7ffff5412ac8 (main_arena+8) —▸ 0x55555eb05d70 ◂— 0xa0
-  RDI  0x7ffff5412ac0 (main_arena) ◂— 0
-  RSI  0x5810
-  R8   1
-  R9   0xa37d68d7b79bde6c
-  R10  0
-  R11  0x297
-  R12  0x7ffff7c62d90 (g_log_default_handler) ◂— endbr64
-  R13  3
-  R14  0xa
-  R15  8
-  RBP  0x7fffffffc940 —▸ 0x7fffffffca10 —▸ 0x7fffffffcaf0 —▸ 0x7fffffffcb30 —▸ 
0x7fffffffcb80 ◂— ...
-  RSP  0x7fffffffc900 ◂— 0x62f
-  RIP  0x7ffff7c625e9 (_g_log_abort+89) ◂— mov rax, qword ptr [rbp - 0x18]
+  RAX  0xfffffffffffffcd0
+  RBX  1
+  RCX  0x51d1
+  RDX  0x7ffff5412ac8 (main_arena+8) —▸ 0x55555eb05d70 ◂— 0xa0
+  RDI  0x7ffff5412ac0 (main_arena) ◂— 0
+  RSI  0x5810
+  R8   1
+  R9   0xa37d68d7b79bde6c
+  R10  0
+  R11  0x297
+  R12  0x7ffff7c62d90 (g_log_default_handler) ◂— endbr64
+  R13  3
+  R14  0xa
+  R15  8
+  RBP  0x7fffffffc940 —▸ 0x7fffffffca10 —▸ 0x7fffffffcaf0 —▸ 0x7fffffffcb30 —▸ 
0x7fffffffcb80 ◂— ...
+  RSP  0x7fffffffc900 ◂— 0x62f
+  RIP  0x7ffff7c625e9 (_g_log_abort+89) ◂— mov rax, qword ptr [rbp - 0x18]
  
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 DISASM / x86-64 / set emulate on 
]──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
-  ► 0x7ffff7c625e9 <_g_log_abort+89>     mov    rax, qword ptr [rbp - 0x18]    
 RAX, [0x7fffffffc928] => 0x236f31748ebed500
-    0x7ffff7c625ed <_g_log_abort+93>     sub    rax, qword ptr fs:[0x28]       
 RAX => 0 (0x236f31748ebed500 - 0x236f31748ebed500)
-    0x7ffff7c625f6 <_g_log_abort+102>  ✘ jne    _g_log_abort+182            
<_g_log_abort+182>
-  
-    0x7ffff7c625f8 <_g_log_abort+104>    mov    rbx, qword ptr [rbp - 8]       
 RBX, [0x7fffffffc938] => 0x7ffff7d9b015 ◂— 'GLib-GObject'
-    0x7ffff7c625fc <_g_log_abort+108>    leave 
-    0x7ffff7c625fd <_g_log_abort+109>    ret                                
<g_logv+802>
-     ↓
-    0x7ffff7c63212 <g_logv+802>          jmp    g_logv+612                  
<g_logv+612>
-     ↓
-    0x7ffff7c63154 <g_logv+612>          mov    esi, dword ptr [rbp - 0x88]    
 ESI, [0x7fffffffc988] => 0
-    0x7ffff7c6315a <g_logv+618>          lea    rdi, [rip + 0xefbbf]           
 RDI => 0x7ffff7d52d20 (g_log_depth) ◂— 0xffffffff0000000c /* '\x0c' */
-    0x7ffff7c63161 <g_logv+625>          call   g_private_set               
<g_private_set>
-  
-    0x7ffff7c63166 <g_logv+630>          test   r13d, r13d
+  ► 0x7ffff7c625e9 <_g_log_abort+89>     mov    rax, qword ptr [rbp - 0x18]    
 RAX, [0x7fffffffc928] => 0x236f31748ebed500
+    0x7ffff7c625ed <_g_log_abort+93>     sub    rax, qword ptr fs:[0x28]       
 RAX => 0 (0x236f31748ebed500 - 0x236f31748ebed500)
+    0x7ffff7c625f6 <_g_log_abort+102>  ✘ jne    _g_log_abort+182            
<_g_log_abort+182>
+ 
+    0x7ffff7c625f8 <_g_log_abort+104>    mov    rbx, qword ptr [rbp - 8]       
 RBX, [0x7fffffffc938] => 0x7ffff7d9b015 ◂— 'GLib-GObject'
+    0x7ffff7c625fc <_g_log_abort+108>    leave
+    0x7ffff7c625fd <_g_log_abort+109>    ret                                
<g_logv+802>
+     ↓
+    0x7ffff7c63212 <g_logv+802>          jmp    g_logv+612                  
<g_logv+612>
+     ↓
+    0x7ffff7c63154 <g_logv+612>          mov    esi, dword ptr [rbp - 0x88]    
 ESI, [0x7fffffffc988] => 0
+    0x7ffff7c6315a <g_logv+618>          lea    rdi, [rip + 0xefbbf]           
 RDI => 0x7ffff7d52d20 (g_log_depth) ◂— 0xffffffff0000000c /* '\x0c' */
+    0x7ffff7c63161 <g_logv+625>          call   g_private_set               
<g_private_set>
+ 
+    0x7ffff7c63166 <g_logv+630>          test   r13d, r13d
  
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 STACK 
]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  00:0000│ rsp 0x7fffffffc900 ◂— 0x62f
  01:0008│-038 0x7fffffffc908 —▸ 0x55555db7e930 —▸ 0x7ffff5412ac8 
(main_arena+8) —▸ 0x55555eb05d70 ◂— 0xa0
  02:0010│-030 0x7fffffffc910 —▸ 0x7ffff7d2842d ◂— 'SYSLOG_IDENTIFIER'
  03:0018│-028 0x7fffffffc918 {len} ◂— 0x62f
  04:0020│-020 0x7fffffffc920 {proc_status} —▸ 0x55555db7e930 —▸ 0x7ffff5412ac8 
(main_arena+8) —▸ 0x55555eb05d70 ◂— 0xa0
  05:0028│-018 0x7fffffffc928 ◂— 0x236f31748ebed500
  06:0030│-010 0x7fffffffc930 —▸ 0x7ffff7d9b015 ◂— 'GLib-GObject'
  07:0038│-008 0x7fffffffc938 —▸ 0x7ffff7d9b015 ◂— 'GLib-GObject'
  
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 BACKTRACE 
]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
-  ► 0   0x7ffff7c625e9 _g_log_abort+89
-    1   0x7ffff7c63212 g_logv+802
-    2   0x7ffff7c634d3 g_log+147
-    3   0x7ffff7c644fd None
-    4   0x7ffff7d7732a g_object_ref+138
-    5   0x7ffff7d7732a g_object_ref+138
-    6   0x5555555eaaa3 begin_location_change+115
-    7   0x555555592769 nautilus_application_open_location_full+329
+  ► 0   0x7ffff7c625e9 _g_log_abort+89
+    1   0x7ffff7c63212 g_logv+802
+    2   0x7ffff7c634d3 g_log+147
+    3   0x7ffff7c644fd None
+    4   0x7ffff7d7732a g_object_ref+138
+    5   0x7ffff7d7732a g_object_ref+138
+    6   0x5555555eaaa3 begin_location_change+115
+    7   0x555555592769 nautilus_application_open_location_full+329
  
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 THREADS (33 TOTAL) 
]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
-   ► 1   "nautilus" stopped: 0x7ffff7c625e9 <_g_log_abort+89> 
-     70   "pool-45"  stopped: 0x7ffff5334d0d <syscall+29> 
-     69   "pool-44"  stopped: 0x7ffff5334d0d <syscall+29> 
-     63   "pool-38"  stopped: 0x7ffff5334d0d <syscall+29> 
+   ► 1   "nautilus" stopped: 0x7ffff7c625e9 <_g_log_abort+89>
+     70   "pool-45"  stopped: 0x7ffff5334d0d <syscall+29>
+     69   "pool-44"  stopped: 0x7ffff5334d0d <syscall+29>
+     63   "pool-38"  stopped: 0x7ffff5334d0d <syscall+29>
  Not showing 29 thread(s). Use set context-max-threads <number of threads> to 
change this.
  
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
- 
  
  Proposed fix:
  Remove g_object_unref(location) for transfer-none getter semantics, or 
explicitly g_object_ref() before use and keep balanced unref.
  
  Request: CVE assignment requested.
  
  Reporter: zhangweichao ([email protected])

** Description changed:

  [ Impact ]
  
- The Files app (nautilus) crashes when trying to open a bookmark from the
- context menu in the Ubuntu Desktop dock.
+ The Files app (nautilus) may crash when trying to open a bookmark from
+ the context menu in the Ubuntu Desktop dock.
  
  [ Test Plan ]
  
  1. Open Files
  2. Right click on the Files icon in the dock
  3. Select a bookmarked location, such as "Documents"
  4. Verify that the Files app did not crash
  5. Verify that a Files window was opened in the Documents location
  6. Repeat 10 times from step 2 (the invalid memory usage may not always 
trigger a crash)
  
  [ Where problems could occur ]
  
  Problems could manifest in the Files app, default file manager and file 
picker dialog provider in Ubuntu Desktop.
  The patch is removing a single call to decrease the ref-count of an object in 
memory; in the worst case this would cause a memory leak.
  
  [ Original report, dismissed as a security issue ]
  
  This is a security issue in Ubuntu downstream Nautilus integration
  (unity_launcher_support.patch), specifically src/unity-bookmarks-
  handler.c in activate_bookmark_by_quicklist().
  
  The function obtains a GFile* via
  nautilus_bookmark_get_location(bookmark) and later calls
  g_object_unref(location). Under current semantics this pointer is non-
  owning, so unref is invalid and can cause premature free. Reopening the
  same bookmark from quicklist later triggers invalid object use and
  crash.
  
  Ubuntu version: 26.04 LTS
  Kernel version: 7.0.0-22-generic
  Nautilus version: 1:50.0-0ubuntu2
  
  Affected version confirmed: nautilus 1:50.0-0ubuntu2
  Type: Use-After-Free
  Impact: Local DoS (Nautilus crash) While this is a local denial of service, 
it can be triggered repeatedly by any local user without authentication, 
causing loss of work and disruption to the desktop session.
  
  Reproducer:
  
  Open Nautilus
  
  Right-click dock icon
  
  Open bookmarked folder from quicklist
  
  Close window
  
  Repeat same quicklist open
  
  Crash occurs
  
  Crash signature:
  GLib-GObject-CRITICAL: g_object_ref: assertion 'G_IS_OBJECT (object)' failed, 
followed by SIGTRAP in GLib abort path.
  
  Root cause:
  activate_bookmark_by_quicklist() does:
  location = nautilus_bookmark_get_location(bookmark);
  g_application_open(... location ...)
  g_object_unref(location) <-- invalid for current non-owning semantics
  The function nautilus_bookmark_get_location() historically may have returned 
a GFile* with full ownership (transfer-full), but in the current version it 
returns a non-owning reference (transfer-none). The code still assumes the old 
semantics and calls g_object_unref(), causing premature free.
  
  Backtrace key frames:
  g_object_ref
  begin_location_change
  nautilus_application_open_location_full
  
  source code:
  static void
  activate_bookmark_by_quicklist (DbusmenuMenuitem *menu,
                                  guint timestamp,
                                  NautilusBookmark *bookmark)
  {
      GFile *location;
      NautilusApplication *application;
  
      g_return_if_fail (NAUTILUS_IS_BOOKMARK (bookmark));
  
      location = nautilus_bookmark_get_location (bookmark);
  
      application = NAUTILUS_APPLICATION (g_application_get_default ());
  
      g_application_open (G_APPLICATION (application),
                          (GFile* []) { location, NULL }, 1, "new-window");
  
      g_object_unref (location); // UAF is here!
  }
  
  GDB(pwndbg) message:
  (org.gnome.Nautilus:150660): GLib-GObject-CRITICAL **: 16:54:18.360: 
g_object_ref: assertion 'G_IS_OBJECT (object)' failed
  
  Thread 1 "nautilus" received signal SIGTRAP, Trace/breakpoint trap.
  _g_log_abort (breakpoint=breakpoint@entry=0x1) at 
../../../glib/gmessages.c:452
  LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
  
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 LAST SIGNAL 
]────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Breakpoint hit at 0x7ffff7c625e9
  
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 REGISTERS / show-flags off / show-compact-regs off 
]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   RAX  0xfffffffffffffcd0
   RBX  1
   RCX  0x51d1
   RDX  0x7ffff5412ac8 (main_arena+8) —▸ 0x55555eb05d70 ◂— 0xa0
   RDI  0x7ffff5412ac0 (main_arena) ◂— 0
   RSI  0x5810
   R8   1
   R9   0xa37d68d7b79bde6c
   R10  0
   R11  0x297
   R12  0x7ffff7c62d90 (g_log_default_handler) ◂— endbr64
   R13  3
   R14  0xa
   R15  8
   RBP  0x7fffffffc940 —▸ 0x7fffffffca10 —▸ 0x7fffffffcaf0 —▸ 0x7fffffffcb30 —▸ 
0x7fffffffcb80 ◂— ...
   RSP  0x7fffffffc900 ◂— 0x62f
   RIP  0x7ffff7c625e9 (_g_log_abort+89) ◂— mov rax, qword ptr [rbp - 0x18]
  
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 DISASM / x86-64 / set emulate on 
]──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   ► 0x7ffff7c625e9 <_g_log_abort+89>     mov    rax, qword ptr [rbp - 0x18]    
 RAX, [0x7fffffffc928] => 0x236f31748ebed500
     0x7ffff7c625ed <_g_log_abort+93>     sub    rax, qword ptr fs:[0x28]       
 RAX => 0 (0x236f31748ebed500 - 0x236f31748ebed500)
     0x7ffff7c625f6 <_g_log_abort+102>  ✘ jne    _g_log_abort+182            
<_g_log_abort+182>
  
     0x7ffff7c625f8 <_g_log_abort+104>    mov    rbx, qword ptr [rbp - 8]       
 RBX, [0x7fffffffc938] => 0x7ffff7d9b015 ◂— 'GLib-GObject'
     0x7ffff7c625fc <_g_log_abort+108>    leave
     0x7ffff7c625fd <_g_log_abort+109>    ret                                
<g_logv+802>
      ↓
     0x7ffff7c63212 <g_logv+802>          jmp    g_logv+612                  
<g_logv+612>
      ↓
     0x7ffff7c63154 <g_logv+612>          mov    esi, dword ptr [rbp - 0x88]    
 ESI, [0x7fffffffc988] => 0
     0x7ffff7c6315a <g_logv+618>          lea    rdi, [rip + 0xefbbf]           
 RDI => 0x7ffff7d52d20 (g_log_depth) ◂— 0xffffffff0000000c /* '\x0c' */
     0x7ffff7c63161 <g_logv+625>          call   g_private_set               
<g_private_set>
  
     0x7ffff7c63166 <g_logv+630>          test   r13d, r13d
  
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 STACK 
]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  00:0000│ rsp 0x7fffffffc900 ◂— 0x62f
  01:0008│-038 0x7fffffffc908 —▸ 0x55555db7e930 —▸ 0x7ffff5412ac8 
(main_arena+8) —▸ 0x55555eb05d70 ◂— 0xa0
  02:0010│-030 0x7fffffffc910 —▸ 0x7ffff7d2842d ◂— 'SYSLOG_IDENTIFIER'
  03:0018│-028 0x7fffffffc918 {len} ◂— 0x62f
  04:0020│-020 0x7fffffffc920 {proc_status} —▸ 0x55555db7e930 —▸ 0x7ffff5412ac8 
(main_arena+8) —▸ 0x55555eb05d70 ◂— 0xa0
  05:0028│-018 0x7fffffffc928 ◂— 0x236f31748ebed500
  06:0030│-010 0x7fffffffc930 —▸ 0x7ffff7d9b015 ◂— 'GLib-GObject'
  07:0038│-008 0x7fffffffc938 —▸ 0x7ffff7d9b015 ◂— 'GLib-GObject'
  
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 BACKTRACE 
]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   ► 0   0x7ffff7c625e9 _g_log_abort+89
     1   0x7ffff7c63212 g_logv+802
     2   0x7ffff7c634d3 g_log+147
     3   0x7ffff7c644fd None
     4   0x7ffff7d7732a g_object_ref+138
     5   0x7ffff7d7732a g_object_ref+138
     6   0x5555555eaaa3 begin_location_change+115
     7   0x555555592769 nautilus_application_open_location_full+329
  
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[
 THREADS (33 TOTAL) 
]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    ► 1   "nautilus" stopped: 0x7ffff7c625e9 <_g_log_abort+89>
      70   "pool-45"  stopped: 0x7ffff5334d0d <syscall+29>
      69   "pool-44"  stopped: 0x7ffff5334d0d <syscall+29>
      63   "pool-38"  stopped: 0x7ffff5334d0d <syscall+29>
  Not showing 29 thread(s). Use set context-max-threads <number of threads> to 
change this.
  
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  
  Proposed fix:
  Remove g_object_unref(location) for transfer-none getter semantics, or 
explicitly g_object_ref() before use and keep balanced unref.
  
  Request: CVE assignment requested.
  
  Reporter: zhangweichao ([email protected])

-- 
You received this bug notification because you are a member of Ubuntu
Desktop Bugs, which is subscribed to nautilus in Ubuntu.
https://bugs.launchpad.net/bugs/2156984

Title:
  UAF in Nautilus Unity quicklist bookmark handler

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/2156984/+subscriptions


-- 
desktop-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/desktop-bugs

Reply via email to