[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