首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >uClibc vfork()导致分段错误

uClibc vfork()导致分段错误
EN

Stack Overflow用户
提问于 2014-07-07 13:13:01
回答 2查看 570关注 0票数 0

我正在使用armv7进行openwrt开发,并且面临着vfork导致的段错误。

我已经写了一个小的测试程序,包含以下部分:

代码语言:javascript
复制
    ...
    pid_t child_t;
    if((child_t = vfork()) < 0)
    {
        printf("error!\n");
        return -1;
    }
    else if(child_t == 0)
    {
        printf("in child:pid =%d\n",getpid());
        sleep(2);
        _exit(0);
    }
    else
    {
        printf("in parent:child_t id = %d,pid = %d\n",child_t,getpid());
    }
    ...

vfork()函数总是导致segfault,这是gdb调试跟踪:

代码语言:javascript
复制
...
   (gdb) c
       Breakpoint 1, main (argc=1, argv=0xbefffed4) at handler.c:33
       33            if((child_t = vfork()) < 0)
   (gdb) stepi 
       0x00008474 in vfork () at         libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfo        rk.S:71
   71        SAVE_PID
   (gdb) l
   66    
   67    #else
   68    __vfork:
   69    
   70    #ifdef __NR_vfork
   71        SAVE_PID
   72        DO_CALL (vfork)
   73        RESTORE_PID
   74        cmn    r0, #4096
   75        IT(t, cc)
  (gdb) b     libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfo    rk.S:72
       Breakpoint 2 at 0xb6fcf930: file     libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfo     rk.S, line 72.
  (gdb) disassemble
           0x00008584 <+40>:        bl      0x8444 <puts>
     => 0x00008588 <+44>:         bl      0x8474 <vfork>
           0x0000858c <+48>:         str    r0, [r11, #-12]
  (gdb)stepi
     ...
  (gdb) stepi 
       0x00008474 in vfork () at     libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfo    rk.S:71
       71              SAVE_PID
  (gdb) disassemble 
       Dump of assembler code for function vfork:
       =>  0x00008474 <+0>:   add  r12, pc, #0, 12
              0x00008478 <+4>:   add  r12, r12, #8, 20        ; 0x8000
              0x0000847c <+8>:   ldr    pc, [r12, #796]!        ; 0x31c
  (gdb) stepi
      …
   (gdb) disassemble
        Dump of assembler code for function vfork:
             0x00008474 <+0>:   add  r12, pc, #0, 12
             0x00008478 <+4>:   add  r12, r12, #8, 20        ; 0x8000
       => 0x0000847c <+8>:     ldr    pc, [r12, #796]!        ; 0x31c
    (gdb)c
       Continuing.
       Program received signal SIGSEGV, Segmentation fault.
       0xffff0fe0 in ?? ()
    (gdb)

我还在vfork.S:__vfork上找到了vfork代码:

代码语言:javascript
复制
#ifdef __NR_vfork
     SAVE_PID
     DO_CALL (vfork)
     RESTORE_PID
     cmn    r0, #4096
     IT(t, cc)
 #if defined(__USE_BX__)
    bxcc    lr
 #else
     movcc    pc, lr
 #endif

     /* Check if vfork even exists.  */
    ldr     r1, =-ENOSYS
    teq     r0, r1
    bne     __error
#endif

    /* If we don't have vfork, use fork.  */
    DO_CALL (fork)
    cmn     r0, #4096

    /* Syscall worked.  Return to child/parent */
    IT(t, cc)
#if defined(__USE_BX__)
    bxcc    lr
#else
    movcc   pc, lr
#endif

__error:
    b    __syscall_error
#endif

更多信息-当像这样绕过vfork时-

代码语言:javascript
复制
   VFORK_LOCK;

-  if ((pid = vfork()) == 0) {  /* Child of vfork... */

+  // if ((pid = vfork()) == 0) {  /* Child of vfork... */

+        pid = syscall(__NR_fork, NULL);

+  if (pid == 0) {  /* Child of vfork... */

一切似乎都很正常。

感谢大家的帮助!

EN

回答 2

Stack Overflow用户

发布于 2014-07-07 13:38:37

man (3) vfork

vfork()函数应等同于fork(),但如果vfork()创建的进程修改用于存储来自vfork()的返回值的pid_t类型变量以外的任何数据,或者从调用vfork()的函数返回,或者在成功调用_exit()或exec系列函数之一之前调用任何其他函数,则行为未定义。

因此,在子代中,您可以调用_exitexec。就这样。

票数 0
EN

Stack Overflow用户

发布于 2014-09-09 18:40:27

这里的解决方案是启用CONFIG_KUSER_HELPER标志。

来自CONFIG_USERS_HELPERS。

代码语言:javascript
复制
If all of the binaries and libraries which run on your platform
 are built specifically for your platform, and make no use of
 these helpers, then you can turn this option off to hinder
 such exploits. However, in that case, if a binary or library
 relying on those helpers is run, it will receive a SIGILL signal,
 which will terminate the program.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24603406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档