#! /bin/awk -f # ## Linux Security Module (LSM) bootstrap script # ## Generates skeleton hook functions for use with the # struct security_operations generated by lsm-genstruct.awk # # Usage: lsm-skeleton.awk [-vraw=1] -vp=PREFIX LINUX_INC_PATH/linux/security.h # raw=1: do not format the code using Linux style indentation. # PREFIX: replace with the base name of the model # LINUX_INC_PATH: path to the header files of the kernel the module # is being developed for, may be "include" if you are # inside the kernel source tree. # # BUGS: argument lists are parsed incorrectly if there is something in between # the argument name and the trailing comma or ");" like the comment in the # hook task_post_setuid. # ## GPL 2004 Manfred Waßmann http://www.berlinos.de/ ## # # Copyright (C) 2004 Manfred Waßmann http://www.berlinos.de/ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2, # as published by the Free Software Foundation. # # lsm-skeleton.awk,v 1.11 2005-10-07 19:52:12 manolo Exp # BEGIN{o=p"_hooks.c";out=o".tmp"; iop="-kr -i8 -ts8 -br -ce -bap -sob -l80 -pcs -cs -ss -bs -di1 -nbc -lp -psl"; #check args if(p){P=toupper(p);} else{ print"Usage "ARGV[0]" [-vraw=1] -vp= <.../linux/security.h>\n"; rc=64;exit(rc)}; #Check for existing output file if(!system("test -e "o)){ print"Output file "o" already exists -- aborting!"; rc=17;exit(rc); } print"/* This file was initially generated with lsm-genskel.awk -- edit with care,"\ "\n * you may want to diff it with a freshly generated version on kernel upgrades!\n */\n"\ "#include \t/* CONFIG_* */\n"\ "#ifdef CONFIG_MODVERSIONS\n"\ "# ifndef MODVERSIONS\n"\ "# define MODVERSIONS\n"\ "# endif\n"\ "# include \n"\ "#endif\n"\ "#include \n"\ "#include \n"\ "#include \n">out; ORS="";}; /^#include /{print$0"\n">out} /^struct security_operations {/,/^};/{#inside struct definition if(!beenhere){ beenhere=1; print"\nextern struct security_operations *security_ops;\n"\ "static struct security_operations *next;"\ "\nstatic char *nextname;\n\n"\ "/** Stub function to register subsequent module.\n * "\ "Call this from "p"_register_security\n */\n"\ "static int register_next( const char *name, struct security_operations *ops)\n"\ "{\n\tif(nextname||!name||!ops){return(-EINVAL);}\n\t"\ "MOD_INC_USE_COUNT;\n\t"\ "nextname = (char*)name;\n\tnext = ops;\n\treturn(0);\n"\ "}\n\n"\ "/** Stub function to unregister subsequent module.\n * "\ "Call this from "p"_unregister_security\n */\n"\ "static int unregister_next( const char *name, struct security_operations *ops)\n"\ "{\n\tif (!nextname||!name||strcmp(nextname,name)){return(-EINVAL);}\n\t"\ "nextname = NULL;\n\tnext = security_ops;\n\t"\ "MOD_DEC_USE_COUNT;\n\treturn(0);\n"\ "}\n\n"\ "void __init "p"_hooks_init(void)\n{\n\tnext = security_ops;\n}\n\n\n"\ "/* *** Hook functions *** */\n\n\n">out;} match($1,"^#");if(RLENGTH>0){print$0"\n">out} else{ t=$1; match($2,"^\(\*[0-9a-zA-Z_]+\)$");if(RLENGTH>0){ h=substr($2,3,RLENGTH-3);#hook name print"static "$1" "p"_"h"">out;#function declaration starts na=0;#number args for(i=2;++iout; match($i,"[0-9A-Z_a-z]+,"); if(RLENGTH>0)A[++na]=substr($i,RSTART,RLENGTH-1)}#gather function args while(substr($NF,length($NF))!=";"){#find end of decl print$NF"\n\t\t">out; i=NF;match($i,"[0-9A-Z_a-z]+,"); if(RLENGTH>0)A[++na]=substr($i,RSTART,RLENGTH-1);#gather function args if(getline==1){ for(i=0;++iout; match($i,"[0-9A-Z_a-z]+,"); if(RLENGTH>0)A[++na]=substr($i,RSTART,RLENGTH-1)}}#gather fun args else{break}} print substr($NF,1,length($NF)-1)>out; match($NF,"[0-9A-Z_a-z]+"); if(RLENGTH>0&&$NF!~"void\);")A[++na]=substr($NF,RSTART,RLENGTH); print"\n{\n\t">out; if(t=="int")print"return( ">out; print"next->"h"("(na?" "A[1]:"")>out;for(i=1;i++out; if(t=="int")print")">out; print");\n}\n\n">out; } } } END{if(rc)exit(rc); print"#ifdef "P"_SECOPS_H\n"\ "# error Header file "p"_secops.h loaded in the wrong place!\n"\ "#endif\n"\ "/* The security_operations structure must be kept in sync with linux/security.h.\n"\ " * To facilitate this it is defined inside its proper header file that can be\n"\ " * generated using this awk script from within the appropriate kernel source\n"\ " * directory:\n\n"\ " awk 'BEGIN{"\ "print\"/\"\"*\\n * This is a generated file! DO NOT EDIT !\\n *\""\ "\"/\\n\\n\"\\\n"\ " \"#ifndef "P"_SECOPS_H\\n#define "P"_SECOPS_H\\n\\n\"\\\n"\ " \"struct security_operations "p"_security_ops = {\"};\n"\ " /^struct security_operations {/,/^};/ {\n"\ " match($1,\"^#\");if(RLENGTH>0)print$0;\n"\ " match($2,\"^\(\*[0-9a-zA-Z_]+\)$\");if(RLENGTH>0){h=substr($2,3,RLENGTH-3);\n"\ " print\"\\t.\"h\" = \"p\"_\"h\",\";};};\n"\ " END{print\"};\\n\\n#endif\";\n"\ " }' -vp="p" include/linux/security.h |tee "p"_secops.h\n"\ "\n */\n"\ "#include \""p"_secops.h\"\n\n">out; if(raw){ system("mv -f "out" "o); }else{ system("indent "iop" -o "o" "out" && rm -f "out); } print" *** Output written to: "o" *** \n"\ " *** You may need to edit some functions, e.g. if they include"\ " comments after *** \n *** args in their prototype "\ "(like task_post_setuid as of 2.4.26 and 2.6.6). *** \n"; }