免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: rabbitte
打印 上一主题 下一主题

[新手入门] 内核扩展正常卸载后仍在可以通过genkex获取到? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2014-08-08 10:48 |只看该作者
贴程序出来吧,我搞死过很多次机器,但从没有卸不掉还返回0的(有出错返回卸不掉的时候)。

论坛徽章:
2
技术图书徽章
日期:2014-04-23 10:23:38射手座
日期:2014-08-14 17:00:52
12 [报告]
发表于 2014-08-11 10:44 |只看该作者
回复 11# orian
  1. struct cfg_load ext_load;
  2. int main(int argc, char **argv)
  3. {

  4.     struct cfg_kmod opt_kmod;
  5.     char c, modname[256] = {'\0'};
  6.     struct stat statbuf;
  7.     int rc;
  8.     int ret;

  9.     if (argc != 2) {
  10.         printf("Usage: %s <kernel_extension>\n", argv[0]);
  11.         exit(EINVAL);
  12.     }

  13.     strcpy(modname, argv[1]);
  14.     if (stat(modname, &statbuf) != 0) {
  15.         perror("stat");
  16.         exit(errno);
  17.     }

  18.     printf("Enter choice:(1)oad, (u)nload\n");
  19.     while((c = getchar()) < 'a' && c > 'z')
  20.         ;

  21.     switch (c) {
  22.     case 'l':
  23.         ext_load.path = modname;
  24.         ext_load.libpath = NULL;
  25.         ext_load.kmid = 0;

  26.         if (sysconfig(SYS_KLOAD, &ext_load, sizeof(struct cfg_load))) {
  27.             printf("Error in loading extension. errno=%d\n", errno);
  28.             exit(1);
  29.         } else {
  30.             printf("Extension Successfully loaded, kmid is %d.\n", ext_load.kmid);
  31.         }

  32.         opt_kmod.kmid = ext_load.kmid;
  33.         opt_kmod.cmd = CFG_INIT;
  34.         opt_kmod.mdiptr = NULL;
  35.         opt_kmod.mdilen = 0;
  36.         if (sysconfig(SYS_CFGKMOD,&opt_kmod,sizeof(struct cfg_kmod)) )
  37.             perror("sysconfig(SYS_CFGKMOD)");  
  38.         else
  39.             printf("Extension Initialized \n");
  40.         break;
  41.     case 'u':        
  42.         ext_load.path = modname;
  43.         ext_load.libpath = NULL;

  44.         if(sysconfig(SYS_QUERYLOAD, &ext_load, sizeof(struct cfg_load))){
  45.             printf("Error while querying.\n");
  46.         }
  47.       
  48.         if (ext_load.kmid == 0) {
  49.             fprintf(stderr, "Extension not loaded.\n");
  50.         } else {
  51.             opt_kmod.kmid = ext_load.kmid;
  52.             opt_kmod.cmd = CFG_TERM;
  53.             opt_kmod.mdiptr = NULL;
  54.             opt_kmod.mdilen = 0;
  55.             if (sysconfig(SYS_CFGKMOD, &opt_kmod, sizeof(struct cfg_kmod))) {
  56.                 perror("sysconfig(SYS_CFGKMOD)");
  57.             } else {
  58.                 fprintf(stderr, "Kernel Extension Terminated. mid=%d\n", opt_kmod.kmid);
  59.             }
  60.         }

  61.         if(sysconfig(SYS_KULOAD, &ext_load, sizeof(struct cfg_load))){
  62.             printf("Error in unloading extension.mid=%d, errno=%d\n",  ext_load.kmid, errno);
  63.             
  64.         } else {
  65.             printf("Extension Successfully unloaded. mid=%d\n", ext_load.kmid);
  66.         }  
  67.         break;
  68.     default:
  69.         printf("Incorret option\n");
  70.         break;
  71.     }

  72.     return 0;
  73. }
复制代码

论坛徽章:
0
13 [报告]
发表于 2014-08-11 12:26 |只看该作者
这几个地方有点混乱

if(sysconfig(SYS_QUERYLOAD, &ext_load, sizeof(struct cfg_load))){
            printf("Error while querying.\n");
        }
      
//既然查询已经出错,应当直接break出去,不能继续判断kmid==0,虽然通常查询不对,kmid也应当是0,但也可能系统就没改,原来是什么,还是什么。

        if (ext_load.kmid == 0) {
            fprintf(stderr, "Extension not loaded.\n");
        } else {
            opt_kmod.kmid = ext_load.kmid;
            opt_kmod.cmd = CFG_TERM;
            opt_kmod.mdiptr = NULL;
            opt_kmod.mdilen = 0;
            if (sysconfig(SYS_CFGKMOD, &opt_kmod, sizeof(struct cfg_kmod))) {
                perror("sysconfig(SYS_CFGKMOD)");
            } else {
                fprintf(stderr, "Kernel Extension Terminated. mid=%d\n", opt_kmod.kmid);
            }
        }
