[pseudo][PATCH] linkat: Avoid a segmentation fault
Peter Kjellerstedt <[email protected]>
| Newsgroups | org.yoctoproject.lists.yocto-patches |
|---|---|
| Message-ID | <[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]>
---
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;
}