LoginSignup
2
1

More than 5 years have passed since last update.

カーネルのシグナル配信についてさらに調べた

Posted at

前回に引き続きLinuxのシグナルの配信について調べた。

カーネルバージョン

v4.5.0

シグナルの配信

シグナルの配信はシステムコール(= "Interrupt came from user space"かな?)から、ユーザモードに戻るときに呼ばれるprepare_exit_to_usermodeで実行される。
ここで、プログラムカウンタ(ip)にシグナルハンドラのエントリポイントにセットしてrestore_regs_and_iretを呼び出すことでハンドラが実行される。

  /* Interrupt came from user space */
GLOBAL(retint_user)
  mov %rsp,%rdi
  call  prepare_exit_to_usermode
  TRACE_IRQS_IRETQ
  SWAPGS
  jmp restore_regs_and_iret

prepare_exit_to_usermodeを見ていくと、do_signal(),handle_signal()によって、対象のプロセスに保留されているシグナルのうち、ハンドラが設定されているものが呼び出される。
handle_signal()ではまず、ユーザモードのスタックを作成する。このとき、シグナルハンドラからの戻り番地をsigreturn()を呼び出すコードにセットする。

ユーザモードスタックにセットするのは次のrt_sigframe構造体である。pretcodeが戻り番地になる。

struct rt_sigframe {
  char __user *pretcode;
  struct ucontext uc;
  struct siginfo info;
  /* fp state follows here */
};

x86_64では、pretcodeにvdsovdso_image_32.sym___kernel_sigreturnがセットされるわけではなく、ka.sa.sa_restorerframe->pretcodeにセットされているようだ。
restorerはsigaction()の引数のactのメンバとしてアプリケーションからセットされる(man 2 sigaction 参照)が、ユーザが好きにセットするものではないのでlibcなどで決められている可能性があるかも。

/* Set up to return from userspace.  If provided, use a stub
   already in userspace.  */
/* x86-64 should always use SA_RESTORER. */
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
  put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode);

...

  regs->sp = (unsigned long)frame;

また、シグナルハンドラのエントリポイントをipにセットすることで、ユーザモードに戻った時にシグナルハンドラが実行されるようにしている。

  regs->ip = (unsigned long) ksig->ka.sa.sa_handler;

本来の呼び出し元のユーザモードのコンテキストは、同じくユーザモードスタック内に保存され,dxレジスタでポイントされる。
これらは呼び出されたsigreturn()によって回復されるはず。

/* Create the ucontext.  */
if (cpu_has_xsave)
  put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
else
  put_user_ex(0, &frame->uc.uc_flags);
put_user_ex(0, &frame->uc.uc_link);
save_altstack_ex(&frame->uc.uc_stack, regs->sp);

...

  regs->dx = (unsigned long)&frame->uc;

まとめ

シグナルの配信は生成と違い、アーキテクチャ依存のコードとなっていて比較的複雑だった。
シグナルハンドラからの復帰をカーネルがフックするために、POSIXに規定されていないsigreturn()なるシステムコールを使っていることがわかった。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1