-ãã³ãžã¥ã©ã¹ã«è¿·æããããŠãã... -å¿é ïŒ ãããŠãããªãã¯åœŒãå·ã€ããŸããã
ãã£ã¹ã«ãã·ã§ã³ã®åã®éšåïŒ 1st ã 2ndããã³3rd ïŒã§ãsys_call_tableã®å 容ãå€æŽããæ©èœã䜿çšããŠãLinuxã·ã¹ãã ã³ãŒã«ã®åäœãå€æŽããæ¹æ³ãæ€èšããŸããã 次ã«ããœãããŠã§ã¢ãããžã§ã¯ãã®ç®çã§æ°ããã·ã¹ãã ã³ãŒã«ãåçã«è¿œå ã§ãããã©ããïŒããã³ãã®æ¹æ³ïŒã®æ¹åã§å®éšãç¶ããŸãã
ããªãïŒããšãã質åã«ã¯çŠç¹ãåœãŠãŸãããããã°ã©ãã³ã°ã§ã¯ãæåŸã«å°ããã®ã¯ããªãïŒãã§ãããã©ããã£ãŠïŒããšå°ããå¿ èŠããããŸãã ããããããã§ããç§ãã¡ã¯è°è«ã®çµããã«åãã£ãŠãããã«ããã«æ»ããŸãã
ã©ã®ããã«èŠããŸããïŒ
ã·ã¹ãã ã³ãŒã«ã眮ãæããåè¿°ã®äŸãšã®äžè¬çãªé¡äŒŒæ§ãèãããšããã®ã¿ã¹ã¯ã¯ãã¹ãŠã®é¡äŒŒç¹ãšãšãã«ãããã€ãã®æªåããç¹åŸŽãæã£ãŠããŸãã
- å ã®sys_call_tableã·ã¹ãã ã³ãŒã«ããŒãã«ã®ãµã€ãºã¯ãã«ãŒãã«ã®ããŒãžã§ã³ããšã«ãã£ããã§ããå調ã«å¢å ããŠãããç¹å®ã®ããã»ããµãã©ãããã©ãŒã ã«å€§ããäŸåããŠããŸãã
- ãã®ããŒãã«ã®ãã£ã¡ã³ã·ã§ã³ãå®çŸ©ããå®æ°ïŒã«ãŒãã«ã§ã¯__NR_syscall_maxããŸãã¯äžéšã®æ°ããããŒãžã§ã³ã§ã¯__NR_syscallsãšããŠç¥ãããŠããŸãïŒã¯ãã³ã³ãã€ã«æéã®ããªããã»ããµå®æ°ïŒãã¯ãïŒã«ãã£ãŠå®£èšãããå®è¡æã«ã¯äžæã§ãïŒå°ãªããšããç§ã«ã¯äžæã§ãïŒã
- ããŒãã«ã®æåŸã«ç¬èªã®ãšã³ããªãã€ã³ããè¿œå ããããšãããšãããŒãã«ã«å²ãåœãŠãããé åãè¶ ããé倧ãªãªã¹ã¯ããããŸã-ããã¯å®è¡ã§ããŸããïŒ
sys_call_tableããŒãã«ã®ãµã€ãºã¯éåžžã«å€§ãããããŒãžã§ã³ããã«ãŒãã«ããŒãžã§ã³ïŒããŒãžã§ã³3.13ïŒã«å€æŽãããŸããããã¯éåžžã«å€§ãŸããªèŠç©ããã§ãã
$ cat /proc/kallsyms | grep ' sys_' | grep T | wc -l 357
è°è«ã®ãã®éšåã®ã«ãŒãã«ããŒãžã§ã³ã¯ãåžžã«èšåããå¿ èŠããããŸãïŒåã®ããŒãžã§ã³ã®ããããŒãã¡ã€ã«ã§å®çŸ©ããããã®ã¯ã次ã®ããŒãžã§ã³ãšã¯ç°ãªãæ¹æ³ã§å®å šã«ç°ãªãå ŽæïŒãã¡ã€ã«ïŒã§æ±ºå®ããããããŸã£ããå®çŸ©ãããªãããšãããããŸãã ããã¯ã«ãŒãã«ã³ãŒãã®äžè¬çãªæ¹æ³ã§ãã ããããããã§ããã¹ãŠã®åºæ¬ååãšäŸåé¢ä¿ã¯ããŒãžã§ã³ããšã«å€æŽãããŠããŸããã
ã·ã¹ãã ã³ãŒã«ã®ããŒãã«ã¯å¯ã§ã¯ãªã ãååã«ã¹ããŒã¹ã§ã¯ãªã ãæªäœ¿çšã®äœçœ®ãããããïŒäžââèšã®å¶éãããç¶æ³ãç·©åããŸãïŒå€ãã·ã¹ãã ã³ãŒã«ããæ®ã£ãŠãããçŸåšãµããŒããããŠããŸããïŒïŒã ãã®ãããªäœçœ®ã¯ãã¹ãŠ 1ã€ã®ã¢ãã¬ã¹ã§æºããããŸã-æªå®çŸåŒã³åºãsys_ni_syscallïŒïŒã®ãã³ãã©ãŒã®é¢æ°ãžã®ãã€ã³ã¿ãŒïŒ
$ cat /proc/kallsyms | grep sys_ni_syscall c045b9a8 T sys_ni_syscall
ãããŠãsys_ni_syscallïŒïŒã·ã¹ãã ã³ãŒã«èªäœã¯æ¬¡ã®ããã«å®çŸ©ãããŸãïŒ
asmlinkage long sys_ni_syscall( void ) { return -ENOSYS; }
ãããã£ãŠãsys_call_tableããŒãã«ã®æªäœ¿çšã®äœçœ®ã«æ°ããã·ã¹ãã ã³ãŒã«ãã³ãã©ãè¿œå ã§ããŸãã ãããã®äœçœ®ã«ã¯å€ãæªäœ¿çšã®åŒã³åºãã¯ãããŸããããåŒã³åºãã¯è¡ããããã®å¯äžã®ã¢ã¯ã·ã§ã³ã¯ãšã©ãŒã³ãŒããè¿ãããšã§ãã ããã«ãã«ãŒãã«éçºè ã«ã¯ãããã®äœçœ®ãåå©çšããæš©å©ããããŸããããããªããšãå®å šã«å»æ¢ãããã¢ããªã±ãŒã·ã§ã³ããçããªãæ°ãã眮æåŒã³åºããåŒãèµ·ããå¯èœæ§ããããŸãã
éçã«ããœãŒã¹ã³ãŒãå ã®ããã¹ãã§ãsys_call_tableããŒãã«ã®æ§é ã詳现ã«èª¿ã¹ãããšãã§ããŸãïŒéžæãããã©ãããã©ãŒã ãšããŒãžã§ã³çšïŒã ãã®ãããªç 究ã§ã¯ããœãŒã¹ã³ãŒãèªäœã¯éçºè ã«ãã£ãŠæ瀺ãããã®ã§ã»ãšãã©åœ¹ã«ç«ã¡ãŸãããã幞ããªããšã«ãä»æ¥ããã§ãããïŒããã§ããŒãžã§ã³ãæ¯èŒã§ããããã«ïŒLXRïŒLinux Kernel Cross ReferenceïŒãããžã§ã¯ãã䜿çšããŠã«ãŒãã«ã³ãŒããèŠèŠåããå€ãã®ãªãœãŒã¹ããããŸãå¿ èŠãªèå¥åãç°¡åã«èŠã€ããããšãã§ããŸãïŒã ããšãã°ãïŒãã¡ã€ã«<arch / x86 / kernel / syscall_table_32.S>ïŒsys_ni_syscallãžã®ãªã³ã¯ãå«ãx86ã¢ãŒããã¯ãã£3.0.26ã«ãŒãã«ã®sys_call_tableã®äœçœ®ã®ã¿ã衚瀺ããŸãïŒãã ããã«ãŒãã«3.2以éã§ã¯ããã®ãã¡ã€ã«ã¯ã³ãŒãããªãŒãããæ¶ããŸã...ããŒãã«ã¯åããŸãŸã§ãå€èŠ³ã¯å€ãããŸããïŒïŒ
ENTRY(sys_call_table) .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ .long sys_exit ... .long sys_ni_syscall /* old break syscall holder */ //17 .long sys_ni_syscall /* old stty syscall holder */ //31 .long sys_ni_syscall /* old gtty syscall holder */ //32 .long sys_ni_syscall /* 35 - old ftime syscall holder */ //35 .long sys_ni_syscall /* old prof syscall holder */ //44 .long sys_ni_syscall /* old lock syscall holder */ //53 .long sys_ni_syscall /* old mpx syscall holder */ //56 .long sys_ni_syscall /* old ulimit syscall holder */ //58 .long sys_ni_syscall /* old profil syscall holder */ //98 .long sys_ni_syscall /* old "idle" system call */ //112 .long sys_ni_syscall /* old "create_module" */ //127 .long sys_ni_syscall /* 130: old "get_kernel_syms" */ //130 .long sys_ni_syscall /* reserved for afs_syscall */ //137 .long sys_ni_syscall /* Old sys_query_module */ //167 .long sys_ni_syscall /* reserved for streams1 */ //188 .long sys_ni_syscall /* reserved for streams2 */ //189 .long sys_ni_syscall /* reserved for TUX */ //222 .long sys_ni_syscall //223 .long sys_ni_syscall //251 .long sys_ni_syscall /* sys_vserver */ //273 .long sys_ni_syscall /* 285 */ /* available */ //285 ... .long sys_setns // 346
ãªã¹ãã«ã¯æªäœ¿çšã®äœçœ®ïŒããŒãã«ã®å é ãšæ«å°Ÿãé€ãïŒã®ã¿ã衚瀺ããããœãŒã¹ã³ãŒãããã³ã¡ã³ããæ®ãããã·ã¹ãã ã³ãŒã«ã®äœçœ®çªå·ãå«ãæåŸã®ã³ã¡ã³ããè¿œå ãããŸããã
ãã®ããŒãžã§ã³ã®ã«ãŒãã«ã§ã¯ãããŒãã«ã«ã¯347åã®ã·ã¹ãã ã³ãŒã«äœçœ®ãããããã®ãã¡21åã¯é¢ä¿ããŠããŸããã å¯å€ã«ãŒãã«ã³ãŒãã«äŸåããªãããã€ããã¯ã¹ã®æªäœ¿çšäœçœ®ã®åæã¯ãæ€èšäžã®æåã®ã«ãŒãã«ã¢ãžã¥ãŒã«ã«åœãŠãããŸãã
static void **taddr, // sys_call_table *niaddr; // sys_ni_syscall() static int nsys = 0; // #define SYS_NR_MAX 450 // SYS_NR_MAX - , sys_call_table static int sys_length( void* data, const char* sym, struct module* mod, unsigned long addr ) { int i; if( ( strstr( sym, "sys_" ) != sym ) || ( 0 == strcmp( "sys_call_table", sym ) ) ) return 0; for( i = 0; i < SYS_NR_MAX; i++ ) { if( taddr[ i ] == (void*)addr ) { // sys_* sys_call_table if( i > nsys ) nsys = i; break; } } return 0; } static void put_entries( void ) { int i, ni = 0; char buf[ 200 ] = ""; for( i = 0; i <= nsys; i++ ) if( taddr[ i ] == niaddr ) { ni++; sprintf( buf + strlen( buf ), "%03d, ", i ); } LOG( "found %d unused entries: %s\n", ni, buf ); } static int __init init_driver( void ) { if( NULL == ( taddr = (void**)kallsyms_lookup_name( "sys_call_table" ) ) ) { ERR( "sys_call_table not found!\n" ); return -EFAULT; } LOG( "sys_call_table address = %p\n", taddr ); if( NULL == ( niaddr = (void*)kallsyms_lookup_name( "sys_ni_syscall" ) ) ) { ERR( "sys_ni_syscall found!\n" ); return -EFAULT; } LOG( "sys_ni_syscall address = %p\n", niaddr ); kallsyms_on_each_symbol( sys_length, NULL ); LOG( "sys_call_table length = %d\n", nsys + 1 ); put_entries(); return -EPERM; } module_init( init_driver );
åãšåæ§ã«ããªãã·ã§ã³ã®è©³çŽ°ïŒãã¯ãLOGïŒïŒãªã©ïŒã¯è¡šç€ºãããããã¹ãŠå®å šãªæ·»ä»ãã¡ã€ã«ã«å«ãŸããŠããŸãã
ç°¡åã«å®è¡ã§ããŸãïŒãããæ£ããïŒ-sys_call_tableã®é·ãã調ã¹ãã«ã¯ãsys_ *ãã¹ã¯ã䜿çšããŠã«ãŒãã«æåã®æ°ãã«ãŠã³ããã1ïŒsys_call_tableæåèªäœïŒãæžç®ããŸãã ããããåé·ãªæ¹æ³ãåããŸãã
- sys_ *ãã¹ã¯ã®æ¬¡ã®æåã¯ã«ãŒãå ã«ãããŸãã
- ãã®äœçœ®ã¯ sys_call_tableã§æ€çŽ¢ãããŸãïŒããã¯ããããã·ã¹ãã ã³ãŒã«ã§ãããšããè¿œå ã®åä¿éºã§ãïŒã
- ãã®äœçœ®ãåã®æåã§ä»¥åã«èŠã€ãã£ãäœçœ®ããã倧ããå Žåã æåŸã®åŒã³åºãã®çŸåšã®çªå·ïŒçŸåšã®ãµã€ãºsys_call_tableïŒãšèŠãªãããŸãã
ãã®åé·ãªïŒãŸã£ããå¿ èŠã§ã¯ãªãïŒã¹ããŒã ã«ãããã¢ãŒããã¯ãã£ãšLinuxã«ãŒãã«ã®ããŒãžã§ã³ã®ã·ã¹ãã ã³ãŒã«ããŒãã«ã®æ£ç¢ºãªãµã€ãºãåæã«æ確ã«ããããšãã§ããŸãã
$ uname -p i686 $ uname -r 3.13.0-37-generic $ sudo insmod nsys.ko insmod: ERROR: could not insert module nsys.ko: Operation not permitted $ dmesg | tail -n 4 [10751.601851] ! sys_call_table address = c1666140 [10751.602194] ! sys_ni_syscall address = c1075930 [10751.659769] ! sys_call_table length = 351 [10751.659779] ! found 27 unused entries: 017, 031, 032, 035, 044, 053, 056, 058, 098, 112, 127, 130, 137, 167, 169, 188, 189, 222, 223, 251, 273, 274, 275, 276, 285, 294, 317,
ãã®ããŒãžã§ã³ã§ã¯351åã®ã·ã¹ãã ã³ãŒã«ã®ãã¡ã27åã¯äœ¿çšãããŸããïŒããŒãã«ãµã€ãºã®ã»ãŒ10ïŒ ïŒã ãã®ãªã¹ãã®å®å®æ§ã¯éåžžã«é«ãã§ãïŒæèçã«ãã³ãŒãåæã«ã¯ããŒãžã§ã³3.0.26ãéžæããããã€ããã¯ã¹ã§ã®å®è¡ã«ã¯äºãã«4幎以äžé¢ããŠããããŒãžã§ã³2.6.32ããã³3.13ãéžæãããŠããŸãïŒã
泚ïŒèã«æ³šæããããããšãªããåæ§ã®æ¹æ³ã§ã¢ãžã¥ãŒã«ãèšè¿°ããããšã«åæ ŒããŠããããšã«æ³šæããŠãã ããã ãŸã£ããããŠã³ããŒãããããšãæå³ããŠããªããbïŒã ãã®ç¹ã«é¢ããŠãæå³çã«ãŒã以å€ã®å®äºã³ãŒããè¿ããŸãcïŒã ãããã£ãŠãã¢ã³ããŒãæ©èœïŒ__exitïŒã¯ãŸã£ãããããŸãã-ããã¯ãŠãŒã¶ãŒã¢ããªã±ãŒã·ã§ã³ïŒã¡ã€ã³ïŒïŒãã€ã³ãããéå§ïŒãšçŽæ¥åçã§ãããæ倧ç¹æš©ã§ã¹ãŒããŒãã€ã¶ãŒã¢ãŒãã§ã®ã¿å®è¡ãããŸãã ããããããã¯ãã§ã«å¥ã®äŒè©±ã®äž»é¡ã§ã...
æ°ããã·ã¹ãã ã³ãŒã«ã®å®è£
ããã§ãå®åŒåãããã¿ã¹ã¯ã®å®è£ ã«æ»ãæºåãã§ããŸãããæ°ããã·ã¹ãã ã³ãŒã«ãè¿œå ããŸãã åœç¶ããã®åŒã³åºãã䜿çšãããã¹ããŠãŒã¶ãŒã¹ããŒã¹ã¢ããªã±ãŒã·ã§ã³ãå¿ èŠã§ãã æ°ããåŒã³åºãã®çªå·ã¯ãã¢ãžã¥ãŒã«ãšããã°ã©ã ïŒãã¯ãLOGïŒïŒãERRïŒïŒãããã³ããã«èšèŒãããŠããä»ã®å°ããªãã®ïŒã®äœ¿çšã®äžè²«æ§ã®ããã«ãäžè¬çãªããããŒãã¡ã€ã«ïŒsyscall.hïŒã§å®çŸ©ãããŠããŸãã
// #define __NR_own 223 // , nsys.ko // 3.31 27 : // 017, 031, 032, 035, 044, 053, 056, 058, 098, 112, // 127, 130, 137, 167, 169, 188, 189, 222, 223, 251, // 273, 274, 275, 276, 285, 294, 317,
æ°ããã·ã¹ãã ã³ãŒã«ãè¡ããŠãŒã¶ãŒã¢ããªã±ãŒã·ã§ã³ããå§ããæ¹ãç°¡åãã€æ確ã§ãã ããã§ã¯ãã¹ãŠãã·ã³ãã«ã§ããç°¡åã«ããããšã¯ã§ããŸããã
static void do_own_call( char *str ) { int n = syscall( __NR_own, str, strlen( str ) ); if( n == 0 ) LOG( "syscall return %d\n", n ); else { ERR( "syscall error %d : %s\n", n, strerror( -n ) ); exit( n ); } } int main( int argc, char *argv[] ) { if( 1 == argc ) do_own_call( "DEFAULT STRING" ); else while( --argc > 0 ) do_own_call( argv[ argc ] ); return EXIT_SUCCESS; };
ããã°ã©ã ã¯ã1ã€ãŸãã¯äžé£ã®ïŒã³ãã³ãã©ã€ã³ã§è€æ°ã®ãã©ã¡ãŒã¿ãŒãæå®ããå ŽåïŒã·ã¹ãã ã³ãŒã«ãäœæããæåãã©ã¡ãŒã¿ãŒãåŒã³åºãã«æž¡ãããšãã§ããŸãïŒsys_writeãªã©ã®æ¹æ³ãšåæ§ïŒã ãããŠããã§ã«ã¢ãžã¥ãŒã«ã³ãŒãã§ããã®è¡ãã«ãŒãã«ã¹ããŒã¹ã«ã©ã®ããã«ã³ããŒãããŠãããã確èªã§ããŸãã ãã ããããã§ã®äž»ãªé¢å¿äºã¯ãªã¿ãŒã³ã³ãŒãã§ããã·ã¹ãã ã³ãŒã«ã®æåãŸãã¯å€±æã§ãã
ãããŠãã«ãŒãã«ããã®ãã®ãããªåŒã³åºãããããã¯ã¢ãããããã¢ãžã¥ãŒã«ã¯æ¬¡ã®ãšããã§ãã
asmlinkage long (*old_sys_addr) ( void ); // : asmlinkage long new_sys_call ( const char __user *buf, size_t count ) { static char buf_msg[ 80 ]; int res = copy_from_user( buf_msg, (void*)buf, count ); buf_msg[ count ] = '\0'; LOG( "accepted %d bytes: %s\n", count, buf_msg ); return res; }; static void **taddr; // sys_call_table static int __init new_sys_init( void ) { void *waddr; if( NULL == ( taddr = (void**)kallsyms_lookup_name( "sys_call_table" ) ) ) { ERR( "sys_call_table not found!\n" ); return -EFAULT; } old_sys_addr = (void*)taddr[ __NR_own ]; if( ( waddr = (void*)kallsyms_lookup_name( "sys_ni_syscall" ) ) != NULL ) LOG( "sys_ni_syscall address = %p\n", waddr ); else { ERR( "sys_ni_syscall not found!\n" ); return -EFAULT; } if( old_sys_addr != waddr ) { ERR( "not free slot!\n" ); return -EINVAL; } LOG( "old sys_call_table[%d] = %p\n", __NR_own, taddr[ __NR_own ] ); rw_enable(); taddr[ __NR_own ] = new_sys_call; rw_disable(); LOG( "new sys_call_table[%d] = %p\n", __NR_own, taddr[ __NR_own ] ); return 0; } static void __exit new_sys_exit( void ) { rw_enable(); taddr[ __NR_own ] = old_sys_addr; rw_disable(); LOG( "restore sys_call_table[%d] = %p\n", __NR_own, taddr[ __NR_own ] ); return; } module_init( new_sys_init ); module_exit( new_sys_exit );
sys_call_tableããŒãã«ã®æå®ãããïŒ__NR_ownïŒäœçœ®ã®ã¢ãã¬ã¹ãšãæªäœ¿çšã®sys_ni_syscallã·ã¹ãã ã³ãŒã«ã®ã¢ãã¬ã¹ãšã®å¯Ÿå¿ã確èªããäºéåä¿éºããããŸãã
ãããŠä»ãç§ãã¡ãåŸããã®ãè©äŸ¡ããŸãïŒ
$ ./syscall syscall error -1 : Operation not permitted $ echo $? 255 $ sudo insmod adds.ko $ lsmod | head -n3 Module Size Used by adds 12622 0 pci_stub 12550 1 $ dmesg | tail -n3 [15000.600618] ! sys_ni_syscall address = c1075930 [15000.600622] ! old sys_call_table[223] = c1075930 [15000.600623] ! new sys_call_table[223] = f87d9000 $ ./syscall new string for call syscall return 0 syscall return 0 syscall return 0 syscall return 0 $ dmesg | tail -n4 [15070.680753] ! accepted 4 bytes: call [15070.680799] ! accepted 3 bytes: for [15070.680804] ! accepted 6 bytes: string [15070.680807] ! accepted 3 bytes: new $ ./syscall 'new string for call' syscall return 0 $ dmesg | tail -n1 [15167.526452] ! accepted 19 bytes: new string for call $ sudo rmmod adds $ dmesg | tail -n1 [15199.917817] ! restore sys_call_table[223] = c1075930 $ ./syscall syscall error -1 : Operation not permitted
ã¢ãžã¥ãŒã«ãã¢ã³ããŒãããããšãã«ãŒãã«ã¯ããã°ã©ã ã«å¿ èŠãªã·ã¹ãã ã³ãŒã«ã®å®è¡ããµããŒãã§ããªããªããŸãïŒ
è°è«
å®éãããã§è°è«ããããšã¯äœããããŸãã-ãã¹ãŠãäŸã«ãã£ãŠééçã«ç€ºãããŠããŸãã ããããæåã¯ãããããŸã£ããé©çšãããªãçç±ã«ã€ããŠèããè¿°ã¹ãããšãçŽæããŸããïŒããããããã°ã©ãã³ã°ã®è³ªåã¯ãªãã§ããïŒ ç€ºãããŠããããªãã¯ã¯ãïŒåæ¹åïŒã¢ããªã±ãŒã·ã§ã³ãã«ãŒãã«ãšå¯Ÿè©±ããããã®å¥ã®æ¹æ³ãæäŸããŸãã ã¯ãããã¡ãã/ devã/ procããŸãã¯/ sysã䜿çšããŠåãããšãè¡ãããšãã§ããŸããããããã®åã¡ãœããã¯ã·ã¹ãã ã³ãŒã«ãããéããããå€æ°ã®äžéã«ãŒãã«ã¡ã«ããºã ãå¿ èŠã«ãªããŸãã
åæ§ã®ã¡ã«ããºã ã䜿çšã§ããã®ã¯ãã€ã§ããïŒ ããšãã°ãäºæãããã€ãã³ããçºçãããŸã§ãã·ã¹ãã ã³ãŒã«ã§å¥ã®ã¢ããªã±ãŒã·ã§ã³ã¹ã¬ããããããã¯ãããå Žåã®ãã«ãŒãã«å ã®äžéšã®ã€ãã³ãã«é¢ããã¢ããªã±ãŒã·ã§ã³ã®éåæéç¥ã®å Žåã ãã®ãããªã€ãã³ãã¯ãããšãã°ããããã°ãããæ°ããããã€ã¹ããã®ããŒããŠã§ã¢å²ã蟌ã¿ïŒIRQïŒã§ããå¯èœæ§ããããŸãïŒããçšåºŠé«éã§ã¯ãããŸããïŒã ãã®ã¢ãããŒãã§ã¯ãããã€ã¹ã§ã®I / Oæäœã¯ãinbïŒïŒãoutbïŒïŒ...ããŸãã¯iopermïŒïŒããã³ioplïŒïŒã°ã«ãŒãã®æäœã䜿çšããŠãŠãŒã¶ãŒç©ºéããå®è£ ã§ããŸãã ããããã¹ãŠã«ããããŠãŒã¶ãŒã®ã¹ããŒã¹ãè¶ ããããšãªããç¹æš©ã«ãŒãã«ã¢ãŒãã«é¢é£ãããªã¹ã¯ãå°é£ã䌎ããã«ãäœæ¥ã調æ»ããããã€ã¹ã䜿çšããŠäº€æã³ãŒããæã詳现ã«èšè¿°ã§ããŸãã ãããŠãç¶æ³ã«å¿ããŠèªç±ã«ïŒãã®ãã¹ãæžã¿ãã©ã€ããŒã®ã³ãŒããã¢ãžã¥ãŒã«ã®åœ¢ã§æ©æ¢°çã«æžãæãããããŠãŒã¶ãŒç©ºéã«ãã®ãŸãŸæ®ãããã§ããŸãã
泚ïŒãã®æ¹æ³ã§ãã解決ã§ããªãããã€ã¹ã®äœéã«é¢ããäžèšã®çºèšã¯ãå¿èã«è¿ã¥ããããªãããã«ããŠãã ããã å®éãLinuxã«ãŒãã«å ã®é«éããã€ã¹ã¯å²ã蟌ã¿ã§ã¯åäœããã埪ç°ããŒãªã³ã°ã䜿çšããŸãã ããšãã°ãããŒããŠã§ã¢ã¬ãã«ã§ã®ãããã¯ãŒã¯ã¹ã¿ãã¯ã®ãã¹ãŠã®ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®ããã«ãLinuxãããã¯ãŒã¯ãµãã·ã¹ãã ãç¥ã£ãŠãã人ãªã誰ã§ãç§ãæå³ããããšãç解ã§ããŸãã
ç§ã¯ããããã©ã€ãšã¿ãªãªããŒããŠã§ã¢ã®éçºè ããä»ã®äººãšåãããã«èªç¶çã«ååšããæš©å©ãæã€ãããžã§ã¯ãã«ã€ããŠè©±ããŠããã®ã§ã¯ãããŸããã 圌ãã®äœåã§ã¯ãåæ§ã®ææ³ãã¢ããªã±ãŒã·ã§ã³ã®åºç€ãèŠã€ããããšãã§ããŸãã
ç¹°ãè¿ããŸããã以åãšåæ§ã«ãã³ãŒãã¢ãŒã«ã€ãã¯ãããŸãã¯ããã§ååŸã§ããŸã ...
ãšãããŒã°
ããã¯Linuxã·ã¹ãã ã³ãŒã«ã®ãã®ãããªç°åžžãªïŒäžåãªïŒïŒåŠçã«é¢ããçããµã€ã¯ã«ã®æåŸã®éšåãªã®ã§ãèšãããããšã®å šäœçãªçµæã®é åºã§äžèšã§èšããããšæããŸãã
ã«ãŒãã«ã¢ãžã¥ãŒã«ãŸãã¯ã«ãŒãã«ãžã®ãããã®äœæãéå§ãããšãæåã¯ç¡¬çŽæãæããŸããããã¯ãææžåãäžååãªã«ãŒãã«APIãæäŸããæ©èœã«ãã£ãŠã®ã¿å¶éããããããLinuxãã©ã€ããŒã®äœæããªã©ã®å€ãããã®æžç±ã§èª¬æãããŠããŸãã ãããããã®ã·ãªãŒãºã§èª¬æãããŠãããã®ãšåæ§ã®å®éšãããã³ä»ã®å€ãã®åæ§ã®å®éšã¯ãã«ãŒãã«ã¢ãžã¥ãŒã«ã§ãã¹ãŠã® ïŒäŸå€ãªãïŒïŒãŠãŒã¶ãŒç©ºéã®å¯èœæ§ïŒæ°ããããã»ã¹ãšã¹ã¬ããã®éå§ãUNIXã·ã°ãã«ã®éä¿¡ãªã©ïŒã«ã¢ã¯ã»ã¹ã§ããããšã瀺åããŠããŸãã ããã«ãç¹æš©ïŒã¹ãŒããŒãã€ã¶ãŒããªã³ã°0ïŒããã»ããµä¿è·ã¢ãŒãïŒç¹æš©ã³ãã³ããå éšããã»ããµã¬ãžã¹ã¿ãå²ã蟌ã¿å¿çïŒã«é¢é£ä»ãããããŠãŒã¶ãŒç©ºéã®éæäžå¯èœãªæ©èœã
ããã瀺ããŠãã ãã-ããã¯ããã®äžé£ã®èšäºã®äž»ãªç®æšã§ããããã©ã€ããŒãã¿ã¹ã¯ã®çœ®æãŸãã¯ã·ã¹ãã ã³ãŒã«ã®è¿œå ã ãã§ã¯ãããŸããã ã«ãŒãã«ã¢ãŒãã§ã®ããã°ã©ãã³ã°ã¯ãããã§ããªããç¥ã®ããã§ãããããã§ãã¹ãŠãå®è¡ã§ãããããªèªç±æãäœæããå¿ èŠããããŸãã ããããããã«ã¯é©åãªçšåºŠã®è²¬ä»»ãå¿ èŠã§ã...