//term如果执行错误,也应当退出,而不能继续unload

        if(sysconfig(SYS_KULOAD, &ext_load, sizeof(struct cfg_load))){
            printf("Error in unloading extension.mid=%d, errno=%d\n",  ext_load.kmid, errno);
            
        } else {
            printf("Extension Successfully unloaded. mid=%d\n", ext_load.kmid);
        }  

论坛徽章:
2
技术图书徽章
日期:2014-04-23 10:23:38射手座
日期:2014-08-14 17:00:52
14 [报告]
发表于 2014-08-11 16:14 |只看该作者
回复 13# orian


    看aix的文档时发现有一个slibclean命令,在卸载一个模块后执行slibclean命令后,在通过genkex执行后两个模块就不存在了。
    但是并不是百分之百的情况下都是如此。。

论坛徽章:
0
15 [报告]
发表于 2014-08-12 06:16 |只看该作者
你所说的sysconfig unload返回0是指在哪一步?我不确认是否是程序中前一步已经出错,后面继续unload返回0还是别的情况。最好每当前一步出错就让程序直接退出,不要继续执行后面的操作,前面已经错误,后面的结果很可能是不确定的0或者非0都不一定代表原意。

论坛徽章:
2
技术图书徽章
日期:2014-04-23 10:23:38射手座
日期:2014-08-14 17:00:52
16 [报告]
发表于 2014-08-12 10:25 |只看该作者
orian 发表于 2014-08-12 06:16
你所说的sysconfig unload返回0是指在哪一步?我不确认是否是程序中前一步已经出错,后面继续unload返回0还 ...


按照您说的方法,我把所有返回error的地方都直接退出,再次执行还是跟之前的运行结果一样。说明加载和卸载都是正常的。

unload分两个步骤:
先sysconfig(SYS_CFGKMOD)赋值CFG_TERM命令终止内核扩展,再sysconfig(SYS_KULOAD)卸载;
这两个操作都是返回0的。而且这两步我都打印了mod number,是一致的。
但是mod明显没有被卸载,因为我在一些基本的syscall中有打印语句,卸载之后还是会打印语句。

论坛徽章:
0
17 [报告]
发表于 2014-08-13 11:47 |只看该作者
kernel extension本身呢?把kernel extension configure调用贴出来看看?里面是你自己写的东西,只要case CFG_TERM部分你让它返回0,sysconfig(...CFG_TERM)就得到0,如果程序里面没有unpin,锁没清等等,sysconfig也不能把程序卸载掉。

论坛徽章:
2
技术图书徽章
日期:2014-04-23 10:23:38射手座
日期:2014-08-14 17:00:52
18 [报告]
发表于 2014-08-13 15:08 |只看该作者
orian 发表于 2014-08-13 11:47
kernel extension本身呢?把kernel extension configure调用贴出来看看?里面是你自己写的东西,只要case C ...


两个内核扩展的配置函数基本一样的,都是打印语句直接返回。
  1. int kernex_config(int cmd, struct uio *uio)
  2. {
  3.     int ret = -1;

  4.     bsdlog(LOG_KERN | LOG_KERN, "Enter old_syscall command = 0x%x\n", cmd);

  5.     if (cmd == CFG_INIT) {
  6.         bsdlog(LOG_DEBUG | LOG_KERN, "Initializing..\n");
  7.     } else if (cmd == CFG_TERM) {
  8.         bsdlog(LOG_DEBUG | LOG_KERN, "Terminating...\n");
  9.     } else
  10.         bsdlog(LOG_DEBUG | LOG_KERN, "Unknow command to adv kernExt\n");

  11.     return 0;
  12. }
复制代码
除了配置函数,其他函数就是系统调用替换了。
按照您所说,我这里应该是直接返回0了。没有对已经替换的syscall做处理,加载的时候是为了替换,卸载的时候应该将syscall还原回去。不知道还原的方法是?删除导出的exp文件?

论坛徽章:
0
19 [报告]
发表于 2014-08-13 20:37 |只看该作者
哦,最后一句话说明了问题。你用新调用替换了kernel中已有的调用,我不知道你替换了哪些,但这种做法是非正规的方案,结果未知。想来情况是这样:
如果你term的时候有别的程序调用被替换掉的调用,则unload不能释放该程序段(因为在使用中),如果过后使用结束,引用值清0,slibclean就能unload,如果还是有人用,就unload不掉。至于为什么sysconfig返回0,这是因为这种方式是不支持的方式,sysconfig返回什么都是可能的,你没有遇到kernel crash已经很幸运了。。。

aix支持动态内核扩展,但不支持动态内核替换(目前不支持,正在研究用变通的方法支持这个,好像是通过做一次虚拟的lpm实现),所以,出现任何情况都是正常的,请原谅这句话的说法,但这就是事实。

论坛徽章:
2
技术图书徽章
日期:2014-04-23 10:23:38射手座
日期:2014-08-14 17:00:52
20 [报告]
发表于 2014-08-14 09:42 |只看该作者
回复 19# orian


    谢谢您回复。
    符号导入导出这种不是官方手册上说了吗,通过内核扩展可以导出新的系统调用。
    那您指的正规方法是?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP