1#!/bin/bash
2
3# Copyright (C) 2021 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# Check that sysfs wakeup nodes are correctly labeled by the
18# device's sepolicy.
19
20wakeup_attr="u:object_r:sysfs_wakeup:s0"
21wakeup_paths=()
22unlabeled_paths=()
23
24get_wakeup_paths() {
25    adb shell 'paths=()
26        wakeup_dir=/sys/class/wakeup
27        cd $wakeup_dir
28        for file in $wakeup_dir/*; do
29            paths+=( $(realpath $file) )
30        done
31        echo "${paths[@]}"'
32}
33
34has_wakeup_attr() { #path
35    local _path="$1"
36
37    adb shell "ls -dZ $_path | grep -q $wakeup_attr"
38    return $?
39}
40
41check_wakeup_dup() { # wakeup_path
42    ret=1
43    for path in "${unlabeled_paths[@]}"; do
44        if [ "$path" == "$1" ]; then
45            ret=0
46            break
47        fi
48    done
49    return $ret
50}
51
52get_unlabeled_wakeup_paths() {
53    for path in ${wakeup_paths[@]}; do
54        wakeup_path="$path"
55        has_wakeup_attr "$wakeup_path" && continue
56
57        # If there exists a common wakeup parent directory, label that instead
58        # of each wakeupN directory
59        dir_path="$(dirname $path)"
60        [ "$(basename $dir_path)" == "wakeup" ] && wakeup_path="$dir_path"
61
62        check_wakeup_dup $wakeup_path || unlabeled_paths+=( $wakeup_path )
63    done
64}
65
66print_missing_labels() {
67    nr_unlabeled="${#unlabeled_paths[@]}"
68
69    [ "$nr_unlabeled" == "0" ] && return 1
70
71    echo ""
72    echo "Unlabeled wakeup nodes found, your device is likely missing"
73    echo "device/oem specific selinux genfscon rules for suspend."
74    echo ""
75    echo "Please review and add the following generated rules to the"
76    echo "device specific genfs_contexts:"
77    echo ""
78
79    for path in ${unlabeled_paths[@]}; do
80        echo "genfscon sysfs ${path#/sys/} $wakeup_attr"
81    done
82
83    echo ""
84
85    return 0
86}
87
88fail() { #msg
89    echo $1
90    exit 1
91}
92
93pass() { #msg
94    echo $1
95    exit 0
96}
97
98# requirement added in T (33)
99vendor_api_level="$(adb shell getprop ro.vendor.api_level 33)"
100if [ "$vendor_api_level" -lt 33 ]; then
101    pass "Test skipped: vendor_api_level ($vendor_api_level) < min_api_level (33)"
102fi
103
104# Test unlabeled sysfs_wakeup nodes
105wakeup_paths+=( $(get_wakeup_paths) )
106get_unlabeled_wakeup_paths
107print_missing_labels && fail "Missing sysfs_wakeup labels" \
108    || pass "No missing sysfs_wakeup labels"
109