mod-denylist.sh 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #! /bin/bash
  2. # shellcheck disable=SC2164
  3. RpmDir=$1
  4. ModDir=$2
  5. Dir="$1/$2"
  6. # Note the list filename must have the format mod-[PACKAGE].list, for example,
  7. # mod-internal.list or mod-extra.list. The PACKAGE is used to create a
  8. # override directory for the modules.
  9. List=$3
  10. Dest="$4"
  11. blacklist()
  12. {
  13. cat > "$RpmDir/etc/modprobe.d/$1-blacklist.conf" <<-__EOF__
  14. # This kernel module can be automatically loaded by non-root users. To
  15. # enhance system security, the module is blacklisted by default to ensure
  16. # system administrators make the module available for use as needed.
  17. # See https://access.redhat.com/articles/3760101 for more details.
  18. #
  19. # Remove the blacklist by adding a comment # at the start of the line.
  20. blacklist $1
  21. __EOF__
  22. }
  23. check_blacklist()
  24. {
  25. mod=$(find "$RpmDir/$ModDir" -name "$1")
  26. [ ! "$mod" ] && return 0
  27. if modinfo "$mod" | grep -q '^alias:\s\+net-'; then
  28. mod="${1##*/}"
  29. mod="${mod%.ko*}"
  30. echo "$mod has an alias that allows auto-loading. Blacklisting."
  31. blacklist "$mod"
  32. fi
  33. }
  34. find_depends()
  35. {
  36. dep=$1
  37. depends=$(modinfo "$dep" | sed -n -e "/^depends/ s/^depends:[ \t]*//p")
  38. [ -z "$depends" ] && exit
  39. for mod in ${depends//,/ }
  40. do
  41. match=$(grep "^$mod.ko" "$ListName")
  42. [ -z "$match" ] && continue
  43. # check if the module we are looking at is in mod-* too.
  44. # if so we do not need to mark the dep as required.
  45. mod2=${dep##*/} # same as $(basename $dep), but faster
  46. match2=$(grep "^$mod2" "$ListName")
  47. if [ -n "$match2" ]
  48. then
  49. #echo $mod2 >> notreq.list
  50. continue
  51. fi
  52. echo "$mod".ko >> req.list
  53. done
  54. }
  55. foreachp()
  56. {
  57. P=$(nproc)
  58. bgcount=0
  59. while read -r mod; do
  60. $1 "$mod" &
  61. bgcount=$((bgcount + 1))
  62. if [ $bgcount -eq "$P" ]; then
  63. wait -n
  64. bgcount=$((bgcount - 1))
  65. fi
  66. done
  67. wait
  68. }
  69. # Destination was specified on the command line
  70. test -n "$4" && echo "$0: Override Destination $Dest has been specified."
  71. pushd "$Dir"
  72. OverrideDir=$(basename "$List")
  73. OverrideDir=${OverrideDir%.*}
  74. OverrideDir=${OverrideDir#*-}
  75. mkdir -p "$OverrideDir"
  76. rm -rf modnames
  77. find . -name "*.ko" -type f > modnames
  78. # Look through all of the modules, and throw any that have a dependency in
  79. # our list into the list as well.
  80. rm -rf dep.list dep2.list
  81. rm -rf req.list req2.list
  82. touch dep.list req.list
  83. cp "$List" .
  84. # This variable needs to be exported because it is used in sub-script
  85. # executed by xargs
  86. ListName=$(basename "$List")
  87. export ListName
  88. foreachp find_depends < modnames
  89. sort -u req.list > req2.list
  90. sort -u "$ListName" > modules2.list
  91. join -v 1 modules2.list req2.list > modules3.list
  92. while IFS= read -r mod
  93. do
  94. # get the path for the module
  95. modpath=$(grep /"$mod" modnames)
  96. [ -z "$modpath" ] && continue
  97. echo "$modpath" >> dep.list
  98. done < modules3.list
  99. sort -u dep.list > dep2.list
  100. if [ -n "$Dest" ]; then
  101. # now move the modules into the $Dest directory
  102. while IFS= read -r mod
  103. do
  104. newpath=$(dirname "$mod" | sed -e "s/kernel\\//$Dest\//")
  105. mkdir -p "$newpath"
  106. mv "$mod" "$newpath"
  107. echo "$mod" | sed -e "s/kernel\\//$Dest\//" | sed -e "s|^.|${ModDir}|g" >> "$RpmDir"/"$ListName"
  108. done < dep2.list
  109. fi
  110. popd
  111. if [ -z "$Dest" ]; then
  112. sed -e "s|^.|${ModDir}|g" "$Dir"/dep2.list > "$RpmDir/$ListName"
  113. echo "$RpmDir/$ListName created."
  114. [ -d "$RpmDir/etc/modprobe.d/" ] || mkdir -p "$RpmDir/etc/modprobe.d/"
  115. foreachp check_blacklist < "$List"
  116. fi
  117. # Many BIOS-es export a PNP-id which causes the floppy driver to autoload
  118. # even though most modern systems don't have a 3.5" floppy driver anymore
  119. # this replaces the old die_floppy_die.patch which removed the PNP-id from
  120. # the module
  121. floppylist=("$RpmDir"/"$ModDir"/kernel/drivers/block/floppy.ko*)
  122. if [[ -n ${floppylist[0]} && -f ${floppylist[0]} ]]; then
  123. blacklist "floppy"
  124. fi
  125. # avoid an empty kernel-extra package
  126. echo "$ModDir/$OverrideDir" >> "$RpmDir/$ListName"
  127. pushd "$Dir"
  128. rm modnames dep.list dep2.list req.list req2.list
  129. rm "$ListName" modules2.list modules3.list
  130. popd