Current Path :
/
opt
/
ds_agent
/
Or
Select Your Path :
Upload File :
New :
File
Dir
//opt/ds_agent/ds_am.init
#!/bin/bash drvdir="/opt/ds_agent" rtscan_dev=/dev/dsa_rtscan bm_dev=/dev/dsa_bmdev RET_CODE_SUCCEED=0 RET_CODE_DRIVER_NOT_FOUND=1 RET_CODE_DRIVER_LOAD_FAILED=2 RET_CODE_DRIVER_UNLOAD_FAILED=3 RET_CODE_CREATE_DEVICE_FAILED=4 RET_CODE_DESTROY_DEVICE_FAILED=5 RET_CODE_MACHINE_OWNER_KEY_NOT_FOUND=6 RET_CODE_MACHINE_OWNER_KEY_EXPIRED=7 RET_CODE_MACHINE_OWNER_KEY_UNKOWN=8 DS20_DER_NAME="DS20.der" DS20_DER_VALIDITY_NOT_BEFORE=20181128071950 DS20_DER_VALIDITY_NOT_AFTER=20241126071950 DS20_DER_X509_SIGN_KEY=5739d58b6ddc0e6bd8aad25be7a3c8b6af7bdc23 DS20_DER_PKCS7_SIGN_KEY=c79e5aa81cfbf1dd DS20V2_DER_NAME="DS20_v2.der" DS20V2_DER_VALIDITY_NOT_BEFORE=20201124092351 DS20V2_DER_VALIDITY_NOT_AFTER=20261024092351 DS20V2_DER_X509_SIGN_KEY=39d113faa9b73d6c43a9d23b9f55af9381958b97 DS20V2_DER_PKCS7_SIGN_KEY=ea828dccce76b891 DS2022_DER_NAME="DS2022.der" DS2022_DER_VALIDITY_NOT_BEFORE=20211126063249 DS2022_DER_VALIDITY_NOT_AFTER=20311124063249 DS2022_DER_X509_SIGN_KEY=9db8a5e911ed975b2274f35993fdf99aaf446960 DS2022_DER_PKCS7_SIGN_KEY=87f3753936c5db76 SUPPORT_KEYS="DS2022 DS20V2 DS20" for fd in $(ls /proc/$$/fd); do case "$fd" in 0|1|2|255) ;; *) eval "exec $fd>&-" ;; esac done # return code 0 indicates that module is being used by somebody, 1 otherwise moduleIsBeingUsed() { local module=${1} local usedby=$(cat /proc/modules | grep -m 1 "^${module}" | cut -d ' ' -f4) if [ "${usedby}" == "" ]; then return 1 elif [ "${usedby}" == "-" ]; then return 1 fi return 0 } moduleIsLoaded() { local module=${1} (lsmod | tr -d '[]' | grep -m 1 "^${module}" > /dev/null) && return 0 return 1 } moduleIsDisabled() { if [ "`cat /proc/driver/gsch/redirfs/enable`" == "1" ]; then return 1 fi if [ "`cat /proc/driver/gsch/fshook/enable`" == "1" ]; then return 1 fi if [ "`cat /proc/driver/gsch/syshook/enable`" == "1" ]; then return 1 fi return 0 } driverIsNotFound() { local tmhookPath="${drvdir}/`uname -r`/${tmhook}.ko" local bmhookPath="${drvdir}/`uname -r`/${bmhook}.ko" if [ ! -f ${tmhookPath} ] || [ ! -f ${bmhookPath} ]; then logger -t ds_am.init "The ds_am module is lack of KernelSupport package for kernel `uname -r`" return 0 fi return 1 } create_device_gsch() { rtscan_dev_major=`grep gsch /proc/devices |cut -d ' ' -f 1` if [ ! -z $rtscan_dev_major ]; then if [ ! -c $rtscan_dev ]; then mknod -m 0600 $rtscan_dev c $rtscan_dev_major 0 ret=$? if [ ${ret} -ne 0 ]; then logger -t ds_am.init "The ds_am module is trying to create device ${rtscan_dev} but failed" return ${RET_CODE_CREATE_DEVICE_FAILED} fi # For DISA STIG Compliance, label device file with SELinux file type 'misc_device_t'. if [ -x /usr/bin/chcon ] ; then /usr/bin/chcon -t misc_device_t ${rtscan_dev} fi fi fi return ${RET_CODE_SUCCEED} } destroy_device() { local dev_name=${1} rm -f $dev_name; ret=$? if [ ${ret} -ne 0 ]; then logger -t ds_am.init "The ds_am module is trying to destroy device ${dev_name} but failed" return ${RET_CODE_DESTROY_DEVICE_FAILED} fi return ${RET_CODE_SUCCEED} } create_device_bmhook() { bmhook_dev_major=`grep bmhook /proc/devices |cut -d ' ' -f 1` if [ ! -z $bmhook_dev_major ]; then if [ ! -c $bm_dev ]; then mknod -m 0600 $bm_dev c $bmhook_dev_major 0 ret=$? if [ ${ret} -ne 0 ]; then logger -t ds_am.init "The ds_am module is trying to create device ${bm_dev} but failed" return ${RET_CODE_CREATE_DEVICE_FAILED} fi # For DISA STIG Compliance, label device file with SELinux file type 'misc_device_t'. if [ -x /usr/bin/chcon ] ; then /usr/bin/chcon -t misc_device_t ${bm_dev} fi fi fi return ${RET_CODE_SUCCEED} } set_excl_to_proc() { ini_file=${1} proc_entry=${2} if [ -f $ini_file ]; then IFS=$'\n' for f in `sort -u $ini_file || cat $ini_file` ; do echo $f > $proc_entry ; done unset IFS fi } load_module_bm() { local tmhook="tmhook" local bmhook="bmhook" local tmhookPath="${drvdir}/`uname -r`/${tmhook}.ko" local bmhookPath="${drvdir}/`uname -r`/${bmhook}.ko" # note that right now tmhook may be being used by someone (e.g., gsch) # unload it only if it is ok to remove if moduleIsLoaded ${tmhook} ; then if ! moduleIsBeingUsed ${tmhook} ; then (lsmod | grep -m 1 ${tmhook} > /dev/null) && rmmod ${tmhook} fi fi if driverIsNotFound; then return ${RET_CODE_DRIVER_NOT_FOUND} fi if ! moduleIsLoaded ${tmhook} ; then insmod ${tmhookPath}; ret=$? if [ $ret -ne 0 ]; then logger -t ds_am.init "The ds_am module load driver ${tmhook} failed" return ${RET_CODE_DRIVER_LOAD_FAILED} fi ln -s -f ${tmhookPath} /lib/modules/`uname -r`/ > /dev/null 2>&1 fi if ! moduleIsLoaded ${bmhook} ; then insmod ${bmhookPath}; ret=$? if [ $ret -ne 0 ]; then logger -t ds_am.init "The ds_am module load driver ${bmhook} failed" return ${RET_CODE_DRIVER_LOAD_FAILED} fi ln -s -f ${bmhookPath} /lib/modules/`uname -r`/ > /dev/null 2>&1 fi if moduleIsLoaded ${bmhook} ; then echo 1 > /proc/driver/bmhook/ftime_innsec echo 1 > /proc/driver/bmhook/tmbpf/jit_enable echo 1 > /proc/driver/bmhook/enable set_excl_to_proc /var/opt/ds_agent/am/ds_am-exclude-process_img_path.ini /proc/driver/bmhook/exclude/process.any set_excl_to_proc /var/opt/ds_agent/am/procexcept.ini /proc/driver/bmhook/exclude/file_event/process.any set_excl_to_proc /var/opt/ds_agent/am/ds_am-exclude-dir.ini /proc/driver/bmhook/exclude/file_event/dir.any set_excl_to_proc /var/opt/ds_agent/am/ds_am-exclude-file.ini /proc/driver/bmhook/exclude/file_event/file.any # Update bmhook settings if [ -f /var/opt/ds_agent/am/bmhook.ini ]; then IFS=$'\n' for line in `cat /var/opt/ds_agent/am/bmhook.ini`; do k=`echo "$line"|cut -d = -f 1` v=`echo "$line"|cut -d = -f 2` if [ -e "/proc/driver/bmhook/config/$k" ]; then echo "$v" > /proc/driver/bmhook/config/$k fi done unset IFS fi if [ -n `grep ^OPENSHIFT /host/etc/os-release 2> /dev/null` ]; then echo 0 > /proc/driver/bmhook/config/cgroup_access fi return ${RET_CODE_SUCCEED} else logger -t ds_am.init "The ds_am module load driver ${bmhook} failed" return ${RET_CODE_DRIVER_LOAD_FAILED} fi } unload_module_bm() { local tmhook="tmhook" local bmhook="bmhook" moduleIsLoaded ${bmhook} && rmmod ${bmhook}; moduleIsLoaded ${bmhook} && sleep 1 && rmmod ${bmhook}; moduleIsLoaded ${bmhook} && sleep 1 && rmmod ${bmhook}; if [ -f /lib/modules/`uname -r`/${bmhook}.ko ]; then unlink /lib/modules/`uname -r`/${bmhook}.ko > /dev/null 2>&1; fi if ! moduleIsBeingUsed ${tmhook} ; then moduleIsLoaded ${tmhook} && rmmod ${tmhook}; moduleIsLoaded ${tmhook} && sleep 1 && rmmod ${tmhook}; moduleIsLoaded ${tmhook} && sleep 1 && rmmod ${tmhook}; if [ -f /lib/modules/`uname -r`/${tmhook}.ko ]; then unlink /lib/modules/`uname -r`/${tmhook}.ko > /dev/null 2>&1; fi fi if moduleIsLoaded ${bmhook}; then logger -t ds_am.init "The ds_am module unload driver ${bmhook} failed" return ${RET_CODE_DRIVER_UNLOAD_FAILED} fi return ${RET_CODE_SUCCEED} } load_module() { local moduleOneName="tmhook" local moduleTwoName="redirfs" local moduleThreeName="gsch" local moduleOnePath="${drvdir}/`uname -r`/${moduleOneName}.ko" local moduleTwoPath="${drvdir}/`uname -r`/${moduleTwoName}.ko" local moduleThreePath="${drvdir}/`uname -r`/${moduleThreeName}.ko" if moduleIsLoaded ${moduleOneName} -o moduleIsLoaded ${moduleTwoName} -o moduleIsLoaded ${moduleThreeName} ; then if moduleIsDisabled ; then (lsmod | grep -m 1 gsch > /dev/null) && rmmod gsch (lsmod | grep -m 1 redirfs > /dev/null) && rmmod redirfs # note that right now tmhook may be being used by someone (e.g., acdc) # unload it only if it is ok to remove if ! moduleIsBeingUsed ${moduleOneName} ; then (lsmod | grep -m 1 ${moduleOneName} > /dev/null) && rmmod ${moduleOneName} fi fi fi if ! moduleIsLoaded ${moduleOneName} ; then insmod ${moduleOnePath}; ln -s -f ${moduleOnePath} /lib/modules/`uname -r`/ > /dev/null 2>&1 fi if ! moduleIsLoaded ${moduleTwoName} ; then insmod ${moduleTwoPath}; ln -s -f ${moduleTwoPath} /lib/modules/`uname -r`/ > /dev/null 2>&1 fi if ! moduleIsLoaded ${moduleThreeName} ; then insmod ${moduleThreePath}; ln -s -f ${moduleThreePath} /lib/modules/`uname -r`/ > /dev/null 2>&1 fi if moduleIsLoaded ${moduleThreeName} ; then if [ -f /var/opt/ds_agent/am/ds_am-exclude-dir.ini ]; then for f in `cat /var/opt/ds_agent/am/ds_am-exclude-dir.ini` ; do echo $f > /proc/driver/gsch/scan/exclusion/dir; done fi if [ -f /var/opt/ds_agent/am/ds_am-exclude-file.ini ]; then for f in `cat /var/opt/ds_agent/am/ds_am-exclude-file.ini` ; do echo $f > /proc/driver/gsch/scan/exclusion/file; done fi echo 1 > /proc/driver/gsch/scan/enable return 0; else return 1; fi } unload_module() { if [ -f /proc/driver/gsch/syshook/enable ]; then echo 0 > /proc/driver/gsch/syshook/enable; fi if [ -f /proc/driver/gsch/fshook/enable ]; then echo 0 > /proc/driver/gsch/fshook/enable; fi if [ -f /proc/driver/gsch/redirfs/enable ]; then echo 0 > /proc/driver/gsch/redirfs/enable; fi (lsmod | grep -m 1 gsch > /dev/null) && rmmod gsch (lsmod | grep -m 1 gsch > /dev/null) && sleep 1 && rmmod gsch (lsmod | grep -m 1 gsch > /dev/null) && sleep 1 && rmmod gsch (lsmod | grep -m 1 redirfs > /dev/null) && rmmod redirfs if [ -f /lib/modules/`uname -r`/gsch.ko ]; then unlink /lib/modules/`uname -r`/gsch.ko > /dev/null 2>&1; fi if [ -f /lib/modules/`uname -r`/redirfs.ko ]; then unlink /lib/modules/`uname -r`/redirfs.ko > /dev/null 2>&1; fi # note that right now tmhook may be being used by someone (e.g., acdc) # unload it only if it is ok to remove if ! moduleIsBeingUsed tmhook ; then (lsmod | grep -m 1 tmhook > /dev/null) && rmmod tmhook if [ -f /lib/modules/`uname -r`/tmhook.ko ]; then unlink /lib/modules/`uname -r`/tmhook.ko > /dev/null 2>&1; fi fi } check_intercepted() { # before DS-11.x, we implemented a mechanism to avoid inter-op issues # with 3rd-party kernel module, and this check is to test if there is # a kernel module hooking the same system calls. # # after adapting tmhook, gsch does not directly manipulate syscall table, # but we still need this to make sure the older gsch can be unloaded after # agent upgrade. local moduleThreeName="gsch" local returnCode="0" if moduleIsLoaded ${moduleThreeName} ; then if [ -f /proc/driver/gsch/syshook/intercepted ]; then returnCode="$(cat /proc/driver/gsch/syshook/intercepted)" if [ "$returnCode" -eq "0" ]; then logger -t ds_am.init "The ds_am module is attempting to start and another kernel module that was running using the gsch driver is now unloaded. The gsch driver will be unloaded and then loaded again." unload_module destroy_device ${rtscan_dev} fi if [ "$returnCode" -eq "1" ]; then logger -t ds_am.init "The ds_am module is attempting to start but another kernel module is running using the gsch driver. The gsch driver may not be updated unless another kernel module is unloaded." create_device_gsch # Used to check the device node still exists. When it was removed, we would create a new one. exit 1 fi fi fi } check_machine_owner_keys() { # check if we have mokutil on the system local mokUtil=`which mokutil 2>/dev/null` if [ -z "${mokUtil}" ]; then return ${RET_CODE_SUCCEED} fi # check if the system is booted with secure boot enabled secureBootState=`$mokUtil --sb-state 2>/dev/null | grep enabled` if [ -z "${secureBootState}" ]; then return ${RET_CODE_SUCCEED} fi # check if we have related key enrolled local bmhook=${drvdir}/`uname -r`/bmhook.ko local moduleSignkey=`modinfo ${bmhook} | grep sig_key | awk '{print $2}' | sed 's/://g' | tr 'A-Z' 'a-z'` local importedTMKeys=`cat /proc/keys | grep ${moduleSignkey}` local currentTime=`date -u +"%Y%m%d%H%M%S"` local timeOutString=`echo ${importedTMKeys} | awk '{print $4}'` if [ -n "${importedTMKeys}" ]; then # The key is enrolled on the system if [ "${timeOutString}" == "perm" ]; then # This key is a permanent key from kernel point of view return ${RET_CODE_SUCCEED} fi # we have related key enrolled, check its validity for key in ${SUPPORT_KEYS}; do target_name="${key}_DER_NAME" target_x509_sign_key="${key}_DER_X509_SIGN_KEY" target_pkcs7_sign_key="${key}_DER_PKCS7_SIGN_KEY" target_validity_not_before="${key}_DER_VALIDITY_NOT_BEFORE" target_validity_not_after="${key}_DER_VALIDITY_NOT_AFTER" if [ "${!target_x509_sign_key}" == "${moduleSignkey}" ] || [ "${!target_pkcs7_sign_key}" == "${moduleSignkey}" ]; then # this key is in our support key lists if [ ${!target_validity_not_before} -lt $currentTime ] && [ $currentTime -le ${!target_validity_not_after} ]; then return ${RET_CODE_SUCCEED} else logger -t ds_am.init "The ds_am module found the enrolled key ${!target_name} has expired" return ${RET_CODE_MACHINE_OWNER_KEY_EXPIRED} fi fi done # key is enrolled, however, we don't recognize it logger -t ds_am.init "The ds_am module found driver is signed with unknown sign key ${moduleSignkey}, and is enrolled: \"${importedTMKeys}\"" return ${RET_CODE_MACHINE_OWNER_KEY_UNKOWN} else # The key is not enrolled on the system for key in ${SUPPORT_KEYS}; do target_name="${key}_DER_NAME" target_x509_sign_key="${key}_DER_X509_SIGN_KEY" target_pkcs7_sign_key="${key}_DER_PKCS7_SIGN_KEY" if [ "${!target_x509_sign_key}" == "${moduleSignkey}" ] || [ "${!target_pkcs7_sign_key}" == "${moduleSignkey}" ]; then logger -t ds_am.init "The ds_am module found missing key ${!target_name}, please enroll it first" return ${RET_CODE_MACHINE_OWNER_KEY_NOT_FOUND} fi done # Key is not enrolled, and we don't recognize it # Two possible cases: # 1. The key is from Trend, not yet supported by this script # 2. Driver is signed with an unknown key outside Trend. logger -t ds_am.init "The ds_am module found driver is signed with unknown sign key ${moduleSignkey}, and is not enrolled" return ${RET_CODE_MACHINE_OWNER_KEY_UNKOWN} fi } start() { check_intercepted; load_module; create_device_gsch; return 0; } stop() { # before DS-11.x, we implemented a mechanism to avoid inter-op issues # with 3rd-party kernel module, and this check is to test if there is # a kernel module hooking the same system calls. # # after adapting tmhook, gsch does not directly manipulate syscall table, # but we still need this to make sure the older gsch can be unloaded after # agent upgrade. local returnCode="0" if [ -f /proc/driver/gsch/syshook/intercepted ]; then returnCode="$(cat /proc/driver/gsch/syshook/intercepted)" if [ "$returnCode" -eq "1" ]; then logger -t ds_am.init "The ds_am module is attempting to stop but another kernel module is running using the gsch driver. The ds_agent process will be stopped but the gsch driver will not be unloaded." destroy_device ${rtscan_dev} exit 1 fi fi unload_module; destroy_device ${rtscan_dev}; return 0 } restart() { stop start } check_and_set_cgroup_path() { if [ ! -z "$1" ]; then local t1=`echo "$1" | awk '{print $1}'` local t2=`echo "$1" | awk '{print $2}'` local t3=`echo "$1" | awk '{print $3}'` local bm_cgroup_base="/proc/driver/bmhook/config/cgroup_base" logger -t ds_am.init "check_and_set_cgroup_path, t1:${t1}" logger -t ds_am.init "check_and_set_cgroup_path, t2:${t2}" logger -t ds_am.init "check_and_set_cgroup_path, t3:${t3}" if [[ "${t1}" == "$2" ]]; then if [ "${t2}" == "on" ]; then echo "${t3}" > ${bm_cgroup_base} logger -t ds_am.init "check_and_set_cgroup_path, set cgroup_base as ${t3}" return 0 fi fi fi logger -t ds_am.init "check_and_set_cgroup_path, invalid format for $2" return 1 } update_bm_cgroup_path() { local v1_path=`mount | grep cgroup | grep /memory` local v2_path=`mount | grep cgroup2` logger -t ds_am.init "update_bm_cgroup_path, v1_path: ${v1_path}" logger -t ds_am.init "update_bm_cgroup_path, v2_path: ${v2_path}" if [ ! -z "${v1_path}" ]; then check_and_set_cgroup_path "${v1_path}" "cgroup" ret=$? if [ ${ret} -eq 0 ]; then return 0 fi fi if [ ! -z "${v2_path}" ]; then check_and_set_cgroup_path "${v2_path}" "cgroup2" ret=$? if [ ${ret} -eq 0 ]; then return 0 fi fi logger -t ds_am.init "update_bm_cgroup_path, failed to set cgroup_base" return 1 } startBM() { local ret=${RET_CODE_SUCCEED} load_module_bm; ret=$? if [ ${ret} -ne ${RET_CODE_SUCCEED} ]; then if [ ${ret} -eq ${RET_CODE_DRIVER_LOAD_FAILED} ]; then check_machine_owner_keys ret2=$? if [ ${ret2} -ne ${RET_CODE_SUCCEED} ]; then # Load driver failed is related to enrolled keys in secure boot environment, # overwrite return code (ret) ret=${ret2} fi fi return ${ret} fi create_device_bmhook; ret=$? if [ ${ret} -ne ${RET_CODE_SUCCEED} ]; then return ${ret} fi update_bm_cgroup_path; return ${RET_CODE_SUCCEED} } stopBM() { local ret=${RET_CODE_SUCCEED} unload_module_bm; ret=$? if [ ${ret} -ne ${RET_CODE_SUCCEED} ]; then return ${ret} fi destroy_device ${bm_dev}; ret=$? if [ ${ret} -ne ${RET_CODE_SUCCEED} ]; then return ${ret} fi return ${RET_CODE_SUCCEED} } restartBM() { stopBM startBM } stopAll() { # used for AM.dsp to unload all kernel modules when ds_am process is terminated stopBM stop } case "$1" in start|stop|restart|startBM|stopBM|restartBM|stopAll) $1 ;; *) echo $"Usage: $0 {start|stop|restart|startBM|stopBM|restartBM|stopAll}" exit 1 esac