xref: /aosp_15_r20/system/sepolicy/tools/sepolicy_cleanup_check.sh (revision e4a36f4174b17bbab9dc043f4a65dc8d87377290)
1*e4a36f41SAndroid Build Coastguard Worker#!/bin/bash
2*e4a36f41SAndroid Build Coastguard Worker
3*e4a36f41SAndroid Build Coastguard Worker# This script uses some heuristics to suggest potential ways to clean up SELinux policy.
4*e4a36f41SAndroid Build Coastguard Worker# As these are heuristics, not everything it outputs is an error.
5*e4a36f41SAndroid Build Coastguard Worker# It is better to run this on device-specific policy rather than core policy.
6*e4a36f41SAndroid Build Coastguard Worker# It requires a device connected to adb.
7*e4a36f41SAndroid Build Coastguard Worker# Usage:
8*e4a36f41SAndroid Build Coastguard Worker#   ./sepolicy_cleanup_check.sh <sepolicy source path> [serial]
9*e4a36f41SAndroid Build Coastguard Worker
10*e4a36f41SAndroid Build Coastguard Workerif [[ $# -lt 1 ]]; then
11*e4a36f41SAndroid Build Coastguard Worker  echo "Usage: $0 <sepolicy source path> [serial]"
12*e4a36f41SAndroid Build Coastguard Worker  exit
13*e4a36f41SAndroid Build Coastguard Workerfi
14*e4a36f41SAndroid Build Coastguard Worker
15*e4a36f41SAndroid Build Coastguard Workersedir=$1
16*e4a36f41SAndroid Build Coastguard Workershift
17*e4a36f41SAndroid Build Coastguard Worker
18*e4a36f41SAndroid Build Coastguard Workeradb_cmd="adb"
19*e4a36f41SAndroid Build Coastguard Workerif [[ $# -eq 1 ]]; then
20*e4a36f41SAndroid Build Coastguard Worker  adb_cmd="$adb_cmd -s $1"
21*e4a36f41SAndroid Build Coastguard Worker  shift
22*e4a36f41SAndroid Build Coastguard Workerfi
23*e4a36f41SAndroid Build Coastguard Worker
24*e4a36f41SAndroid Build Coastguard Worker$adb_cmd shell id &>/dev/null
25*e4a36f41SAndroid Build Coastguard Workerif [[ $? -ne 0 ]]; then
26*e4a36f41SAndroid Build Coastguard Worker  echo "Please plug in a device and/or specify a serial"
27*e4a36f41SAndroid Build Coastguard Worker  adb devices
28*e4a36f41SAndroid Build Coastguard Worker  exit
29*e4a36f41SAndroid Build Coastguard Workerfi
30*e4a36f41SAndroid Build Coastguard Worker
31*e4a36f41SAndroid Build Coastguard Workerecho "Warning: this file uses heuristics, so all of its outputs are not necessarily errors."
32*e4a36f41SAndroid Build Coastguard Workerecho "For example, when run on core policy, it will likely find many things that do not exist on a given device but might exist on others."
33*e4a36f41SAndroid Build Coastguard Worker
34*e4a36f41SAndroid Build Coastguard Workerecho
35*e4a36f41SAndroid Build Coastguard Workerecho "Scanning for labels that are not assigned to any files."
36*e4a36f41SAndroid Build Coastguard Worker# Find all types.
37*e4a36f41SAndroid Build Coastguard Workergrep -r "^type " --exclude=\*.go $sedir --exclude=\*_macros | sed 's/^.*:.*type \([^,]*\)*.*$/\1/' | sort | uniq | while read -r type; do
38*e4a36f41SAndroid Build Coastguard Worker  # Find types that are not referenced in *_contexts.
39*e4a36f41SAndroid Build Coastguard Worker  if [[ `find $sedir -name "*_contexts" -not -path "*prebuilts*" -exec grep $type '{}' \; |wc -l` -eq 0 ]]; then
40*e4a36f41SAndroid Build Coastguard Worker    echo "None for $type"
41*e4a36f41SAndroid Build Coastguard Worker    grep -r $type --exclude-dir=prebuilts --exclude=\*.cil $sedir
42*e4a36f41SAndroid Build Coastguard Worker  fi
43*e4a36f41SAndroid Build Coastguard Workerdone
44*e4a36f41SAndroid Build Coastguard Worker
45*e4a36f41SAndroid Build Coastguard Workerecho
46*e4a36f41SAndroid Build Coastguard Workerecho "Scanning for executables that don't exist."
47*e4a36f41SAndroid Build Coastguard Worker# Find executable types.
48*e4a36f41SAndroid Build Coastguard Workergrep -r "^type .*exec_type" --exclude=\*.go $sedir | sed 's/^.*:.*type \([^,]*\)*.*$/\1/' | sort | uniq | while read -r type; do
49*e4a36f41SAndroid Build Coastguard Worker  path_line=`grep -r $type --include=\*_contexts $sedir`
50*e4a36f41SAndroid Build Coastguard Worker  # Note that this only examines one entry, even if multiple executables have the same label.
51*e4a36f41SAndroid Build Coastguard Worker  # But the file_contexts scan below covers that case.
52*e4a36f41SAndroid Build Coastguard Worker  path=`echo $path_line | sed 's/^.*:[^\/]*\([^ ]*\) .*$/\1/'`
53*e4a36f41SAndroid Build Coastguard Worker  # Replace character classes and + with *.
54*e4a36f41SAndroid Build Coastguard Worker  path=`echo $path | sed 's/\[[^]]*\]/*/' | sed 's/+/*/'`
55*e4a36f41SAndroid Build Coastguard Worker  # Check whether the file exists.
56*e4a36f41SAndroid Build Coastguard Worker  if [ -n "`$adb_cmd shell ls -lZ $path < /dev/null |& grep "No such file or directory"`" ]; then
57*e4a36f41SAndroid Build Coastguard Worker    echo "$path does not exist"
58*e4a36f41SAndroid Build Coastguard Worker  fi
59*e4a36f41SAndroid Build Coastguard Workerdone
60*e4a36f41SAndroid Build Coastguard Worker
61*e4a36f41SAndroid Build Coastguard Workerecho
62*e4a36f41SAndroid Build Coastguard Workerecho "Scanning genfs_contexts for files that don't exist."
63*e4a36f41SAndroid Build Coastguard Worker# Find files in genfs_contexts.
64*e4a36f41SAndroid Build Coastguard Workerfind $sedir -name genfs_contexts -exec grep "^genfscon " '{}' \; | cut -d' ' -f2,3 | sort | uniq | while read -r file_line; do
65*e4a36f41SAndroid Build Coastguard Worker  # Extract the full path.
66*e4a36f41SAndroid Build Coastguard Worker  path=`echo $file_line | sed 's/rootfs //' | sed 's/sysfs /\/sys/' | sed 's/proc /\/proc/' | sed 's/debugfs /\/sys\/kernel\/debug/' | sed 's/tracefs /\/sys\/kernel\/debug\/tracing/'`
67*e4a36f41SAndroid Build Coastguard Worker  # Skip things whose prefix we don't recognize.
68*e4a36f41SAndroid Build Coastguard Worker  if [[ $path = *" "* ]]; then
69*e4a36f41SAndroid Build Coastguard Worker    continue
70*e4a36f41SAndroid Build Coastguard Worker  fi
71*e4a36f41SAndroid Build Coastguard Worker  # Check whether the file exists.
72*e4a36f41SAndroid Build Coastguard Worker  if [ -n "`$adb_cmd shell ls -lZ $path < /dev/null |& grep "No such file or directory"`" ]; then
73*e4a36f41SAndroid Build Coastguard Worker    echo "$path does not exist"
74*e4a36f41SAndroid Build Coastguard Worker  fi
75*e4a36f41SAndroid Build Coastguard Workerdone
76*e4a36f41SAndroid Build Coastguard Worker
77*e4a36f41SAndroid Build Coastguard Workerecho
78*e4a36f41SAndroid Build Coastguard Workerecho "Scanning file_contexts for files that don't exist."
79*e4a36f41SAndroid Build Coastguard Worker# Find files in file_contexts.
80*e4a36f41SAndroid Build Coastguard Workerfind $sedir -name file_contexts -not -path "*prebuilts*" -exec grep "^/" '{}' \; | cut -d' ' -f1 | cut -f1 | sort | uniq | while read -r path; do
81*e4a36f41SAndroid Build Coastguard Worker  # Replace (/.*)? with *
82*e4a36f41SAndroid Build Coastguard Worker  # Replace (64)? with ??
83*e4a36f41SAndroid Build Coastguard Worker  # Replace (vendor|system/vendor) with /vendor
84*e4a36f41SAndroid Build Coastguard Worker  # Replace character classes and + with *.
85*e4a36f41SAndroid Build Coastguard Worker  # Replace captures.
86*e4a36f41SAndroid Build Coastguard Worker  # Replace \. with .
87*e4a36f41SAndroid Build Coastguard Worker  # Replace .* with *
88*e4a36f41SAndroid Build Coastguard Worker  # Replace ** with *
89*e4a36f41SAndroid Build Coastguard Worker  path=`echo "$path" | sed 's/(\/\.\*)?$//' | sed 's/(64)?/??/' | sed 's/\(vendor|system\/vendor\)/vendor/' | sed 's/\[[^]]*\]/*/' | sed 's/+/*/' | sed 's/(\([^)]*\))/\1/' | sed 's/\\\././g' | sed 's/\.\*/\*/g' | sed 's/\*\*/\*/g'`
90*e4a36f41SAndroid Build Coastguard Worker  # Check whether the file exists.
91*e4a36f41SAndroid Build Coastguard Worker  if [ -n "`$adb_cmd shell ls -lZ "$path" < /dev/null |& grep "No such file or directory"`" ]; then
92*e4a36f41SAndroid Build Coastguard Worker    echo "$path does not exist"
93*e4a36f41SAndroid Build Coastguard Worker  fi
94*e4a36f41SAndroid Build Coastguard Workerdone
95*e4a36f41SAndroid Build Coastguard Worker
96*e4a36f41SAndroid Build Coastguard Workerecho
97*e4a36f41SAndroid Build Coastguard Workerecho "Scanning for rules that are defined in the wrong file."
98*e4a36f41SAndroid Build Coastguard Workerecho "That is, rules that do not contain the name of the file."
99*e4a36f41SAndroid Build Coastguard Worker# Find .te files.
100*e4a36f41SAndroid Build Coastguard Workerfind $sedir -name "*.te" -not -path "*prebuilts*" | while read -r file; do
101*e4a36f41SAndroid Build Coastguard Worker  filename=`basename $file`
102*e4a36f41SAndroid Build Coastguard Worker  filename="${filename%.*}"
103*e4a36f41SAndroid Build Coastguard Worker  # Look for lines that don't have the filename in them.
104*e4a36f41SAndroid Build Coastguard Worker  lines=$(grep "^[^# }']" $file | grep -v $filename | grep -v "^userdebug_or_eng(\`$" | grep -v "^type " | grep "[,)]" | grep -v "^define(")
105*e4a36f41SAndroid Build Coastguard Worker  if [[ -n "$lines" ]]; then
106*e4a36f41SAndroid Build Coastguard Worker    echo "$file:"
107*e4a36f41SAndroid Build Coastguard Worker    echo "$lines"
108*e4a36f41SAndroid Build Coastguard Worker  fi
109*e4a36f41SAndroid Build Coastguard Workerdone
110*e4a36f41SAndroid Build Coastguard Worker
111*e4a36f41SAndroid Build Coastguard Workerecho
112*e4a36f41SAndroid Build Coastguard Workerecho "Scanning for labels in file_contexts that do not escape '.' properly."
113*e4a36f41SAndroid Build Coastguard Workerfind $sedir -name file_contexts -not -path "*prebuilts*" -exec grep -H "^[^#].*[^\\]\.[^*]" '{}' \;
114*e4a36f41SAndroid Build Coastguard Worker
115*e4a36f41SAndroid Build Coastguard Workerecho
116*e4a36f41SAndroid Build Coastguard Workerecho "Scanning for rules that use the wrong file/dir macros."
117*e4a36f41SAndroid Build Coastguard Workergrep -r ":file.*_dir_perms" --exclude=\*_macros $sedir
118*e4a36f41SAndroid Build Coastguard Workergrep -r ":dir.*_file_perms" --exclude=\*_macros $sedir
119