[pseudo][PATCH 02/11] linkat: Avoid a segmentation fault

Mark Hatle <[email protected]>
Newsgroups org.yoctoproject.lists.yocto-patches
Message-ID <[email protected]>
From: Peter Kjellerstedt <[email protected]>

This avoids the following segmentation fault (in useradd):

  Program terminated with signal SIGSEGV, Segmentation fault.
  #0  0x0000795b22562f49 in wrap_linkat (olddirfd=olddirfd@entry=-100,
      oldname=oldname@entry=0x6016835f1fb0 "/etc/group.3167327",
      newdirfd=newdirfd@entry=-100,
      newname=newname@entry=0x6016835f1fd0 "/etc/group.lock",
      flags=flags@entry=0) at ports/unix/guts/linkat.c:37
  37              oldpath = oldname;
  (gdb) bt
  #0  0x0000795b22562f49 in wrap_linkat (olddirfd=olddirfd@entry=-100,
      oldname=oldname@entry=0x6016835f1fb0 "/etc/group.3167327",
      newdirfd=newdirfd@entry=-100,
      newname=newname@entry=0x6016835f1fd0 "/etc/group.lock",
      flags=flags@entry=0) at ports/unix/guts/linkat.c:37
  #1  0x0000795b2257b95c in wrap_link (newname=0x6016835f1fd0 "/etc/group.lock",
      oldname=0x6016835f1fb0 "/etc/group.3167327") at ports/unix/guts/link.c:17
  #2  link (oldname=0x6016835f1fb0 "/etc/group.3167327",
      newname=0x6016835f1fd0 "/etc/group.lock") at pseudo_wrapfuncs.c:8968
  #3  0x00006016814d45dd in do_lock_file (file=file@entry=0x6016835f1fb0 "/etc/group.3167327",
      lock=lock@entry=0x6016835f1fd0 "/etc/group.lock", log=log@entry=true)
      at ../../sources/shadow-4.19.4/lib/commonio.c:167
  #4  0x00006016814d4e88 in commonio_lock_nowait (db=db@entry=0x6016814df9e0 <group_db>,
      log=log@entry=true) at ../../sources/shadow-4.19.4/lib/commonio.c:373
  #5  0x00006016814d4f09 in commonio_lock (db=db@entry=0x6016814df9e0 <group_db>)
      at ../../sources/shadow-4.19.4/lib/commonio.c:413
  #6  0x00006016814cfc9a in gr_lock () at ../../sources/shadow-4.19.4/lib/groupio.c:141
  #7  0x00006016814c981f in open_group_files (process_selinux=process_selinux@entry=false)
      at ../../sources/shadow-4.19.4/src/useradd.c:1797
  #8  0x00006016814cacdc in open_files (process_selinux=process_selinux@entry=false)
      at ../../sources/shadow-4.19.4/src/useradd.c:1759
  #9  0x00006016814cc388 in main (argc=<optimized out>, argv=<optimized out>)
      at ../../sources/shadow-4.19.4/src/useradd.c:2585
  (gdb) l
  32              if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) {
  33                      errno = ENOSYS;
  34                      return -1;
  35              }
  36      #endif
  37              oldpath = oldname;
  38              if (pseudo_chroot_len && strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
  39                      oldpath[pseudo_chroot_len] == '/') {
  40                      oldpath += pseudo_chroot_len;
  41              }
  (gdb) p oldname
  $1 = 0x6016835f1fb0 "/etc/group.3167327"
  (gdb) p oldpath
  $2 = 0x6016835f1fb0 "/etc/group.3167327"
  (gdb) p pseudo_chroot_len
  $3 = 91

The above code (on line 38) is supposed to check if oldpath is prefixed
by pseudo_chroot, but instead it checks the opposite, and then the check
for the slash on the next line is made outside oldpath if it is shorter
than pseudo_chroot.

Signed-off-by: Peter Kjellerstedt <[email protected]>
Signed-off-by: Mark Hatle <[email protected]>
Signed-off-by: Mark Hatle <[email protected]>
---
 ports/unix/guts/linkat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ports/unix/guts/linkat.c b/ports/unix/guts/linkat.c
index e1712a9..60fbf63 100644
--- a/ports/unix/guts/linkat.c
+++ b/ports/unix/guts/linkat.c
@@ -35,7 +35,7 @@
 	}
 #endif
 	oldpath = oldname;
-	if (pseudo_chroot_len && strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
+	if (pseudo_chroot_len && !strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
 		oldpath[pseudo_chroot_len] == '/') {
 		oldpath += pseudo_chroot_len;
 	}
-- 
1.8.3.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.