kernel: Reformat code using clang-format (#347)

* The coding format is too messy, reformat to improve readability
  and get closer to Linux kernel coding style.

* While at it, update .clang-format file to linux-mainline state.
This commit is contained in:
Helium_Studio
2025-08-22 14:02:20 +08:00
committed by GitHub
parent fe472057b1
commit ce58519e66
31 changed files with 1542 additions and 1131 deletions

View File

@@ -1,10 +1,10 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# #
# clang-format configuration file. Intended for clang-format >= 4. # clang-format configuration file. Intended for clang-format >= 11.
# #
# For more information, see: # For more information, see:
# #
# Documentation/process/clang-format.rst # Documentation/dev-tools/clang-format.rst
# https://clang.llvm.org/docs/ClangFormat.html # https://clang.llvm.org/docs/ClangFormat.html
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html # https://clang.llvm.org/docs/ClangFormatStyleOptions.html
# #
@@ -13,7 +13,7 @@ AccessModifierOffset: -4
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false AlignConsecutiveDeclarations: false
#AlignEscapedNewlines: Left # Unknown to clang-format-4.0 AlignEscapedNewlines: Left
AlignOperands: true AlignOperands: true
AlignTrailingComments: false AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false
@@ -37,24 +37,24 @@ BraceWrapping:
AfterObjCDeclaration: false AfterObjCDeclaration: false
AfterStruct: false AfterStruct: false
AfterUnion: false AfterUnion: false
#AfterExternBlock: false # Unknown to clang-format-5.0 AfterExternBlock: false
BeforeCatch: false BeforeCatch: false
BeforeElse: false BeforeElse: false
IndentBraces: false IndentBraces: false
#SplitEmptyFunction: true # Unknown to clang-format-4.0 SplitEmptyFunction: true
#SplitEmptyRecord: true # Unknown to clang-format-4.0 SplitEmptyRecord: true
#SplitEmptyNamespace: true # Unknown to clang-format-4.0 SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom BreakBeforeBraces: Custom
#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0 BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false BreakConstructorInitializersBeforeComma: false
#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0 BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false BreakStringLiterals: false
ColumnLimit: 80 ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
#CompactNamespaces: false # Unknown to clang-format-4.0 CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8 ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8 ContinuationIndentWidth: 8
@@ -62,39 +62,61 @@ Cpp11BracedListStyle: false
DerivePointerAlignment: false DerivePointerAlignment: false
DisableFormat: false DisableFormat: false
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
#FixNamespaceComments: false # Unknown to clang-format-4.0 FixNamespaceComments: false
# Taken from: # Taken from:
# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \ # git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ tools/ \
# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \ # | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
# | sort | uniq # | LC_ALL=C sort -u
ForEachMacros: ForEachMacros:
- '__ata_qc_for_each'
- '__bio_for_each_bvec'
- '__bio_for_each_segment'
- '__evlist__for_each_entry'
- '__evlist__for_each_entry_continue'
- '__evlist__for_each_entry_from'
- '__evlist__for_each_entry_reverse'
- '__evlist__for_each_entry_safe'
- '__for_each_mem_range'
- '__for_each_mem_range_rev'
- '__for_each_thread'
- '__hlist_for_each_rcu'
- '__map__for_each_symbol_by_name'
- '__pci_bus_for_each_res0'
- '__pci_bus_for_each_res1'
- '__pci_dev_for_each_res0'
- '__pci_dev_for_each_res1'
- '__perf_evlist__for_each_entry'
- '__perf_evlist__for_each_entry_reverse'
- '__perf_evlist__for_each_entry_safe'
- '__rq_for_each_bio'
- '__shost_for_each_device'
- '__sym_for_each'
- '_for_each_counter'
- 'apei_estatus_for_each_section' - 'apei_estatus_for_each_section'
- 'ata_for_each_dev' - 'ata_for_each_dev'
- 'ata_for_each_link' - 'ata_for_each_link'
- '__ata_qc_for_each'
- 'ata_qc_for_each' - 'ata_qc_for_each'
- 'ata_qc_for_each_raw' - 'ata_qc_for_each_raw'
- 'ata_qc_for_each_with_internal' - 'ata_qc_for_each_with_internal'
- 'ax25_for_each' - 'ax25_for_each'
- 'ax25_uid_for_each' - 'ax25_uid_for_each'
- '__bio_for_each_bvec'
- 'bio_for_each_bvec' - 'bio_for_each_bvec'
- 'bio_for_each_bvec_all' - 'bio_for_each_bvec_all'
- 'bio_for_each_folio_all'
- 'bio_for_each_integrity_vec' - 'bio_for_each_integrity_vec'
- '__bio_for_each_segment'
- 'bio_for_each_segment' - 'bio_for_each_segment'
- 'bio_for_each_segment_all' - 'bio_for_each_segment_all'
- 'bio_list_for_each' - 'bio_list_for_each'
- 'bip_for_each_vec' - 'bip_for_each_vec'
- 'bitmap_for_each_clear_region'
- 'bitmap_for_each_set_region'
- 'blkg_for_each_descendant_post'
- 'blkg_for_each_descendant_pre'
- 'blk_queue_for_each_rl'
- 'bond_for_each_slave' - 'bond_for_each_slave'
- 'bond_for_each_slave_rcu' - 'bond_for_each_slave_rcu'
- 'bpf_for_each'
- 'bpf_for_each_reg_in_vstate'
- 'bpf_for_each_reg_in_vstate_mask'
- 'bpf_for_each_spilled_reg' - 'bpf_for_each_spilled_reg'
- 'bpf_object__for_each_map'
- 'bpf_object__for_each_program'
- 'btree_for_each_safe128' - 'btree_for_each_safe128'
- 'btree_for_each_safe32' - 'btree_for_each_safe32'
- 'btree_for_each_safe64' - 'btree_for_each_safe64'
@@ -102,6 +124,8 @@ ForEachMacros:
- 'card_for_each_dev' - 'card_for_each_dev'
- 'cgroup_taskset_for_each' - 'cgroup_taskset_for_each'
- 'cgroup_taskset_for_each_leader' - 'cgroup_taskset_for_each_leader'
- 'cpu_aggr_map__for_each_idx'
- 'cpufreq_for_each_efficient_entry_idx'
- 'cpufreq_for_each_entry' - 'cpufreq_for_each_entry'
- 'cpufreq_for_each_entry_idx' - 'cpufreq_for_each_entry_idx'
- 'cpufreq_for_each_valid_entry' - 'cpufreq_for_each_valid_entry'
@@ -109,8 +133,30 @@ ForEachMacros:
- 'css_for_each_child' - 'css_for_each_child'
- 'css_for_each_descendant_post' - 'css_for_each_descendant_post'
- 'css_for_each_descendant_pre' - 'css_for_each_descendant_pre'
- 'damon_for_each_region'
- 'damon_for_each_region_from'
- 'damon_for_each_region_safe'
- 'damon_for_each_scheme'
- 'damon_for_each_scheme_safe'
- 'damon_for_each_target'
- 'damon_for_each_target_safe'
- 'damos_for_each_filter'
- 'damos_for_each_filter_safe'
- 'damos_for_each_ops_filter'
- 'damos_for_each_ops_filter_safe'
- 'damos_for_each_quota_goal'
- 'damos_for_each_quota_goal_safe'
- 'data__for_each_file'
- 'data__for_each_file_new'
- 'data__for_each_file_start'
- 'def_for_each_cpu'
- 'device_for_each_child_node' - 'device_for_each_child_node'
- 'device_for_each_child_node_scoped'
- 'dma_fence_array_for_each'
- 'dma_fence_chain_for_each' - 'dma_fence_chain_for_each'
- 'dma_fence_unwrap_for_each'
- 'dma_resv_for_each_fence'
- 'dma_resv_for_each_fence_unlocked'
- 'do_for_each_ftrace_op' - 'do_for_each_ftrace_op'
- 'drm_atomic_crtc_for_each_plane' - 'drm_atomic_crtc_for_each_plane'
- 'drm_atomic_crtc_state_for_each_plane' - 'drm_atomic_crtc_state_for_each_plane'
@@ -119,9 +165,12 @@ ForEachMacros:
- 'drm_client_for_each_connector_iter' - 'drm_client_for_each_connector_iter'
- 'drm_client_for_each_modeset' - 'drm_client_for_each_modeset'
- 'drm_connector_for_each_possible_encoder' - 'drm_connector_for_each_possible_encoder'
- 'drm_exec_for_each_locked_object'
- 'drm_exec_for_each_locked_object_reverse'
- 'drm_for_each_bridge_in_chain' - 'drm_for_each_bridge_in_chain'
- 'drm_for_each_connector_iter' - 'drm_for_each_connector_iter'
- 'drm_for_each_crtc' - 'drm_for_each_crtc'
- 'drm_for_each_crtc_reverse'
- 'drm_for_each_encoder' - 'drm_for_each_encoder'
- 'drm_for_each_encoder_mask' - 'drm_for_each_encoder_mask'
- 'drm_for_each_fb' - 'drm_for_each_fb'
@@ -129,19 +178,64 @@ ForEachMacros:
- 'drm_for_each_plane' - 'drm_for_each_plane'
- 'drm_for_each_plane_mask' - 'drm_for_each_plane_mask'
- 'drm_for_each_privobj' - 'drm_for_each_privobj'
- 'drm_gem_for_each_gpuvm_bo'
- 'drm_gem_for_each_gpuvm_bo_safe'
- 'drm_gpusvm_for_each_range'
- 'drm_gpuva_for_each_op'
- 'drm_gpuva_for_each_op_from_reverse'
- 'drm_gpuva_for_each_op_reverse'
- 'drm_gpuva_for_each_op_safe'
- 'drm_gpuvm_bo_for_each_va'
- 'drm_gpuvm_bo_for_each_va_safe'
- 'drm_gpuvm_for_each_va'
- 'drm_gpuvm_for_each_va_range'
- 'drm_gpuvm_for_each_va_range_safe'
- 'drm_gpuvm_for_each_va_safe'
- 'drm_mm_for_each_hole' - 'drm_mm_for_each_hole'
- 'drm_mm_for_each_node' - 'drm_mm_for_each_node'
- 'drm_mm_for_each_node_in_range' - 'drm_mm_for_each_node_in_range'
- 'drm_mm_for_each_node_safe' - 'drm_mm_for_each_node_safe'
- 'dsa_switch_for_each_available_port'
- 'dsa_switch_for_each_cpu_port'
- 'dsa_switch_for_each_cpu_port_continue_reverse'
- 'dsa_switch_for_each_port'
- 'dsa_switch_for_each_port_continue_reverse'
- 'dsa_switch_for_each_port_safe'
- 'dsa_switch_for_each_user_port'
- 'dsa_switch_for_each_user_port_continue_reverse'
- 'dsa_tree_for_each_cpu_port'
- 'dsa_tree_for_each_user_port'
- 'dsa_tree_for_each_user_port_continue_reverse'
- 'dso__for_each_symbol'
- 'elf_hash_for_each_possible'
- 'elf_symtab__for_each_symbol'
- 'evlist__for_each_cpu'
- 'evlist__for_each_entry'
- 'evlist__for_each_entry_continue'
- 'evlist__for_each_entry_from'
- 'evlist__for_each_entry_reverse'
- 'evlist__for_each_entry_safe'
- 'flow_action_for_each' - 'flow_action_for_each'
- 'for_each_acpi_consumer_dev'
- 'for_each_acpi_dev_match'
- 'for_each_active_dev_scope' - 'for_each_active_dev_scope'
- 'for_each_active_drhd_unit' - 'for_each_active_drhd_unit'
- 'for_each_active_iommu' - 'for_each_active_iommu'
- 'for_each_active_irq'
- 'for_each_active_route'
- 'for_each_aggr_pgid' - 'for_each_aggr_pgid'
- 'for_each_alloc_capable_rdt_resource'
- 'for_each_and_bit'
- 'for_each_andnot_bit'
- 'for_each_available_child_of_node' - 'for_each_available_child_of_node'
- 'for_each_available_child_of_node_scoped'
- 'for_each_bench'
- 'for_each_bio' - 'for_each_bio'
- 'for_each_board_func_rsrc' - 'for_each_board_func_rsrc'
- 'for_each_btf_ext_rec'
- 'for_each_btf_ext_sec'
- 'for_each_bvec' - 'for_each_bvec'
- 'for_each_capable_rdt_resource'
- 'for_each_card_auxs' - 'for_each_card_auxs'
- 'for_each_card_auxs_safe' - 'for_each_card_auxs_safe'
- 'for_each_card_components' - 'for_each_card_components'
@@ -154,22 +248,32 @@ ForEachMacros:
- 'for_each_card_widgets_safe' - 'for_each_card_widgets_safe'
- 'for_each_cgroup_storage_type' - 'for_each_cgroup_storage_type'
- 'for_each_child_of_node' - 'for_each_child_of_node'
- 'for_each_child_of_node_scoped'
- 'for_each_child_of_node_with_prefix'
- 'for_each_clear_bit' - 'for_each_clear_bit'
- 'for_each_clear_bit_from' - 'for_each_clear_bit_from'
- 'for_each_clear_bitrange'
- 'for_each_clear_bitrange_from'
- 'for_each_cmd'
- 'for_each_cmsghdr' - 'for_each_cmsghdr'
- 'for_each_collection'
- 'for_each_comp_order'
- 'for_each_compatible_node' - 'for_each_compatible_node'
- 'for_each_component_dais' - 'for_each_component_dais'
- 'for_each_component_dais_safe' - 'for_each_component_dais_safe'
- 'for_each_comp_order' - 'for_each_conduit'
- 'for_each_console' - 'for_each_console'
- 'for_each_console_srcu'
- 'for_each_cpu' - 'for_each_cpu'
- 'for_each_cpu_and' - 'for_each_cpu_and'
- 'for_each_cpu_not' - 'for_each_cpu_andnot'
- 'for_each_cpu_from'
- 'for_each_cpu_or'
- 'for_each_cpu_wrap' - 'for_each_cpu_wrap'
- 'for_each_dapm_widgets' - 'for_each_dapm_widgets'
- 'for_each_dedup_cand'
- 'for_each_dev_addr' - 'for_each_dev_addr'
- 'for_each_dev_scope' - 'for_each_dev_scope'
- 'for_each_displayid_db'
- 'for_each_dma_cap_mask' - 'for_each_dma_cap_mask'
- 'for_each_dpcm_be' - 'for_each_dpcm_be'
- 'for_each_dpcm_be_rollback' - 'for_each_dpcm_be_rollback'
@@ -182,107 +286,160 @@ ForEachMacros:
- 'for_each_element' - 'for_each_element'
- 'for_each_element_extid' - 'for_each_element_extid'
- 'for_each_element_id' - 'for_each_element_id'
- 'for_each_enabled_cpu'
- 'for_each_endpoint_of_node' - 'for_each_endpoint_of_node'
- 'for_each_event'
- 'for_each_event_tps'
- 'for_each_evictable_lru' - 'for_each_evictable_lru'
- 'for_each_fib6_node_rt_rcu' - 'for_each_fib6_node_rt_rcu'
- 'for_each_fib6_walker_rt' - 'for_each_fib6_walker_rt'
- 'for_each_free_mem_pfn_range_in_zone' - 'for_each_file_lock'
- 'for_each_free_mem_pfn_range_in_zone_from' - 'for_each_free_mem_pfn_range_in_zone_from'
- 'for_each_free_mem_range' - 'for_each_free_mem_range'
- 'for_each_free_mem_range_reverse' - 'for_each_free_mem_range_reverse'
- 'for_each_func_rsrc' - 'for_each_func_rsrc'
- 'for_each_gpiochip_node'
- 'for_each_group_evsel'
- 'for_each_group_evsel_head'
- 'for_each_group_member'
- 'for_each_group_member_head'
- 'for_each_hstate' - 'for_each_hstate'
- 'for_each_hwgpio'
- 'for_each_hwgpio_in_range'
- 'for_each_if' - 'for_each_if'
- 'for_each_inject_fn'
- 'for_each_insn'
- 'for_each_insn_op_loc'
- 'for_each_insn_prefix'
- 'for_each_intid'
- 'for_each_iommu' - 'for_each_iommu'
- 'for_each_ip_tunnel_rcu' - 'for_each_ip_tunnel_rcu'
- 'for_each_irq_desc'
- 'for_each_irq_nr' - 'for_each_irq_nr'
- 'for_each_lang'
- 'for_each_link_ch_maps'
- 'for_each_link_codecs' - 'for_each_link_codecs'
- 'for_each_link_cpus' - 'for_each_link_cpus'
- 'for_each_link_platforms' - 'for_each_link_platforms'
- 'for_each_lru' - 'for_each_lru'
- 'for_each_matching_node' - 'for_each_matching_node'
- 'for_each_matching_node_and_match' - 'for_each_matching_node_and_match'
- 'for_each_member' - 'for_each_media_entity_data_link'
- 'for_each_mem_region'
- 'for_each_memblock_type'
- 'for_each_memcg_cache_index'
- 'for_each_mem_pfn_range' - 'for_each_mem_pfn_range'
- '__for_each_mem_range'
- 'for_each_mem_range' - 'for_each_mem_range'
- '__for_each_mem_range_rev'
- 'for_each_mem_range_rev' - 'for_each_mem_range_rev'
- 'for_each_mem_region'
- 'for_each_member'
- 'for_each_memory'
- 'for_each_migratetype_order' - 'for_each_migratetype_order'
- 'for_each_msi_entry' - 'for_each_missing_reg'
- 'for_each_msi_entry_safe' - 'for_each_mle_subelement'
- 'for_each_mod_mem_type'
- 'for_each_mon_capable_rdt_resource'
- 'for_each_mp_bvec'
- 'for_each_net' - 'for_each_net'
- 'for_each_net_continue_reverse' - 'for_each_net_continue_reverse'
- 'for_each_net_rcu'
- 'for_each_netdev' - 'for_each_netdev'
- 'for_each_netdev_continue' - 'for_each_netdev_continue'
- 'for_each_netdev_continue_rcu' - 'for_each_netdev_continue_rcu'
- 'for_each_netdev_continue_reverse' - 'for_each_netdev_continue_reverse'
- 'for_each_netdev_dump'
- 'for_each_netdev_feature' - 'for_each_netdev_feature'
- 'for_each_netdev_in_bond_rcu' - 'for_each_netdev_in_bond_rcu'
- 'for_each_netdev_rcu' - 'for_each_netdev_rcu'
- 'for_each_netdev_reverse' - 'for_each_netdev_reverse'
- 'for_each_netdev_safe' - 'for_each_netdev_safe'
- 'for_each_net_rcu'
- 'for_each_new_connector_in_state' - 'for_each_new_connector_in_state'
- 'for_each_new_crtc_in_state' - 'for_each_new_crtc_in_state'
- 'for_each_new_mst_mgr_in_state' - 'for_each_new_mst_mgr_in_state'
- 'for_each_new_plane_in_state' - 'for_each_new_plane_in_state'
- 'for_each_new_plane_in_state_reverse'
- 'for_each_new_private_obj_in_state' - 'for_each_new_private_obj_in_state'
- 'for_each_new_reg'
- 'for_each_nhlt_endpoint'
- 'for_each_nhlt_endpoint_fmtcfg'
- 'for_each_nhlt_fmtcfg'
- 'for_each_node' - 'for_each_node'
- 'for_each_node_by_name' - 'for_each_node_by_name'
- 'for_each_node_by_type' - 'for_each_node_by_type'
- 'for_each_node_mask' - 'for_each_node_mask'
- 'for_each_node_numadist'
- 'for_each_node_state' - 'for_each_node_state'
- 'for_each_node_with_cpus' - 'for_each_node_with_cpus'
- 'for_each_node_with_property' - 'for_each_node_with_property'
- 'for_each_nonreserved_multicast_dest_pgid' - 'for_each_nonreserved_multicast_dest_pgid'
- 'for_each_numa_hop_mask'
- 'for_each_of_allnodes' - 'for_each_of_allnodes'
- 'for_each_of_allnodes_from' - 'for_each_of_allnodes_from'
- 'for_each_of_cpu_node' - 'for_each_of_cpu_node'
- 'for_each_of_graph_port'
- 'for_each_of_graph_port_endpoint'
- 'for_each_of_pci_range' - 'for_each_of_pci_range'
- 'for_each_old_connector_in_state' - 'for_each_old_connector_in_state'
- 'for_each_old_crtc_in_state' - 'for_each_old_crtc_in_state'
- 'for_each_old_mst_mgr_in_state' - 'for_each_old_mst_mgr_in_state'
- 'for_each_old_plane_in_state'
- 'for_each_old_private_obj_in_state'
- 'for_each_oldnew_connector_in_state' - 'for_each_oldnew_connector_in_state'
- 'for_each_oldnew_crtc_in_state' - 'for_each_oldnew_crtc_in_state'
- 'for_each_oldnew_mst_mgr_in_state' - 'for_each_oldnew_mst_mgr_in_state'
- 'for_each_oldnew_plane_in_state' - 'for_each_oldnew_plane_in_state'
- 'for_each_oldnew_plane_in_state_reverse' - 'for_each_oldnew_plane_in_state_reverse'
- 'for_each_oldnew_private_obj_in_state' - 'for_each_oldnew_private_obj_in_state'
- 'for_each_old_plane_in_state'
- 'for_each_old_private_obj_in_state'
- 'for_each_online_cpu' - 'for_each_online_cpu'
- 'for_each_online_cpu_wrap'
- 'for_each_online_node' - 'for_each_online_node'
- 'for_each_online_pgdat' - 'for_each_online_pgdat'
- 'for_each_or_bit'
- 'for_each_page_ext'
- 'for_each_path'
- 'for_each_pci_bridge' - 'for_each_pci_bridge'
- 'for_each_pci_dev' - 'for_each_pci_dev'
- 'for_each_pci_msi_entry'
- 'for_each_pcm_streams' - 'for_each_pcm_streams'
- 'for_each_physmem_range' - 'for_each_physmem_range'
- 'for_each_populated_zone' - 'for_each_populated_zone'
- 'for_each_possible_cpu' - 'for_each_possible_cpu'
- 'for_each_possible_cpu_wrap'
- 'for_each_present_blessed_reg'
- 'for_each_present_cpu' - 'for_each_present_cpu'
- 'for_each_present_section_nr'
- 'for_each_prime_number' - 'for_each_prime_number'
- 'for_each_prime_number_from' - 'for_each_prime_number_from'
- 'for_each_probe_cache_entry'
- 'for_each_process' - 'for_each_process'
- 'for_each_process_thread' - 'for_each_process_thread'
- 'for_each_prop_codec_conf'
- 'for_each_prop_dai_codec'
- 'for_each_prop_dai_cpu'
- 'for_each_prop_dlc_codecs'
- 'for_each_prop_dlc_cpus'
- 'for_each_prop_dlc_platforms'
- 'for_each_property_of_node' - 'for_each_property_of_node'
- 'for_each_registered_fb' - 'for_each_rdt_resource'
- 'for_each_reg'
- 'for_each_reg_filtered'
- 'for_each_reloc'
- 'for_each_reloc_from'
- 'for_each_requested_gpio' - 'for_each_requested_gpio'
- 'for_each_requested_gpio_in_range' - 'for_each_requested_gpio_in_range'
- 'for_each_reserved_child_of_node'
- 'for_each_reserved_mem_range' - 'for_each_reserved_mem_range'
- 'for_each_reserved_mem_region' - 'for_each_reserved_mem_region'
- 'for_each_rtd_ch_maps'
- 'for_each_rtd_codec_dais' - 'for_each_rtd_codec_dais'
- 'for_each_rtd_codec_dais_rollback'
- 'for_each_rtd_components' - 'for_each_rtd_components'
- 'for_each_rtd_cpu_dais' - 'for_each_rtd_cpu_dais'
- 'for_each_rtd_cpu_dais_rollback'
- 'for_each_rtd_dais' - 'for_each_rtd_dais'
- 'for_each_rtd_dais_reverse'
- 'for_each_sband_iftype_data'
- 'for_each_script'
- 'for_each_sec'
- 'for_each_set_bit' - 'for_each_set_bit'
- 'for_each_set_bit_from' - 'for_each_set_bit_from'
- 'for_each_set_bit_wrap'
- 'for_each_set_bitrange'
- 'for_each_set_bitrange_from'
- 'for_each_set_clump8' - 'for_each_set_clump8'
- 'for_each_sg' - 'for_each_sg'
- 'for_each_sg_dma_page' - 'for_each_sg_dma_page'
@@ -292,22 +449,37 @@ ForEachMacros:
- 'for_each_sgtable_page' - 'for_each_sgtable_page'
- 'for_each_sgtable_sg' - 'for_each_sgtable_sg'
- 'for_each_sibling_event' - 'for_each_sibling_event'
- 'for_each_sta_active_link'
- 'for_each_subelement' - 'for_each_subelement'
- 'for_each_subelement_extid' - 'for_each_subelement_extid'
- 'for_each_subelement_id' - 'for_each_subelement_id'
- '__for_each_thread' - 'for_each_sublist'
- 'for_each_subsystem'
- 'for_each_suite'
- 'for_each_supported_activate_fn'
- 'for_each_supported_inject_fn'
- 'for_each_sym'
- 'for_each_thread' - 'for_each_thread'
- 'for_each_token'
- 'for_each_unicast_dest_pgid' - 'for_each_unicast_dest_pgid'
- 'for_each_valid_link'
- 'for_each_vif_active_link'
- 'for_each_vma'
- 'for_each_vma_range'
- 'for_each_vsi'
- 'for_each_wakeup_source' - 'for_each_wakeup_source'
- 'for_each_zone' - 'for_each_zone'
- 'for_each_zone_zonelist' - 'for_each_zone_zonelist'
- 'for_each_zone_zonelist_nodemask' - 'for_each_zone_zonelist_nodemask'
- 'func_for_each_insn'
- 'fwnode_for_each_available_child_node' - 'fwnode_for_each_available_child_node'
- 'fwnode_for_each_child_node' - 'fwnode_for_each_child_node'
- 'fwnode_for_each_parent_node'
- 'fwnode_graph_for_each_endpoint' - 'fwnode_graph_for_each_endpoint'
- 'gadget_for_each_ep' - 'gadget_for_each_ep'
- 'genradix_for_each' - 'genradix_for_each'
- 'genradix_for_each_from' - 'genradix_for_each_from'
- 'genradix_for_each_reverse'
- 'hash_for_each' - 'hash_for_each'
- 'hash_for_each_possible' - 'hash_for_each_possible'
- 'hash_for_each_possible_rcu' - 'hash_for_each_possible_rcu'
@@ -315,7 +487,13 @@ ForEachMacros:
- 'hash_for_each_possible_safe' - 'hash_for_each_possible_safe'
- 'hash_for_each_rcu' - 'hash_for_each_rcu'
- 'hash_for_each_safe' - 'hash_for_each_safe'
- 'hashmap__for_each_entry'
- 'hashmap__for_each_entry_safe'
- 'hashmap__for_each_key_entry'
- 'hashmap__for_each_key_entry_safe'
- 'hctx_for_each_ctx' - 'hctx_for_each_ctx'
- 'hists__for_each_format'
- 'hists__for_each_sort_list'
- 'hlist_bl_for_each_entry' - 'hlist_bl_for_each_entry'
- 'hlist_bl_for_each_entry_rcu' - 'hlist_bl_for_each_entry_rcu'
- 'hlist_bl_for_each_entry_safe' - 'hlist_bl_for_each_entry_safe'
@@ -330,7 +508,7 @@ ForEachMacros:
- 'hlist_for_each_entry_rcu_bh' - 'hlist_for_each_entry_rcu_bh'
- 'hlist_for_each_entry_rcu_notrace' - 'hlist_for_each_entry_rcu_notrace'
- 'hlist_for_each_entry_safe' - 'hlist_for_each_entry_safe'
- '__hlist_for_each_rcu' - 'hlist_for_each_entry_srcu'
- 'hlist_for_each_safe' - 'hlist_for_each_safe'
- 'hlist_nulls_for_each_entry' - 'hlist_nulls_for_each_entry'
- 'hlist_nulls_for_each_entry_from' - 'hlist_nulls_for_each_entry_from'
@@ -338,17 +516,19 @@ ForEachMacros:
- 'hlist_nulls_for_each_entry_safe' - 'hlist_nulls_for_each_entry_safe'
- 'i3c_bus_for_each_i2cdev' - 'i3c_bus_for_each_i2cdev'
- 'i3c_bus_for_each_i3cdev' - 'i3c_bus_for_each_i3cdev'
- 'ide_host_for_each_port'
- 'ide_port_for_each_dev'
- 'ide_port_for_each_present_dev'
- 'idr_for_each_entry' - 'idr_for_each_entry'
- 'idr_for_each_entry_continue' - 'idr_for_each_entry_continue'
- 'idr_for_each_entry_continue_ul' - 'idr_for_each_entry_continue_ul'
- 'idr_for_each_entry_ul' - 'idr_for_each_entry_ul'
- 'iio_for_each_active_channel'
- 'in_dev_for_each_ifa_rcu' - 'in_dev_for_each_ifa_rcu'
- 'in_dev_for_each_ifa_rtnl' - 'in_dev_for_each_ifa_rtnl'
- 'in_dev_for_each_ifa_rtnl_net'
- 'inet_bind_bucket_for_each' - 'inet_bind_bucket_for_each'
- 'inet_lhash2_for_each_icsk_rcu' - 'interval_tree_for_each_span'
- 'intlist__for_each_entry'
- 'intlist__for_each_entry_safe'
- 'kcore_copy__for_each_phdr'
- 'key_for_each' - 'key_for_each'
- 'key_for_each_safe' - 'key_for_each_safe'
- 'klp_for_each_func' - 'klp_for_each_func'
@@ -359,7 +539,9 @@ ForEachMacros:
- 'klp_for_each_object_static' - 'klp_for_each_object_static'
- 'kunit_suite_for_each_test_case' - 'kunit_suite_for_each_test_case'
- 'kvm_for_each_memslot' - 'kvm_for_each_memslot'
- 'kvm_for_each_memslot_in_gfn_range'
- 'kvm_for_each_vcpu' - 'kvm_for_each_vcpu'
- 'libbpf_nla_for_each_attr'
- 'list_for_each' - 'list_for_each'
- 'list_for_each_codec' - 'list_for_each_codec'
- 'list_for_each_codec_safe' - 'list_for_each_codec_safe'
@@ -378,29 +560,53 @@ ForEachMacros:
- 'list_for_each_entry_safe_continue' - 'list_for_each_entry_safe_continue'
- 'list_for_each_entry_safe_from' - 'list_for_each_entry_safe_from'
- 'list_for_each_entry_safe_reverse' - 'list_for_each_entry_safe_reverse'
- 'list_for_each_entry_srcu'
- 'list_for_each_from'
- 'list_for_each_prev' - 'list_for_each_prev'
- 'list_for_each_prev_safe' - 'list_for_each_prev_safe'
- 'list_for_each_rcu'
- 'list_for_each_safe' - 'list_for_each_safe'
- 'llist_for_each' - 'llist_for_each'
- 'llist_for_each_entry' - 'llist_for_each_entry'
- 'llist_for_each_entry_safe' - 'llist_for_each_entry_safe'
- 'llist_for_each_safe' - 'llist_for_each_safe'
- 'lwq_for_each_safe'
- 'map__for_each_symbol'
- 'map__for_each_symbol_by_name'
- 'mas_for_each'
- 'mas_for_each_rev'
- 'mci_for_each_dimm' - 'mci_for_each_dimm'
- 'media_device_for_each_entity' - 'media_device_for_each_entity'
- 'media_device_for_each_intf' - 'media_device_for_each_intf'
- 'media_device_for_each_link' - 'media_device_for_each_link'
- 'media_device_for_each_pad' - 'media_device_for_each_pad'
- 'media_entity_for_each_pad'
- 'media_pipeline_for_each_entity'
- 'media_pipeline_for_each_pad'
- 'mlx5_lag_for_each_peer_mdev'
- 'mptcp_for_each_subflow'
- 'msi_domain_for_each_desc'
- 'msi_for_each_desc'
- 'mt_for_each'
- 'nanddev_io_for_each_block'
- 'nanddev_io_for_each_page' - 'nanddev_io_for_each_page'
- 'neigh_for_each_in_bucket'
- 'neigh_for_each_in_bucket_rcu'
- 'neigh_for_each_in_bucket_safe'
- 'netdev_for_each_lower_dev' - 'netdev_for_each_lower_dev'
- 'netdev_for_each_lower_private' - 'netdev_for_each_lower_private'
- 'netdev_for_each_lower_private_rcu' - 'netdev_for_each_lower_private_rcu'
- 'netdev_for_each_mc_addr' - 'netdev_for_each_mc_addr'
- 'netdev_for_each_synced_mc_addr'
- 'netdev_for_each_synced_uc_addr'
- 'netdev_for_each_uc_addr' - 'netdev_for_each_uc_addr'
- 'netdev_for_each_upper_dev_rcu' - 'netdev_for_each_upper_dev_rcu'
- 'netdev_hw_addr_list_for_each' - 'netdev_hw_addr_list_for_each'
- 'nft_rule_for_each_expr' - 'nft_rule_for_each_expr'
- 'nla_for_each_attr' - 'nla_for_each_attr'
- 'nla_for_each_attr_type'
- 'nla_for_each_nested' - 'nla_for_each_nested'
- 'nla_for_each_nested_type'
- 'nlmsg_for_each_attr' - 'nlmsg_for_each_attr'
- 'nlmsg_for_each_msg' - 'nlmsg_for_each_msg'
- 'nr_neigh_for_each' - 'nr_neigh_for_each'
@@ -411,8 +617,26 @@ ForEachMacros:
- 'of_property_for_each_string' - 'of_property_for_each_string'
- 'of_property_for_each_u32' - 'of_property_for_each_u32'
- 'pci_bus_for_each_resource' - 'pci_bus_for_each_resource'
- 'pci_dev_for_each_resource'
- 'pcl_for_each_chunk'
- 'pcl_for_each_segment'
- 'pcm_for_each_format' - 'pcm_for_each_format'
- 'ping_portaddr_for_each_entry' - 'perf_config_items__for_each_entry'
- 'perf_config_sections__for_each_entry'
- 'perf_config_set__for_each_entry'
- 'perf_cpu_map__for_each_cpu'
- 'perf_cpu_map__for_each_cpu_skip_any'
- 'perf_cpu_map__for_each_idx'
- 'perf_evlist__for_each_entry'
- 'perf_evlist__for_each_entry_reverse'
- 'perf_evlist__for_each_entry_safe'
- 'perf_evlist__for_each_evsel'
- 'perf_evlist__for_each_mmap'
- 'perf_evsel_for_each_per_thread_period_safe'
- 'perf_hpp_list__for_each_format'
- 'perf_hpp_list__for_each_format_safe'
- 'perf_hpp_list__for_each_sort_list'
- 'perf_hpp_list__for_each_sort_list_safe'
- 'plist_for_each' - 'plist_for_each'
- 'plist_for_each_continue' - 'plist_for_each_continue'
- 'plist_for_each_entry' - 'plist_for_each_entry'
@@ -426,6 +650,7 @@ ForEachMacros:
- 'queue_for_each_hw_ctx' - 'queue_for_each_hw_ctx'
- 'radix_tree_for_each_slot' - 'radix_tree_for_each_slot'
- 'radix_tree_for_each_tagged' - 'radix_tree_for_each_tagged'
- 'rb_for_each'
- 'rbtree_postorder_for_each_entry_safe' - 'rbtree_postorder_for_each_entry_safe'
- 'rdma_for_each_block' - 'rdma_for_each_block'
- 'rdma_for_each_port' - 'rdma_for_each_port'
@@ -443,18 +668,24 @@ ForEachMacros:
- 'rht_for_each_from' - 'rht_for_each_from'
- 'rht_for_each_rcu' - 'rht_for_each_rcu'
- 'rht_for_each_rcu_from' - 'rht_for_each_rcu_from'
- '__rq_for_each_bio'
- 'rq_for_each_bvec' - 'rq_for_each_bvec'
- 'rq_for_each_segment' - 'rq_for_each_segment'
- 'rq_list_for_each'
- 'rq_list_for_each_safe'
- 'sample_read_group__for_each'
- 'scsi_for_each_prot_sg' - 'scsi_for_each_prot_sg'
- 'scsi_for_each_sg' - 'scsi_for_each_sg'
- 'sctp_for_each_hentry' - 'sctp_for_each_hentry'
- 'sctp_skb_for_each' - 'sctp_skb_for_each'
- 'sec_for_each_insn'
- 'sec_for_each_insn_continue'
- 'sec_for_each_insn_from'
- 'sec_for_each_sym'
- 'shdma_for_each_chan' - 'shdma_for_each_chan'
- '__shost_for_each_device'
- 'shost_for_each_device' - 'shost_for_each_device'
- 'sk_for_each' - 'sk_for_each'
- 'sk_for_each_bound' - 'sk_for_each_bound'
- 'sk_for_each_bound_safe'
- 'sk_for_each_entry_offset_rcu' - 'sk_for_each_entry_offset_rcu'
- 'sk_for_each_from' - 'sk_for_each_from'
- 'sk_for_each_rcu' - 'sk_for_each_rcu'
@@ -468,8 +699,20 @@ ForEachMacros:
- 'snd_soc_dapm_widget_for_each_path_safe' - 'snd_soc_dapm_widget_for_each_path_safe'
- 'snd_soc_dapm_widget_for_each_sink_path' - 'snd_soc_dapm_widget_for_each_sink_path'
- 'snd_soc_dapm_widget_for_each_source_path' - 'snd_soc_dapm_widget_for_each_source_path'
- 'sparsebit_for_each_set_range'
- 'strlist__for_each_entry'
- 'strlist__for_each_entry_safe'
- 'sym_for_each_insn'
- 'sym_for_each_insn_continue_reverse'
- 'symbols__for_each_entry'
- 'tb_property_for_each' - 'tb_property_for_each'
- 'tcf_act_for_each_action'
- 'tcf_exts_for_each_action' - 'tcf_exts_for_each_action'
- 'test_suite__for_each_test_case'
- 'tool_pmu__for_each_event'
- 'ttm_bo_lru_for_each_reserved_guarded'
- 'ttm_resource_manager_for_each_res'
- 'udp_lrpa_for_each_entry_rcu'
- 'udp_portaddr_for_each_entry' - 'udp_portaddr_for_each_entry'
- 'udp_portaddr_for_each_entry_rcu' - 'udp_portaddr_for_each_entry_rcu'
- 'usb_hub_for_each_child' - 'usb_hub_for_each_child'
@@ -479,7 +722,15 @@ ForEachMacros:
- 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf'
- 'v4l2_m2m_for_each_src_buf_safe' - 'v4l2_m2m_for_each_src_buf_safe'
- 'virtio_device_for_each_vq' - 'virtio_device_for_each_vq'
- 'vkms_config_for_each_connector'
- 'vkms_config_for_each_crtc'
- 'vkms_config_for_each_encoder'
- 'vkms_config_for_each_plane'
- 'vkms_config_connector_for_each_possible_encoder'
- 'vkms_config_encoder_for_each_possible_crtc'
- 'vkms_config_plane_for_each_possible_crtc'
- 'while_for_each_ftrace_op' - 'while_for_each_ftrace_op'
- 'workloads__for_each'
- 'xa_for_each' - 'xa_for_each'
- 'xa_for_each_marked' - 'xa_for_each_marked'
- 'xa_for_each_range' - 'xa_for_each_range'
@@ -492,15 +743,20 @@ ForEachMacros:
- 'xbc_node_for_each_array_value' - 'xbc_node_for_each_array_value'
- 'xbc_node_for_each_child' - 'xbc_node_for_each_child'
- 'xbc_node_for_each_key_value' - 'xbc_node_for_each_key_value'
- 'xbc_node_for_each_subkey'
- 'ynl_attr_for_each'
- 'ynl_attr_for_each_nested'
- 'ynl_attr_for_each_payload'
- 'zorro_for_each_dev' - 'zorro_for_each_dev'
#IncludeBlocks: Preserve # Unknown to clang-format-5.0 IncludeBlocks: Preserve
IncludeCategories: IncludeCategories:
- Regex: '.*' - Regex: '.*'
Priority: 1 Priority: 1
IncludeIsMainRegex: '(Test)?$' IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false IndentCaseLabels: false
#IndentPPDirectives: None # Unknown to clang-format-5.0 IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 8 IndentWidth: 8
IndentWrappedFunctionNames: false IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave JavaScriptQuotes: Leave
@@ -510,13 +766,13 @@ MacroBlockBegin: ''
MacroBlockEnd: '' MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
NamespaceIndentation: None NamespaceIndentation: None
#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0 ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 8 ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true ObjCSpaceBeforeProtocolList: true
# Taken from git's rules # Taken from git's rules
#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0 PenaltyBreakAssignment: 10
PenaltyBreakBeforeFirstCallParameter: 30 PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10 PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0 PenaltyBreakFirstLessLess: 0
@@ -527,14 +783,14 @@ PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right PointerAlignment: Right
ReflowComments: false ReflowComments: false
SortIncludes: false SortIncludes: false
#SortUsingDeclarations: false # Unknown to clang-format-4.0 SortUsingDeclarations: false
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0 SpaceBeforeCtorInitializerColon: true
#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0 SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatementsExceptForEachMacros
#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0 SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1 SpacesBeforeTrailingComments: 1
SpacesInAngles: false SpacesInAngles: false

View File

@@ -31,7 +31,8 @@ static DEFINE_MUTEX(allowlist_mutex);
static struct root_profile default_root_profile; static struct root_profile default_root_profile;
static struct non_root_profile default_non_root_profile; static struct non_root_profile default_non_root_profile;
static int allow_list_arr[PAGE_SIZE / sizeof(int)] __read_mostly __aligned(PAGE_SIZE); static int allow_list_arr[PAGE_SIZE / sizeof(int)] __read_mostly
__aligned(PAGE_SIZE);
static int allow_list_pointer __read_mostly = 0; static int allow_list_pointer __read_mostly = 0;
static void remove_uid_from_arr(uid_t uid) static void remove_uid_from_arr(uid_t uid)
@@ -118,7 +119,8 @@ static void ksu_grant_root_to_shell()
.current_uid = 2000, .current_uid = 2000,
}; };
strcpy(profile.key, "com.android.shell"); strcpy(profile.key, "com.android.shell");
strcpy(profile.rp_config.profile.selinux_domain, KSU_DEFAULT_SELINUX_DOMAIN); strcpy(profile.rp_config.profile.selinux_domain,
KSU_DEFAULT_SELINUX_DOMAIN);
ksu_set_app_profile(&profile, false); ksu_set_app_profile(&profile, false);
} }
#endif #endif
@@ -144,7 +146,8 @@ exit:
return found; return found;
} }
static inline bool forbid_system_uid(uid_t uid) { static inline bool forbid_system_uid(uid_t uid)
{
#define SHELL_UID 2000 #define SHELL_UID 2000
#define SYSTEM_UID 1000 #define SYSTEM_UID 1000
return uid < SHELL_UID && uid != SYSTEM_UID; return uid < SHELL_UID && uid != SYSTEM_UID;
@@ -220,9 +223,11 @@ bool ksu_set_app_profile(struct app_profile *profile, bool persist)
out: out:
if (profile->current_uid <= BITMAP_UID_MAX) { if (profile->current_uid <= BITMAP_UID_MAX) {
if (profile->allow_su) if (profile->allow_su)
allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] |= 1 << (profile->current_uid % BITS_PER_BYTE); allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] |=
1 << (profile->current_uid % BITS_PER_BYTE);
else else
allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] &= ~(1 << (profile->current_uid % BITS_PER_BYTE)); allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] &=
~(1 << (profile->current_uid % BITS_PER_BYTE));
} else { } else {
if (profile->allow_su) { if (profile->allow_su) {
/* /*
@@ -234,7 +239,8 @@ out:
WARN_ON(1); WARN_ON(1);
return false; return false;
} }
allow_list_arr[allow_list_pointer++] = profile->current_uid; allow_list_arr[allow_list_pointer++] =
profile->current_uid;
} else { } else {
remove_uid_from_arr(profile->current_uid); remove_uid_from_arr(profile->current_uid);
} }
@@ -274,13 +280,15 @@ bool __ksu_is_allow_uid(uid_t uid)
return false; return false;
} }
if (likely(ksu_is_manager_uid_valid()) && unlikely(ksu_get_manager_uid() == uid)) { if (likely(ksu_is_manager_uid_valid()) &&
unlikely(ksu_get_manager_uid() == uid)) {
// manager is always allowed! // manager is always allowed!
return true; return true;
} }
if (likely(uid <= BITMAP_UID_MAX)) { if (likely(uid <= BITMAP_UID_MAX)) {
return !!(allow_list_bitmap[uid / BITS_PER_BYTE] & (1 << (uid % BITS_PER_BYTE))); return !!(allow_list_bitmap[uid / BITS_PER_BYTE] &
(1 << (uid % BITS_PER_BYTE)));
} else { } else {
for (i = 0; i < allow_list_pointer; i++) { for (i = 0; i < allow_list_pointer; i++) {
if (allow_list_arr[i] == uid) if (allow_list_arr[i] == uid)
@@ -294,7 +302,8 @@ bool __ksu_is_allow_uid(uid_t uid)
bool ksu_uid_should_umount(uid_t uid) bool ksu_uid_should_umount(uid_t uid)
{ {
struct app_profile profile = { .current_uid = uid }; struct app_profile profile = { .current_uid = uid };
if (likely(ksu_is_manager_uid_valid()) && unlikely(ksu_get_manager_uid() == uid)) { if (likely(ksu_is_manager_uid_valid()) &&
unlikely(ksu_get_manager_uid() == uid)) {
// we should not umount on manager! // we should not umount on manager!
return false; return false;
} }
@@ -359,10 +368,11 @@ void do_save_allow_list(struct work_struct *work)
struct list_head *pos = NULL; struct list_head *pos = NULL;
loff_t off = 0; loff_t off = 0;
struct file *fp = struct file *fp = ksu_filp_open_compat(
ksu_filp_open_compat(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644); KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
pr_err("save_allow_list create file failed: %ld\n", PTR_ERR(fp)); pr_err("save_allow_list create file failed: %ld\n",
PTR_ERR(fp));
return; return;
} }
@@ -450,7 +460,8 @@ exit:
filp_close(fp, 0); filp_close(fp, 0);
} }
void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data) void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *),
void *data)
{ {
struct perm_data *np = NULL; struct perm_data *np = NULL;
struct perm_data *n = NULL; struct perm_data *n = NULL;
@@ -468,7 +479,8 @@ void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data
pr_info("prune uid: %d, package: %s\n", uid, package); pr_info("prune uid: %d, package: %s\n", uid, package);
list_del(&np->list); list_del(&np->list);
if (likely(uid <= BITMAP_UID_MAX)) { if (likely(uid <= BITMAP_UID_MAX)) {
allow_list_bitmap[uid / BITS_PER_BYTE] &= ~(1 << (uid % BITS_PER_BYTE)); allow_list_bitmap[uid / BITS_PER_BYTE] &=
~(1 << (uid % BITS_PER_BYTE));
} }
remove_uid_from_arr(uid); remove_uid_from_arr(uid);
smp_mb(); smp_mb();

View File

@@ -17,7 +17,8 @@ bool __ksu_is_allow_uid(uid_t uid);
bool ksu_get_allow_list(int *array, int *length, bool allow); bool ksu_get_allow_list(int *array, int *length, bool allow);
void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, char *, void *), void *data); void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, char *, void *),
void *data);
bool ksu_get_app_profile(struct app_profile *); bool ksu_get_app_profile(struct app_profile *);
bool ksu_set_app_profile(struct app_profile *, bool persist); bool ksu_set_app_profile(struct app_profile *, bool persist);

View File

@@ -82,7 +82,8 @@ static int ksu_sha256(const unsigned char *data, unsigned int datalen,
crypto_free_shash(alg); crypto_free_shash(alg);
return ret; return ret;
} }
static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset, int *matched_index) static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset,
int *matched_index)
{ {
int i; int i;
struct apk_sign_key sign_key; struct apk_sign_key sign_key;
@@ -136,7 +137,8 @@ static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset, i
hash_str[SHA256_DIGEST_SIZE * 2] = '\0'; hash_str[SHA256_DIGEST_SIZE * 2] = '\0';
bin2hex(hash_str, digest, SHA256_DIGEST_SIZE); bin2hex(hash_str, digest, SHA256_DIGEST_SIZE);
pr_info("sha256: %s, expected: %s, index: %d\n", hash_str, sign_key.sha256, i); pr_info("sha256: %s, expected: %s, index: %d\n", hash_str,
sign_key.sha256, i);
if (strcmp(sign_key.sha256, hash_str) == 0) { if (strcmp(sign_key.sha256, hash_str) == 0) {
signature_valid = true; signature_valid = true;
@@ -202,7 +204,8 @@ static bool has_v1_signature_file(struct file *fp)
return false; return false;
} }
static __always_inline bool check_v2_signature(char *path, bool check_multi_manager, int *signature_index) static __always_inline bool
check_v2_signature(char *path, bool check_multi_manager, int *signature_index)
{ {
unsigned char buffer[0x11] = { 0 }; unsigned char buffer[0x11] = { 0 };
u32 size4; u32 size4;
@@ -279,7 +282,8 @@ static __always_inline bool check_v2_signature(char *path, bool check_multi_mana
offset = 4; offset = 4;
if (id == 0x7109871au) { if (id == 0x7109871au) {
v2_signing_blocks++; v2_signing_blocks++;
bool result = check_block(fp, &size4, &pos, &offset, &matched_index); bool result = check_block(fp, &size4, &pos, &offset,
&matched_index);
if (result) { if (result) {
v2_signing_valid = true; v2_signing_valid = true;
} }
@@ -331,7 +335,8 @@ clean:
if (check_multi_manager) { if (check_multi_manager) {
// 0: ShirkNeko/SukiSU, 1: Dynamic Sign // 0: ShirkNeko/SukiSU, 1: Dynamic Sign
if (matched_index == 0 || matched_index == 1) { if (matched_index == 0 || matched_index == 1) {
pr_info("Multi-manager APK detected (dynamic_sign enabled): signature_index=%d\n", matched_index); pr_info("Multi-manager APK detected (dynamic_sign enabled): signature_index=%d\n",
matched_index);
return true; return true;
} }
return false; return false;

View File

@@ -186,8 +186,8 @@ void escape_to_root(void)
// setup capabilities // setup capabilities
// we need CAP_DAC_READ_SEARCH becuase `/data/adb/ksud` is not accessible for non root process // we need CAP_DAC_READ_SEARCH becuase `/data/adb/ksud` is not accessible for non root process
// we add it here but don't add it to cap_inhertiable, it would be dropped automaticly after exec! // we add it here but don't add it to cap_inhertiable, it would be dropped automaticly after exec!
u64 cap_for_ksud = u64 cap_for_ksud = profile->capabilities.effective |
profile->capabilities.effective | CAP_DAC_READ_SEARCH; CAP_DAC_READ_SEARCH;
memcpy(&newcreds->cap_effective, &cap_for_ksud, memcpy(&newcreds->cap_effective, &cap_for_ksud,
sizeof(newcreds->cap_effective)); sizeof(newcreds->cap_effective));
memcpy(&newcreds->cap_permitted, &profile->capabilities.effective, memcpy(&newcreds->cap_permitted, &profile->capabilities.effective,
@@ -244,7 +244,8 @@ int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry)
} }
#ifdef CONFIG_EXT4_FS #ifdef CONFIG_EXT4_FS
static void nuke_ext4_sysfs() { static void nuke_ext4_sysfs()
{
struct path path; struct path path;
int err = kern_path("/data/adb/modules", 0, &path); int err = kern_path("/data/adb/modules", 0, &path);
if (err) { if (err) {
@@ -264,7 +265,9 @@ static void nuke_ext4_sysfs() {
path_put(&path); path_put(&path);
} }
#else #else
static inline void nuke_ext4_sysfs() { } static inline void nuke_ext4_sysfs()
{
}
#endif #endif
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
@@ -340,11 +343,14 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
if (arg2 == CMD_GET_FULL_VERSION) { if (arg2 == CMD_GET_FULL_VERSION) {
char ksu_version_full[KSU_FULL_VERSION_STRING] = { 0 }; char ksu_version_full[KSU_FULL_VERSION_STRING] = { 0 };
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
strscpy(ksu_version_full, KSU_VERSION_FULL, KSU_FULL_VERSION_STRING); strscpy(ksu_version_full, KSU_VERSION_FULL,
KSU_FULL_VERSION_STRING);
#else #else
strlcpy(ksu_version_full, KSU_VERSION_FULL, KSU_FULL_VERSION_STRING); strlcpy(ksu_version_full, KSU_VERSION_FULL,
KSU_FULL_VERSION_STRING);
#endif #endif
if (copy_to_user((void __user *)arg3, ksu_version_full, KSU_FULL_VERSION_STRING)) { if (copy_to_user((void __user *)arg3, ksu_version_full,
KSU_FULL_VERSION_STRING)) {
pr_err("prctl reply error, cmd: %lu\n", arg2); pr_err("prctl reply error, cmd: %lu\n", arg2);
return -EFAULT; return -EFAULT;
} }
@@ -359,7 +365,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
struct dynamic_sign_user_config config; struct dynamic_sign_user_config config;
if (copy_from_user(&config, (void __user *)arg3, sizeof(config))) { if (copy_from_user(&config, (void __user *)arg3,
sizeof(config))) {
pr_err("copy dynamic sign config failed\n"); pr_err("copy dynamic sign config failed\n");
return 0; return 0;
} }
@@ -367,7 +374,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
int ret = ksu_handle_dynamic_sign(&config); int ret = ksu_handle_dynamic_sign(&config);
if (ret == 0 && config.operation == DYNAMIC_SIGN_OP_GET) { if (ret == 0 && config.operation == DYNAMIC_SIGN_OP_GET) {
if (copy_to_user((void __user *)arg3, &config, sizeof(config))) { if (copy_to_user((void __user *)arg3, &config,
sizeof(config))) {
pr_err("copy dynamic sign config back failed\n"); pr_err("copy dynamic sign config back failed\n");
return 0; return 0;
} }
@@ -391,7 +399,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
int ret = ksu_get_active_managers(&manager_info); int ret = ksu_get_active_managers(&manager_info);
if (ret == 0) { if (ret == 0) {
if (copy_to_user((void __user *)arg3, &manager_info, sizeof(manager_info))) { if (copy_to_user((void __user *)arg3, &manager_info,
sizeof(manager_info))) {
pr_err("copy manager list failed\n"); pr_err("copy manager list failed\n");
return 0; return 0;
} }
@@ -544,7 +553,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
#endif #endif
if (arg2 == CMD_ENABLE_KPM) { if (arg2 == CMD_ENABLE_KPM) {
bool KPM_Enabled = IS_ENABLED(CONFIG_KPM); bool KPM_Enabled = IS_ENABLED(CONFIG_KPM);
if (copy_to_user((void __user *)arg3, &KPM_Enabled, sizeof(KPM_Enabled))) if (copy_to_user((void __user *)arg3, &KPM_Enabled,
sizeof(KPM_Enabled)))
pr_info("KPM: copy_to_user() failed\n"); pr_info("KPM: copy_to_user() failed\n");
return 0; return 0;
} }
@@ -654,7 +664,8 @@ static bool should_umount(struct path *path)
return false; return false;
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) || defined(KSU_HAS_PATH_UMOUNT) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) || \
defined(KSU_HAS_PATH_UMOUNT)
static void ksu_path_umount(const char *mnt, struct path *path, int flags) static void ksu_path_umount(const char *mnt, struct path *path, int flags)
{ {
int ret = path_umount(path, flags); int ret = path_umount(path, flags);
@@ -781,11 +792,9 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
return 0; return 0;
} }
// kernel 4.4 and 4.9 // kernel 4.4 and 4.9
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \
defined(CONFIG_IS_HW_HISI) || \ defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
int ksu_key_permission(key_ref_t key_ref, const struct cred *cred, int ksu_key_permission(key_ref_t key_ref, const struct cred *cred,
unsigned perm) unsigned perm)
{ {
@@ -826,9 +835,11 @@ static int ksu_task_fix_setuid(struct cred *new, const struct cred *old,
extern int __ksu_handle_devpts(struct inode *inode); extern int __ksu_handle_devpts(struct inode *inode);
static int ksu_inode_permission(struct inode *inode, int mask) static int ksu_inode_permission(struct inode *inode, int mask)
{ {
if (unlikely(inode->i_sb && inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)) { if (unlikely(inode->i_sb &&
inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)) {
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
pr_info("%s: devpts inode accessed with mask: %x\n", __func__, mask); pr_info("%s: devpts inode accessed with mask: %x\n", __func__,
mask);
#endif #endif
__ksu_handle_devpts(inode); __ksu_handle_devpts(inode);
} }
@@ -841,8 +852,7 @@ static struct security_hook_list ksu_hooks[] = {
LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid), LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid),
LSM_HOOK_INIT(inode_permission, ksu_inode_permission), LSM_HOOK_INIT(inode_permission, ksu_inode_permission),
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \
defined(CONFIG_IS_HW_HISI) || \ defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
LSM_HOOK_INIT(key_permission, ksu_key_permission) LSM_HOOK_INIT(key_permission, ksu_key_permission)
#endif #endif
}; };

View File

@@ -65,10 +65,12 @@ void ksu_add_manager(uid_t uid, int signature_index)
// Check if manager already exists and update // Check if manager already exists and update
for (i = 0; i < MAX_MANAGERS; i++) { for (i = 0; i < MAX_MANAGERS; i++) {
if (active_managers[i].is_active && active_managers[i].uid == uid) { if (active_managers[i].is_active &&
active_managers[i].uid == uid) {
active_managers[i].signature_index = signature_index; active_managers[i].signature_index = signature_index;
spin_unlock_irqrestore(&managers_lock, flags); spin_unlock_irqrestore(&managers_lock, flags);
pr_info("Updated manager uid=%d, signature_index=%d\n", uid, signature_index); pr_info("Updated manager uid=%d, signature_index=%d\n",
uid, signature_index);
return; return;
} }
} }
@@ -80,7 +82,8 @@ void ksu_add_manager(uid_t uid, int signature_index)
active_managers[i].signature_index = signature_index; active_managers[i].signature_index = signature_index;
active_managers[i].is_active = true; active_managers[i].is_active = true;
spin_unlock_irqrestore(&managers_lock, flags); spin_unlock_irqrestore(&managers_lock, flags);
pr_info("Added manager uid=%d, signature_index=%d\n", uid, signature_index); pr_info("Added manager uid=%d, signature_index=%d\n",
uid, signature_index);
return; return;
} }
} }
@@ -101,7 +104,8 @@ void ksu_remove_manager(uid_t uid)
spin_lock_irqsave(&managers_lock, flags); spin_lock_irqsave(&managers_lock, flags);
for (i = 0; i < MAX_MANAGERS; i++) { for (i = 0; i < MAX_MANAGERS; i++) {
if (active_managers[i].is_active && active_managers[i].uid == uid) { if (active_managers[i].is_active &&
active_managers[i].uid == uid) {
active_managers[i].is_active = false; active_managers[i].is_active = false;
pr_info("Removed manager uid=%d\n", uid); pr_info("Removed manager uid=%d\n", uid);
break; break;
@@ -124,7 +128,8 @@ bool ksu_is_any_manager(uid_t uid)
spin_lock_irqsave(&managers_lock, flags); spin_lock_irqsave(&managers_lock, flags);
for (i = 0; i < MAX_MANAGERS; i++) { for (i = 0; i < MAX_MANAGERS; i++) {
if (active_managers[i].is_active && active_managers[i].uid == uid) { if (active_managers[i].is_active &&
active_managers[i].uid == uid) {
is_manager = true; is_manager = true;
break; break;
} }
@@ -152,7 +157,8 @@ int ksu_get_manager_signature_index(uid_t uid)
spin_lock_irqsave(&managers_lock, flags); spin_lock_irqsave(&managers_lock, flags);
for (i = 0; i < MAX_MANAGERS; i++) { for (i = 0; i < MAX_MANAGERS; i++) {
if (active_managers[i].is_active && active_managers[i].uid == uid) { if (active_managers[i].is_active &&
active_managers[i].uid == uid) {
signature_index = active_managers[i].signature_index; signature_index = active_managers[i].signature_index;
break; break;
} }
@@ -172,7 +178,8 @@ static void clear_dynamic_manager(void)
for (i = 0; i < MAX_MANAGERS; i++) { for (i = 0; i < MAX_MANAGERS; i++) {
if (active_managers[i].is_active) { if (active_managers[i].is_active) {
pr_info("Clearing dynamic manager uid=%d (signature_index=%d) for rescan\n", pr_info("Clearing dynamic manager uid=%d (signature_index=%d) for rescan\n",
active_managers[i].uid, active_managers[i].signature_index); active_managers[i].uid,
active_managers[i].signature_index);
active_managers[i].is_active = false; active_managers[i].is_active = false;
} }
} }
@@ -202,8 +209,10 @@ int ksu_get_active_managers(struct manager_list_info *info)
for (i = 0; i < MAX_MANAGERS && count < 2; i++) { for (i = 0; i < MAX_MANAGERS && count < 2; i++) {
if (active_managers[i].is_active) { if (active_managers[i].is_active) {
info->managers[count].uid = active_managers[i].uid; info->managers[count].uid =
info->managers[count].signature_index = active_managers[i].signature_index; active_managers[i].uid;
info->managers[count].signature_index =
active_managers[i].signature_index;
count++; count++;
} }
} }
@@ -233,23 +242,28 @@ static void do_save_dynamic_sign(struct work_struct *work)
return; return;
} }
fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN, O_WRONLY | O_CREAT | O_TRUNC, 0644); fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN,
O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
pr_err("save_dynamic_sign create file failed: %ld\n", PTR_ERR(fp)); pr_err("save_dynamic_sign create file failed: %ld\n",
PTR_ERR(fp));
return; return;
} }
if (ksu_kernel_write_compat(fp, &magic, sizeof(magic), &off) != sizeof(magic)) { if (ksu_kernel_write_compat(fp, &magic, sizeof(magic), &off) !=
sizeof(magic)) {
pr_err("save_dynamic_sign write magic failed.\n"); pr_err("save_dynamic_sign write magic failed.\n");
goto exit; goto exit;
} }
if (ksu_kernel_write_compat(fp, &version, sizeof(version), &off) != sizeof(version)) { if (ksu_kernel_write_compat(fp, &version, sizeof(version), &off) !=
sizeof(version)) {
pr_err("save_dynamic_sign write version failed.\n"); pr_err("save_dynamic_sign write version failed.\n");
goto exit; goto exit;
} }
if (ksu_kernel_write_compat(fp, &config_to_save, sizeof(config_to_save), &off) != sizeof(config_to_save)) { if (ksu_kernel_write_compat(fp, &config_to_save, sizeof(config_to_save),
&off) != sizeof(config_to_save)) {
pr_err("save_dynamic_sign write config failed.\n"); pr_err("save_dynamic_sign write config failed.\n");
goto exit; goto exit;
} }
@@ -276,32 +290,37 @@ static void do_load_dynamic_sign(struct work_struct *work)
if (PTR_ERR(fp) == -ENOENT) { if (PTR_ERR(fp) == -ENOENT) {
pr_info("No saved dynamic sign config found\n"); pr_info("No saved dynamic sign config found\n");
} else { } else {
pr_err("load_dynamic_sign open file failed: %ld\n", PTR_ERR(fp)); pr_err("load_dynamic_sign open file failed: %ld\n",
PTR_ERR(fp));
} }
return; return;
} }
if (ksu_kernel_read_compat(fp, &magic, sizeof(magic), &off) != sizeof(magic) || if (ksu_kernel_read_compat(fp, &magic, sizeof(magic), &off) !=
sizeof(magic) ||
magic != DYNAMIC_SIGN_FILE_MAGIC) { magic != DYNAMIC_SIGN_FILE_MAGIC) {
pr_err("dynamic sign file invalid magic: %x!\n", magic); pr_err("dynamic sign file invalid magic: %x!\n", magic);
goto exit; goto exit;
} }
if (ksu_kernel_read_compat(fp, &version, sizeof(version), &off) != sizeof(version)) { if (ksu_kernel_read_compat(fp, &version, sizeof(version), &off) !=
sizeof(version)) {
pr_err("dynamic sign read version failed\n"); pr_err("dynamic sign read version failed\n");
goto exit; goto exit;
} }
pr_info("dynamic sign file version: %d\n", version); pr_info("dynamic sign file version: %d\n", version);
ret = ksu_kernel_read_compat(fp, &loaded_config, sizeof(loaded_config), &off); ret = ksu_kernel_read_compat(fp, &loaded_config, sizeof(loaded_config),
&off);
if (ret <= 0) { if (ret <= 0) {
pr_info("load_dynamic_sign read err: %zd\n", ret); pr_info("load_dynamic_sign read err: %zd\n", ret);
goto exit; goto exit;
} }
if (ret != sizeof(loaded_config)) { if (ret != sizeof(loaded_config)) {
pr_err("load_dynamic_sign read incomplete config: %zd/%zu\n", ret, sizeof(loaded_config)); pr_err("load_dynamic_sign read incomplete config: %zd/%zu\n",
ret, sizeof(loaded_config));
goto exit; goto exit;
} }
@@ -311,7 +330,8 @@ static void do_load_dynamic_sign(struct work_struct *work)
} }
if (strlen(loaded_config.hash) != 64) { if (strlen(loaded_config.hash) != 64) {
pr_err("Invalid saved config hash length: %zu\n", strlen(loaded_config.hash)); pr_err("Invalid saved config hash length: %zu\n",
strlen(loaded_config.hash));
goto exit; goto exit;
} }
@@ -319,7 +339,8 @@ static void do_load_dynamic_sign(struct work_struct *work)
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
char c = loaded_config.hash[i]; char c = loaded_config.hash[i];
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))) { if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))) {
pr_err("Invalid saved config hash character at position %d: %c\n", i, c); pr_err("Invalid saved config hash character at position %d: %c\n",
i, c);
goto exit; goto exit;
} }
} }
@@ -348,14 +369,17 @@ static void do_clear_dynamic_sign(struct work_struct *work)
memset(zero_buffer, 0, sizeof(zero_buffer)); memset(zero_buffer, 0, sizeof(zero_buffer));
fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN, O_WRONLY | O_CREAT | O_TRUNC, 0644); fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN,
O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
pr_err("clear_dynamic_sign create file failed: %ld\n", PTR_ERR(fp)); pr_err("clear_dynamic_sign create file failed: %ld\n",
PTR_ERR(fp));
return; return;
} }
// Write null bytes to overwrite the file content // Write null bytes to overwrite the file content
if (ksu_kernel_write_compat(fp, zero_buffer, sizeof(zero_buffer), &off) != sizeof(zero_buffer)) { if (ksu_kernel_write_compat(fp, zero_buffer, sizeof(zero_buffer),
&off) != sizeof(zero_buffer)) {
pr_err("clear_dynamic_sign write null bytes failed.\n"); pr_err("clear_dynamic_sign write null bytes failed.\n");
} else { } else {
pr_info("Dynamic sign config file cleared successfully\n"); pr_info("Dynamic sign config file cleared successfully\n");
@@ -387,15 +411,18 @@ int ksu_handle_dynamic_sign(struct dynamic_sign_user_config *config)
} }
if (strlen(config->hash) != 64) { if (strlen(config->hash) != 64) {
pr_err("invalid hash length: %zu\n", strlen(config->hash)); pr_err("invalid hash length: %zu\n",
strlen(config->hash));
return -EINVAL; return -EINVAL;
} }
// Validate hash format // Validate hash format
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
char c = config->hash[i]; char c = config->hash[i];
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))) { if (!((c >= '0' && c <= '9') ||
pr_err("invalid hash character at position %d: %c\n", i, c); (c >= 'a' && c <= 'f'))) {
pr_err("invalid hash character at position %d: %c\n",
i, c);
return -EINVAL; return -EINVAL;
} }
} }
@@ -403,9 +430,11 @@ int ksu_handle_dynamic_sign(struct dynamic_sign_user_config *config)
spin_lock_irqsave(&dynamic_sign_lock, flags); spin_lock_irqsave(&dynamic_sign_lock, flags);
dynamic_sign.size = config->size; dynamic_sign.size = config->size;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
strscpy(dynamic_sign.hash, config->hash, sizeof(dynamic_sign.hash)); strscpy(dynamic_sign.hash, config->hash,
sizeof(dynamic_sign.hash));
#else #else
strlcpy(dynamic_sign.hash, config->hash, sizeof(dynamic_sign.hash)); strlcpy(dynamic_sign.hash, config->hash,
sizeof(dynamic_sign.hash));
#endif #endif
dynamic_sign.is_set = 1; dynamic_sign.is_set = 1;
spin_unlock_irqrestore(&dynamic_sign_lock, flags); spin_unlock_irqrestore(&dynamic_sign_lock, flags);
@@ -420,9 +449,11 @@ int ksu_handle_dynamic_sign(struct dynamic_sign_user_config *config)
if (dynamic_sign.is_set) { if (dynamic_sign.is_set) {
config->size = dynamic_sign.size; config->size = dynamic_sign.size;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
strscpy(config->hash, dynamic_sign.hash, sizeof(config->hash)); strscpy(config->hash, dynamic_sign.hash,
sizeof(config->hash));
#else #else
strlcpy(config->hash, dynamic_sign.hash, sizeof(config->hash)); strlcpy(config->hash, dynamic_sign.hash,
sizeof(config->hash));
#endif #endif
ret = 0; ret = 0;
} else { } else {
@@ -434,7 +465,8 @@ int ksu_handle_dynamic_sign(struct dynamic_sign_user_config *config)
case DYNAMIC_SIGN_OP_CLEAR: case DYNAMIC_SIGN_OP_CLEAR:
spin_lock_irqsave(&dynamic_sign_lock, flags); spin_lock_irqsave(&dynamic_sign_lock, flags);
dynamic_sign.size = 0x300; dynamic_sign.size = 0x300;
strcpy(dynamic_sign.hash, "0000000000000000000000000000000000000000000000000000000000000000"); strcpy(dynamic_sign.hash,
"0000000000000000000000000000000000000000000000000000000000000000");
dynamic_sign.is_set = 0; dynamic_sign.is_set = 0;
spin_unlock_irqrestore(&dynamic_sign_lock, flags); spin_unlock_irqrestore(&dynamic_sign_lock, flags);
@@ -448,7 +480,8 @@ int ksu_handle_dynamic_sign(struct dynamic_sign_user_config *config)
break; break;
default: default:
pr_err("Invalid dynamic sign operation: %d\n", config->operation); pr_err("Invalid dynamic sign operation: %d\n",
config->operation);
return -EINVAL; return -EINVAL;
} }
@@ -495,8 +528,10 @@ bool ksu_get_dynamic_sign_config(unsigned int *size, const char **hash)
spin_lock_irqsave(&dynamic_sign_lock, flags); spin_lock_irqsave(&dynamic_sign_lock, flags);
if (dynamic_sign.is_set) { if (dynamic_sign.is_set) {
if (size) *size = dynamic_sign.size; if (size)
if (hash) *hash = dynamic_sign.hash; *size = dynamic_sign.size;
if (hash)
*hash = dynamic_sign.hash;
valid = true; valid = true;
} }
spin_unlock_irqrestore(&dynamic_sign_lock, flags); spin_unlock_irqrestore(&dynamic_sign_lock, flags);

View File

@@ -11,8 +11,7 @@
#include "kernel_compat.h" // Add check Huawei Device #include "kernel_compat.h" // Add check Huawei Device
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \
defined(CONFIG_IS_HW_HISI) || \ defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
#include <linux/key.h> #include <linux/key.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/cred.h> #include <linux/cred.h>
@@ -82,8 +81,7 @@ void ksu_android_ns_fs_check()
struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode) struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
{ {
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \
defined(CONFIG_IS_HW_HISI) || \ defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
if (init_session_keyring != NULL && !current_cred()->session_keyring && if (init_session_keyring != NULL && !current_cred()->session_keyring &&
(current->flags & PF_WQ_WORKER)) { (current->flags & PF_WQ_WORKER)) {
pr_info("installing init session keyring for older kernel\n"); pr_info("installing init session keyring for older kernel\n");
@@ -112,7 +110,8 @@ struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count, ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
loff_t *pos) loff_t *pos)
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) || defined(KSU_OPTIONAL_KERNEL_READ) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) || \
defined(KSU_OPTIONAL_KERNEL_READ)
return kernel_read(p, buf, count, pos); return kernel_read(p, buf, count, pos);
#else #else
loff_t offset = pos ? *pos : 0; loff_t offset = pos ? *pos : 0;
@@ -127,7 +126,8 @@ ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count, ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count,
loff_t *pos) loff_t *pos)
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) || defined(KSU_OPTIONAL_KERNEL_WRITE) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) || \
defined(KSU_OPTIONAL_KERNEL_WRITE)
return kernel_write(p, buf, count, pos); return kernel_write(p, buf, count, pos);
#else #else
loff_t offset = pos ? *pos : 0; loff_t offset = pos ? *pos : 0;
@@ -139,7 +139,8 @@ ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count,
#endif #endif
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) || defined(KSU_OPTIONAL_STRNCPY) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) || \
defined(KSU_OPTIONAL_STRNCPY)
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
long count) long count)
{ {

View File

@@ -36,8 +36,7 @@ extern long ksu_strncpy_from_user_retry(char *dst,
long count); long count);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \
defined(CONFIG_IS_HW_HISI) || \ defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
extern struct key *init_session_keyring; extern struct key *init_session_keyring;
#endif #endif

View File

@@ -34,29 +34,29 @@ unsigned long sukisu_compact_find_symbol(const char* name);
// ====================================================================== // ======================================================================
// 兼容函数 for KPM // 兼容函数 for KPM
static static int sukisu_is_su_allow_uid(uid_t uid)
int sukisu_is_su_allow_uid(uid_t uid) { {
return ksu_is_allow_uid(uid) ? 1 : 0; return ksu_is_allow_uid(uid) ? 1 : 0;
} }
static static int sukisu_get_ap_mod_exclude(uid_t uid)
int sukisu_get_ap_mod_exclude(uid_t uid) { {
// Not supported // Not supported
return 0; return 0;
} }
static static int sukisu_is_uid_should_umount(uid_t uid)
int sukisu_is_uid_should_umount(uid_t uid) { {
return ksu_uid_should_umount(uid) ? 1 : 0; return ksu_uid_should_umount(uid) ? 1 : 0;
} }
static static int sukisu_is_current_uid_manager()
int sukisu_is_current_uid_manager() { {
return is_manager(); return is_manager();
} }
static static uid_t sukisu_get_manager_uid()
uid_t sukisu_get_manager_uid() { {
return ksu_manager_uid; return ksu_manager_uid;
} }
@@ -78,12 +78,15 @@ static struct CompactAddressSymbol address_symbol [] = {
{ "get_manager_uid", &sukisu_get_manager_uid } { "get_manager_uid", &sukisu_get_manager_uid }
}; };
unsigned long sukisu_compact_find_symbol(const char* name) { unsigned long sukisu_compact_find_symbol(const char *name)
{
int i; int i;
unsigned long addr; unsigned long addr;
// 先自己在地址表部分查出来 // 先自己在地址表部分查出来
for(i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) { for (i = 0;
i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol));
i++) {
struct CompactAddressSymbol *symbol = &address_symbol[i]; struct CompactAddressSymbol *symbol = &address_symbol[i];
if (strcmp(name, symbol->symbol_name) == 0) { if (strcmp(name, symbol->symbol_name) == 0) {
return (unsigned long)symbol->addr; return (unsigned long)symbol->addr;

View File

@@ -56,71 +56,86 @@
// ============================================================================================ // ============================================================================================
noinline noinline NO_OPTIMIZE void sukisu_kpm_load_module_path(const char *path,
NO_OPTIMIZE const char *args,
void sukisu_kpm_load_module_path(const char* path, const char* args, void* ptr, void __user* result) { void *ptr,
void __user *result)
{
// This is a KPM module stub. // This is a KPM module stub.
int res = -1; int res = -1;
printk("KPM: Stub function called (sukisu_kpm_load_module_path). path=%s args=%s ptr=%p\n", path, args, ptr); printk("KPM: Stub function called (sukisu_kpm_load_module_path). path=%s args=%s ptr=%p\n",
path, args, ptr);
__asm__ volatile("nop"); // 精确控制循环不被优化 __asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
} }
noinline noinline NO_OPTIMIZE void sukisu_kpm_unload_module(const char *name, void *ptr,
NO_OPTIMIZE void __user *result)
void sukisu_kpm_unload_module(const char* name, void* ptr, void __user* result) { {
// This is a KPM module stub. // This is a KPM module stub.
int res = -1; int res = -1;
printk("KPM: Stub function called (sukisu_kpm_unload_module). name=%s ptr=%p\n", name, ptr); printk("KPM: Stub function called (sukisu_kpm_unload_module). name=%s ptr=%p\n",
name, ptr);
__asm__ volatile("nop"); // 精确控制循环不被优化 __asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
} }
noinline noinline NO_OPTIMIZE void sukisu_kpm_num(void __user *result)
NO_OPTIMIZE {
void sukisu_kpm_num(void __user* result) {
// This is a KPM module stub. // This is a KPM module stub.
int res = 0; int res = 0;
printk("KPM: Stub function called (sukisu_kpm_num).\n"); printk("KPM: Stub function called (sukisu_kpm_num).\n");
__asm__ volatile("nop"); // 精确控制循环不被优化 __asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
} }
noinline noinline NO_OPTIMIZE void sukisu_kpm_info(const char *name, void __user *out,
NO_OPTIMIZE void __user *result)
void sukisu_kpm_info(const char* name, void __user* out, void __user* result) { {
// This is a KPM module stub. // This is a KPM module stub.
int res = -1; int res = -1;
printk("KPM: Stub function called (sukisu_kpm_info). name=%s buffer=%p\n", name, out); printk("KPM: Stub function called (sukisu_kpm_info). name=%s buffer=%p\n",
name, out);
__asm__ volatile("nop"); // 精确控制循环不被优化 __asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
} }
noinline noinline NO_OPTIMIZE void
NO_OPTIMIZE sukisu_kpm_list(void __user *out, unsigned int bufferSize, void __user *result)
void sukisu_kpm_list(void __user* out, unsigned int bufferSize, void __user* result) { {
// This is a KPM module stub. // This is a KPM module stub.
int res = -1; int res = -1;
printk("KPM: Stub function called (sukisu_kpm_list). buffer=%p size=%d\n", out, bufferSize); printk("KPM: Stub function called (sukisu_kpm_list). buffer=%p size=%d\n",
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); out, bufferSize);
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
} }
noinline noinline NO_OPTIMIZE void
NO_OPTIMIZE sukisu_kpm_control(void __user *name, void __user *args, void __user *result)
void sukisu_kpm_control(void __user* name, void __user* args, void __user* result) { {
// This is a KPM module stub. // This is a KPM module stub.
int res = -1; int res = -1;
printk("KPM: Stub function called (sukisu_kpm_control). name=%p args=%p\n", name, args); printk("KPM: Stub function called (sukisu_kpm_control). name=%p args=%p\n",
name, args);
__asm__ volatile("nop"); // 精确控制循环不被优化 __asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
} }
noinline noinline NO_OPTIMIZE void sukisu_kpm_version(void __user *out,
NO_OPTIMIZE unsigned int bufferSize,
void sukisu_kpm_version(void __user* out, unsigned int bufferSize, void __user* result) { void __user *result)
{
int res = -1; int res = -1;
printk("KPM: Stub function called (sukisu_kpm_version). buffer=%p size=%d\n", out, bufferSize); printk("KPM: Stub function called (sukisu_kpm_version). buffer=%p size=%d\n",
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); out, bufferSize);
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
} }
EXPORT_SYMBOL(sukisu_kpm_load_module_path); EXPORT_SYMBOL(sukisu_kpm_load_module_path);
@@ -131,8 +146,8 @@ EXPORT_SYMBOL(sukisu_kpm_list);
EXPORT_SYMBOL(sukisu_kpm_version); EXPORT_SYMBOL(sukisu_kpm_version);
EXPORT_SYMBOL(sukisu_kpm_control); EXPORT_SYMBOL(sukisu_kpm_control);
noinline noinline int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3,
int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) unsigned long arg4, unsigned long arg5)
{ {
if (arg2 == SUKISU_KPM_LOAD) { if (arg2 == SUKISU_KPM_LOAD) {
char kernel_load_path[256] = { 0 }; char kernel_load_path[256] = { 0 };
@@ -142,11 +157,15 @@ int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4
return -1; return -1;
} }
strncpy_from_user((char*)&kernel_load_path, (const char __user *)arg3, 255); strncpy_from_user((char *)&kernel_load_path,
(const char __user *)arg3, 255);
if (arg4 != 0) { if (arg4 != 0) {
strncpy_from_user((char*)&kernel_args_buffer, (const char __user *)arg4, 255); strncpy_from_user((char *)&kernel_args_buffer,
(const char __user *)arg4, 255);
} }
sukisu_kpm_load_module_path((const char*)&kernel_load_path, (const char*) &kernel_args_buffer, NULL, (void __user*) arg5); sukisu_kpm_load_module_path((const char *)&kernel_load_path,
(const char *)&kernel_args_buffer,
NULL, (void __user *)arg5);
} else if (arg2 == SUKISU_KPM_UNLOAD) { } else if (arg2 == SUKISU_KPM_UNLOAD) {
char kernel_name_buffer[256] = { 0 }; char kernel_name_buffer[256] = { 0 };
@@ -154,8 +173,10 @@ int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4
return -1; return -1;
} }
strncpy_from_user((char*)&kernel_name_buffer, (const char __user *)arg3, 255); strncpy_from_user((char *)&kernel_name_buffer,
sukisu_kpm_unload_module((const char*) &kernel_name_buffer, NULL, (void __user*) arg5); (const char __user *)arg3, 255);
sukisu_kpm_unload_module((const char *)&kernel_name_buffer,
NULL, (void __user *)arg5);
} else if (arg2 == SUKISU_KPM_NUM) { } else if (arg2 == SUKISU_KPM_NUM) {
sukisu_kpm_num((void __user *)arg5); sukisu_kpm_num((void __user *)arg5);
} else if (arg2 == SUKISU_KPM_INFO) { } else if (arg2 == SUKISU_KPM_INFO) {
@@ -165,19 +186,25 @@ int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4
return -1; return -1;
} }
strncpy_from_user((char*)&kernel_name_buffer, (const char __user *)arg3, 255); strncpy_from_user((char *)&kernel_name_buffer,
sukisu_kpm_info((const char*) &kernel_name_buffer, (char __user*) arg4, (void __user*) arg5); (const char __user *)arg3, 255);
sukisu_kpm_info((const char *)&kernel_name_buffer,
(char __user *)arg4, (void __user *)arg5);
} else if (arg2 == SUKISU_KPM_LIST) { } else if (arg2 == SUKISU_KPM_LIST) {
sukisu_kpm_list((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); sukisu_kpm_list((char __user *)arg3, (unsigned int)arg4,
(void __user *)arg5);
} else if (arg2 == SUKISU_KPM_VERSION) { } else if (arg2 == SUKISU_KPM_VERSION) {
sukisu_kpm_version((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); sukisu_kpm_version((char __user *)arg3, (unsigned int)arg4,
(void __user *)arg5);
} else if (arg2 == SUKISU_KPM_CONTROL) { } else if (arg2 == SUKISU_KPM_CONTROL) {
sukisu_kpm_control((char __user*) arg3, (char __user*) arg4, (void __user*) arg5); sukisu_kpm_control((char __user *)arg3, (char __user *)arg4,
(void __user *)arg5);
} }
return 0; return 0;
} }
int sukisu_is_kpm_control_code(unsigned long arg2) { int sukisu_is_kpm_control_code(unsigned long arg2)
{
return (arg2 >= CMD_KPM_CONTROL && arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0; return (arg2 >= CMD_KPM_CONTROL && arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0;
} }

View File

@@ -1,7 +1,8 @@
#ifndef ___SUKISU_KPM_H #ifndef ___SUKISU_KPM_H
#define ___SUKISU_KPM_H #define ___SUKISU_KPM_H
int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5);
int sukisu_is_kpm_control_code(unsigned long arg2); int sukisu_is_kpm_control_code(unsigned long arg2);
// KPM控制代码 // KPM控制代码

View File

@@ -47,19 +47,18 @@ struct DynamicStructInfo {
// 定义结构体元数据的宏(直接使用 struct 名称) // 定义结构体元数据的宏(直接使用 struct 名称)
#define DYNAMIC_STRUCT_BEGIN(struct_name) \ #define DYNAMIC_STRUCT_BEGIN(struct_name) \
static struct DynamicStructMember struct_name##_members[] = { static struct DynamicStructMember struct_name##_members[] = {
#define DEFINE_MEMBER(struct_name, member) \ #define DEFINE_MEMBER(struct_name, member) \
{ \ { .name = #member, \
.name = #member, \
.size = sizeof(((struct struct_name *)0)->member), \ .size = sizeof(((struct struct_name *)0)->member), \
.offset = offsetof(struct struct_name, member) \ .offset = offsetof(struct struct_name, member) },
},
#define DYNAMIC_STRUCT_END(struct_name) \ #define DYNAMIC_STRUCT_END(struct_name) \
}; \ } \
; \
static struct DynamicStructInfo struct_name##_info = { \ static struct DynamicStructInfo struct_name##_info = { \
.name = #struct_name, \ .name = #struct_name, \
.count = sizeof(struct_name##_members) / sizeof(struct DynamicStructMember), \ .count = sizeof(struct_name##_members) / \
sizeof(struct DynamicStructMember), \
.total_size = sizeof(struct struct_name), \ .total_size = sizeof(struct struct_name), \
.members = struct_name##_members \ .members = struct_name##_members \
}; };
@@ -155,7 +154,6 @@ DYNAMIC_STRUCT_BEGIN(netlink_kernel_cfg)
#endif #endif
DYNAMIC_STRUCT_END(netlink_kernel_cfg) DYNAMIC_STRUCT_END(netlink_kernel_cfg)
#include <linux/sched.h> #include <linux/sched.h>
DYNAMIC_STRUCT_BEGIN(task_struct) DYNAMIC_STRUCT_BEGIN(task_struct)
DEFINE_MEMBER(task_struct, pid) DEFINE_MEMBER(task_struct, pid)
@@ -198,8 +196,7 @@ DYNAMIC_STRUCT_END(task_struct)
#define STRUCT_INFO(name) &(name##_info) #define STRUCT_INFO(name) &(name##_info)
static static struct DynamicStructInfo *dynamic_struct_infos[] = {
struct DynamicStructInfo* dynamic_struct_infos[] = {
STRUCT_INFO(mount), STRUCT_INFO(mount),
STRUCT_INFO(vfsmount), STRUCT_INFO(vfsmount),
STRUCT_INFO(mnt_namespace), STRUCT_INFO(mnt_namespace),
@@ -214,12 +211,12 @@ struct DynamicStructInfo* dynamic_struct_infos[] = {
// return 0 if successful // return 0 if successful
// return -1 if struct not defined // return -1 if struct not defined
int sukisu_super_find_struct( int sukisu_super_find_struct(const char *struct_name, size_t *out_size,
const char* struct_name, int *out_members)
size_t* out_size, {
int* out_members for (size_t i = 0; i < (sizeof(dynamic_struct_infos) /
) { sizeof(dynamic_struct_infos[0]));
for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { i++) {
struct DynamicStructInfo *info = dynamic_struct_infos[i]; struct DynamicStructInfo *info = dynamic_struct_infos[i];
if (strcmp(struct_name, info->name) == 0) { if (strcmp(struct_name, info->name) == 0) {
if (out_size) if (out_size)
@@ -237,21 +234,23 @@ EXPORT_SYMBOL(sukisu_super_find_struct);
// return 0 if successful // return 0 if successful
// return -1 if struct not defined // return -1 if struct not defined
// return -2 if member not defined // return -2 if member not defined
int sukisu_super_access ( int sukisu_super_access(const char *struct_name, const char *member_name,
const char* struct_name, size_t *out_offset, size_t *out_size)
const char* member_name, {
size_t* out_offset, for (size_t i = 0; i < (sizeof(dynamic_struct_infos) /
size_t* out_size sizeof(dynamic_struct_infos[0]));
) { i++) {
for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) {
struct DynamicStructInfo *info = dynamic_struct_infos[i]; struct DynamicStructInfo *info = dynamic_struct_infos[i];
if (strcmp(struct_name, info->name) == 0) { if (strcmp(struct_name, info->name) == 0) {
for (size_t i1 = 0; i1 < info->count; i1++) { for (size_t i1 = 0; i1 < info->count; i1++) {
if (strcmp(info->members[i1].name, member_name) == 0) { if (strcmp(info->members[i1].name,
member_name) == 0) {
if (out_offset) if (out_offset)
*out_offset = info->members[i].offset; *out_offset =
info->members[i].offset;
if (out_size) if (out_size)
*out_size = info->members[i].size; *out_size =
info->members[i].size;
return 0; return 0;
} }
} }
@@ -263,29 +262,33 @@ int sukisu_super_access (
EXPORT_SYMBOL(sukisu_super_access); EXPORT_SYMBOL(sukisu_super_access);
// 动态 container_of 宏 // 动态 container_of 宏
#define DYNAMIC_CONTAINER_OF(offset, member_ptr) ({ \ #define DYNAMIC_CONTAINER_OF(offset, member_ptr) \
(offset != (size_t)-1) ? (void*)((char*)(member_ptr) - offset) : NULL; \ ({ \
(offset != (size_t)-1) ? \
(void *)((char *)(member_ptr) - offset) : \
NULL; \
}) })
// Dynamic container_of // Dynamic container_of
// return 0 if success // return 0 if success
// return -1 if current struct not defined // return -1 if current struct not defined
// return -2 if target member not defined // return -2 if target member not defined
int sukisu_super_container_of( int sukisu_super_container_of(const char *struct_name, const char *member_name,
const char* struct_name, void *ptr, void **out_ptr)
const char* member_name, {
void* ptr,
void** out_ptr
) {
if (ptr == NULL) { if (ptr == NULL) {
return -3; return -3;
} }
for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { for (size_t i = 0; i < (sizeof(dynamic_struct_infos) /
sizeof(dynamic_struct_infos[0]));
i++) {
struct DynamicStructInfo *info = dynamic_struct_infos[i]; struct DynamicStructInfo *info = dynamic_struct_infos[i];
if (strcmp(struct_name, info->name) == 0) { if (strcmp(struct_name, info->name) == 0) {
for (size_t i1 = 0; i1 < info->count; i1++) { for (size_t i1 = 0; i1 < info->count; i1++) {
if (strcmp(info->members[i1].name, member_name) == 0) { if (strcmp(info->members[i1].name,
*out_ptr = (void*) DYNAMIC_CONTAINER_OF(info->members[i1].offset, ptr); member_name) == 0) {
*out_ptr = (void *)DYNAMIC_CONTAINER_OF(
info->members[i1].offset, ptr);
return 0; return 0;
} }
} }

View File

@@ -8,32 +8,21 @@
// return 0 if successful // return 0 if successful
// return -1 if struct not defined // return -1 if struct not defined
int sukisu_super_find_struct( int sukisu_super_find_struct(const char *struct_name, size_t *out_size,
const char* struct_name, int *out_members);
size_t* out_size,
int* out_members
);
// Dynamic access struct // Dynamic access struct
// return 0 if successful // return 0 if successful
// return -1 if struct not defined // return -1 if struct not defined
// return -2 if member not defined // return -2 if member not defined
int sukisu_super_access ( int sukisu_super_access(const char *struct_name, const char *member_name,
const char* struct_name, size_t *out_offset, size_t *out_size);
const char* member_name,
size_t* out_offset,
size_t* out_size
);
// Dynamic container_of // Dynamic container_of
// return 0 if success // return 0 if success
// return -1 if current struct not defined // return -1 if current struct not defined
// return -2 if target member not defined // return -2 if target member not defined
int sukisu_super_container_of( int sukisu_super_container_of(const char *struct_name, const char *member_name,
const char* struct_name, void *ptr, void **out_ptr);
const char* member_name,
void* ptr,
void** out_ptr
);
#endif #endif

View File

@@ -24,9 +24,15 @@ static int __init read_kernelsu_state(char *s)
} }
__setup("kernelsu.enabled=", read_kernelsu_state); __setup("kernelsu.enabled=", read_kernelsu_state);
bool get_ksu_state(void) { return enable_kernelsu >= 1; } bool get_ksu_state(void)
{
return enable_kernelsu >= 1;
}
#else #else
bool get_ksu_state(void) { return true; } bool get_ksu_state(void)
{
return true;
}
#endif /* CONFIG_KSU_CMDLINE */ #endif /* CONFIG_KSU_CMDLINE */
static struct workqueue_struct *ksu_workqueue; static struct workqueue_struct *ksu_workqueue;
@@ -61,8 +67,7 @@ extern void ksu_trace_unregister();
int __init kernelsu_init(void) int __init kernelsu_init(void)
{ {
pr_info("kernelsu.enabled=%d\n", pr_info("kernelsu.enabled=%d\n", (int)get_ksu_state());
(int)get_ksu_state());
#ifdef CONFIG_KSU_CMDLINE #ifdef CONFIG_KSU_CMDLINE
if (!get_ksu_state()) { if (!get_ksu_state()) {
@@ -72,13 +77,20 @@ int __init kernelsu_init(void)
#endif #endif
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
pr_alert("*************************************************************"); pr_alert(
pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **"); "*************************************************************");
pr_alert("** **"); pr_alert(
pr_alert("** You are running KernelSU in DEBUG mode **"); "** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **");
pr_alert("** **"); pr_alert(
pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **"); "** **");
pr_alert("*************************************************************"); pr_alert(
"** You are running KernelSU in DEBUG mode **");
pr_alert(
"** **");
pr_alert(
"** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **");
pr_alert(
"*************************************************************");
#endif #endif
ksu_core_init(); ksu_core_init();

View File

@@ -1,58 +1,68 @@
#include "ksu_trace.h" #include "ksu_trace.h"
// extern kernelsu functions // extern kernelsu functions
extern bool ksu_execveat_hook __read_mostly; extern bool ksu_execveat_hook __read_mostly;
extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags); extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr,
extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags); void *argv, void *envp, int *flags);
extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, int *flags); extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
void *argv, void *envp, int *flags);
extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user,
int *mode, int *flags);
extern bool ksu_vfs_read_hook __read_mostly; extern bool ksu_vfs_read_hook __read_mostly;
extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, size_t *count_ptr); extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr,
extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); size_t *count_ptr);
extern int ksu_handle_stat(int *dfd, const char __user **filename_user,
int *flags);
extern bool ksu_input_hook __read_mostly; extern bool ksu_input_hook __read_mostly;
extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code,
int *value);
extern int ksu_handle_devpts(struct inode *); extern int ksu_handle_devpts(struct inode *);
// end kernelsu functions // end kernelsu functions
// tracepoint callback functions // tracepoint callback functions
void ksu_trace_execveat_hook_callback(void *data, int *fd, struct filename **filename_ptr, void ksu_trace_execveat_hook_callback(void *data, int *fd,
struct filename **filename_ptr,
void *argv, void *envp, int *flags) void *argv, void *envp, int *flags)
{ {
if (unlikely(ksu_execveat_hook)) if (unlikely(ksu_execveat_hook))
ksu_handle_execveat(fd, filename_ptr, argv, envp, flags); ksu_handle_execveat(fd, filename_ptr, argv, envp, flags);
else else
ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL); ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL,
NULL);
} }
void ksu_trace_execveat_sucompat_hook_callback(void *data, int *fd, struct filename **filename_ptr, void ksu_trace_execveat_sucompat_hook_callback(void *data, int *fd,
void *argv, void *envp, int *flags) struct filename **filename_ptr,
void *argv, void *envp,
int *flags)
{ {
if (!ksu_execveat_hook) if (!ksu_execveat_hook)
ksu_handle_execveat_sucompat(fd, filename_ptr, argv, envp, flags); ksu_handle_execveat_sucompat(fd, filename_ptr, argv, envp,
flags);
} }
void ksu_trace_faccessat_hook_callback(void *data, int *dfd, const char __user **filename_user, void ksu_trace_faccessat_hook_callback(void *data, int *dfd,
const char __user **filename_user,
int *mode, int *flags) int *mode, int *flags)
{ {
ksu_handle_faccessat(dfd, filename_user, mode, flags); ksu_handle_faccessat(dfd, filename_user, mode, flags);
} }
void ksu_trace_sys_read_hook_callback(void *data, unsigned int fd, char __user **buf_ptr, void ksu_trace_sys_read_hook_callback(void *data, unsigned int fd,
size_t *count_ptr) char __user **buf_ptr, size_t *count_ptr)
{ {
if (unlikely(ksu_vfs_read_hook)) if (unlikely(ksu_vfs_read_hook))
ksu_handle_sys_read(fd, buf_ptr, count_ptr); ksu_handle_sys_read(fd, buf_ptr, count_ptr);
} }
void ksu_trace_stat_hook_callback(void *data, int *dfd, const char __user **filename_user, void ksu_trace_stat_hook_callback(void *data, int *dfd,
int *flags) const char __user **filename_user, int *flags)
{ {
ksu_handle_stat(dfd, filename_user, flags); ksu_handle_stat(dfd, filename_user, flags);
} }
void ksu_trace_input_hook_callback(void *data, unsigned int *type, unsigned int *code, void ksu_trace_input_hook_callback(void *data, unsigned int *type,
int *value) unsigned int *code, int *value)
{ {
if (unlikely(ksu_input_hook)) if (unlikely(ksu_input_hook))
ksu_handle_input_handle_event(type, code, value); ksu_handle_input_handle_event(type, code, value);
@@ -64,27 +74,39 @@ void ksu_trace_devpts_hook_callback(void *data, struct inode *inode)
} }
// end tracepoint callback functions // end tracepoint callback functions
// register tracepoint callback functions // register tracepoint callback functions
void ksu_trace_register(void) void ksu_trace_register(void)
{ {
register_trace_ksu_trace_execveat_hook(ksu_trace_execveat_hook_callback, NULL); register_trace_ksu_trace_execveat_hook(ksu_trace_execveat_hook_callback,
register_trace_ksu_trace_execveat_sucompat_hook(ksu_trace_execveat_sucompat_hook_callback, NULL); NULL);
register_trace_ksu_trace_faccessat_hook(ksu_trace_faccessat_hook_callback, NULL); register_trace_ksu_trace_execveat_sucompat_hook(
register_trace_ksu_trace_sys_read_hook(ksu_trace_sys_read_hook_callback, NULL); ksu_trace_execveat_sucompat_hook_callback, NULL);
register_trace_ksu_trace_faccessat_hook(
ksu_trace_faccessat_hook_callback, NULL);
register_trace_ksu_trace_sys_read_hook(ksu_trace_sys_read_hook_callback,
NULL);
register_trace_ksu_trace_stat_hook(ksu_trace_stat_hook_callback, NULL); register_trace_ksu_trace_stat_hook(ksu_trace_stat_hook_callback, NULL);
register_trace_ksu_trace_input_hook(ksu_trace_input_hook_callback, NULL); register_trace_ksu_trace_input_hook(ksu_trace_input_hook_callback,
register_trace_ksu_trace_devpts_hook(ksu_trace_devpts_hook_callback, NULL); NULL);
register_trace_ksu_trace_devpts_hook(ksu_trace_devpts_hook_callback,
NULL);
} }
// unregister tracepoint callback functions // unregister tracepoint callback functions
void ksu_trace_unregister(void) void ksu_trace_unregister(void)
{ {
unregister_trace_ksu_trace_execveat_hook(ksu_trace_execveat_hook_callback, NULL); unregister_trace_ksu_trace_execveat_hook(
unregister_trace_ksu_trace_execveat_sucompat_hook(ksu_trace_execveat_sucompat_hook_callback, NULL); ksu_trace_execveat_hook_callback, NULL);
unregister_trace_ksu_trace_faccessat_hook(ksu_trace_faccessat_hook_callback, NULL); unregister_trace_ksu_trace_execveat_sucompat_hook(
unregister_trace_ksu_trace_sys_read_hook(ksu_trace_sys_read_hook_callback, NULL); ksu_trace_execveat_sucompat_hook_callback, NULL);
unregister_trace_ksu_trace_stat_hook(ksu_trace_stat_hook_callback, NULL); unregister_trace_ksu_trace_faccessat_hook(
unregister_trace_ksu_trace_input_hook(ksu_trace_input_hook_callback, NULL); ksu_trace_faccessat_hook_callback, NULL);
unregister_trace_ksu_trace_devpts_hook(ksu_trace_devpts_hook_callback, NULL); unregister_trace_ksu_trace_sys_read_hook(
ksu_trace_sys_read_hook_callback, NULL);
unregister_trace_ksu_trace_stat_hook(ksu_trace_stat_hook_callback,
NULL);
unregister_trace_ksu_trace_input_hook(ksu_trace_input_hook_callback,
NULL);
unregister_trace_ksu_trace_devpts_hook(ksu_trace_devpts_hook_callback,
NULL);
} }

View File

@@ -8,19 +8,23 @@
#include <linux/tracepoint.h> #include <linux/tracepoint.h>
DECLARE_TRACE(ksu_trace_execveat_hook, DECLARE_TRACE(ksu_trace_execveat_hook,
TP_PROTO(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags), TP_PROTO(int *fd, struct filename **filename_ptr, void *argv,
void *envp, int *flags),
TP_ARGS(fd, filename_ptr, argv, envp, flags)); TP_ARGS(fd, filename_ptr, argv, envp, flags));
DECLARE_TRACE(ksu_trace_execveat_sucompat_hook, DECLARE_TRACE(ksu_trace_execveat_sucompat_hook,
TP_PROTO(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags), TP_PROTO(int *fd, struct filename **filename_ptr, void *argv,
void *envp, int *flags),
TP_ARGS(fd, filename_ptr, argv, envp, flags)); TP_ARGS(fd, filename_ptr, argv, envp, flags));
DECLARE_TRACE(ksu_trace_faccessat_hook, DECLARE_TRACE(ksu_trace_faccessat_hook,
TP_PROTO(int *dfd, const char __user **filename_user, int *mode, int *flags), TP_PROTO(int *dfd, const char __user **filename_user, int *mode,
int *flags),
TP_ARGS(dfd, filename_user, mode, flags)); TP_ARGS(dfd, filename_user, mode, flags));
DECLARE_TRACE(ksu_trace_sys_read_hook, DECLARE_TRACE(ksu_trace_sys_read_hook,
TP_PROTO(unsigned int fd, char __user **buf_ptr, size_t *count_ptr), TP_PROTO(unsigned int fd, char __user **buf_ptr,
size_t *count_ptr),
TP_ARGS(fd, buf_ptr, count_ptr)); TP_ARGS(fd, buf_ptr, count_ptr));
DECLARE_TRACE(ksu_trace_stat_hook, DECLARE_TRACE(ksu_trace_stat_hook,
@@ -31,8 +35,7 @@ DECLARE_TRACE(ksu_trace_input_hook,
TP_PROTO(unsigned int *type, unsigned int *code, int *value), TP_PROTO(unsigned int *type, unsigned int *code, int *value),
TP_ARGS(type, code, value)); TP_ARGS(type, code, value));
DECLARE_TRACE(ksu_trace_devpts_hook, DECLARE_TRACE(ksu_trace_devpts_hook, TP_PROTO(struct inode *inode),
TP_PROTO(struct inode *inode),
TP_ARGS(inode)); TP_ARGS(inode));
#endif /* _KSU_TRACE_H */ #endif /* _KSU_TRACE_H */

View File

@@ -200,8 +200,8 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1); const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) { if (p && !IS_ERR(p)) {
char first_arg[16]; char first_arg[16];
ksu_strncpy_from_user_retry( ksu_strncpy_from_user_retry(first_arg, p,
first_arg, p, sizeof(first_arg)); sizeof(first_arg));
pr_info("/system/bin/init first arg: %s\n", pr_info("/system/bin/init first arg: %s\n",
first_arg); first_arg);
if (!strcmp(first_arg, "second_stage")) { if (!strcmp(first_arg, "second_stage")) {
@@ -225,8 +225,8 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1); const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) { if (p && !IS_ERR(p)) {
char first_arg[16]; char first_arg[16];
ksu_strncpy_from_user_retry( ksu_strncpy_from_user_retry(first_arg, p,
first_arg, p, sizeof(first_arg)); sizeof(first_arg));
pr_info("/init first arg: %s\n", first_arg); pr_info("/init first arg: %s\n", first_arg);
if (!strcmp(first_arg, "--second-stage")) { if (!strcmp(first_arg, "--second-stage")) {
pr_info("/init second_stage executed\n"); pr_info("/init second_stage executed\n");
@@ -597,10 +597,12 @@ static int ksu_execve_ksud_common(const char __user *filename_user,
filename_in.name = path; filename_in.name = path;
filename_p = &filename_in; filename_p = &filename_in;
return ksu_handle_execveat_ksud(AT_FDCWD, &filename_p, argv, NULL, NULL); return ksu_handle_execveat_ksud(AT_FDCWD, &filename_p, argv, NULL,
NULL);
} }
int __maybe_unused ksu_handle_execve_ksud(const char __user *filename_user, int __maybe_unused
ksu_handle_execve_ksud(const char __user *filename_user,
const char __user *const __user *__argv) const char __user *const __user *__argv)
{ {
struct user_arg_ptr argv = { .ptr.native = __argv }; struct user_arg_ptr argv = { .ptr.native = __argv };
@@ -608,8 +610,8 @@ int __maybe_unused ksu_handle_execve_ksud(const char __user *filename_user,
} }
#if defined(CONFIG_COMPAT) && defined(CONFIG_64BIT) #if defined(CONFIG_COMPAT) && defined(CONFIG_64BIT)
int __maybe_unused ksu_handle_compat_execve_ksud(const char __user *filename_user, int __maybe_unused ksu_handle_compat_execve_ksud(
const compat_uptr_t __user *__argv) const char __user *filename_user, const compat_uptr_t __user *__argv)
{ {
struct user_arg_ptr argv = { .ptr.compat = __argv }; struct user_arg_ptr argv = { .ptr.compat = __argv };
return ksu_execve_ksud_common(filename_user, &argv); return ksu_execve_ksud_common(filename_user, &argv);
@@ -651,7 +653,9 @@ static void stop_input_hook()
bool ret = schedule_work(&stop_input_hook_work); bool ret = schedule_work(&stop_input_hook_work);
pr_info("unregister input kprobe: %d!\n", ret); pr_info("unregister input kprobe: %d!\n", ret);
#else #else
if (!ksu_input_hook) { return; } if (!ksu_input_hook) {
return;
}
ksu_input_hook = false; ksu_input_hook = false;
pr_info("stop input_hook\n"); pr_info("stop input_hook\n");
#endif #endif

View File

@@ -21,7 +21,8 @@ static inline bool ksu_is_manager_uid_valid()
static inline bool is_manager() static inline bool is_manager()
{ {
return unlikely(ksu_is_any_manager(ksu_current_uid()) || ksu_manager_uid == ksu_current_uid()); return unlikely(ksu_is_any_manager(ksu_current_uid()) ||
ksu_manager_uid == ksu_current_uid());
} }
static inline uid_t ksu_get_manager_uid() static inline uid_t ksu_get_manager_uid()

View File

@@ -3,10 +3,12 @@
// ShirkNeko/KernelSU // ShirkNeko/KernelSU
#define EXPECTED_SIZE_SHIRKNEKO 0x35c #define EXPECTED_SIZE_SHIRKNEKO 0x35c
#define EXPECTED_HASH_SHIRKNEKO "947ae944f3de4ed4c21a7e4f7953ecf351bfa2b36239da37a34111ad29993eef" #define EXPECTED_HASH_SHIRKNEKO \
"947ae944f3de4ed4c21a7e4f7953ecf351bfa2b36239da37a34111ad29993eef"
// Dynamic Sign // Dynamic Sign
#define EXPECTED_SIZE_OTHER 0x300 #define EXPECTED_SIZE_OTHER 0x300
#define EXPECTED_HASH_OTHER "0000000000000000000000000000000000000000000000000000000000000000" #define EXPECTED_HASH_OTHER \
"0000000000000000000000000000000000000000000000000000000000000000"
#endif /* MANAGER_SIGN_H */ #endif /* MANAGER_SIGN_H */

View File

@@ -239,11 +239,13 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
} }
u32 cmd, subcmd; u32 cmd, subcmd;
char __user *sepol1, *sepol2, *sepol3, *sepol4, *sepol5, *sepol6, *sepol7; char __user *sepol1, *sepol2, *sepol3, *sepol4, *sepol5, *sepol6,
*sepol7;
if (unlikely(ksu_is_compat)) { if (unlikely(ksu_is_compat)) {
struct sepol_data_compat data_compat; struct sepol_data_compat data_compat;
if (copy_from_user(&data_compat, arg4, sizeof(struct sepol_data_compat))) { if (copy_from_user(&data_compat, arg4,
sizeof(struct sepol_data_compat))) {
pr_err("sepol: copy sepol_data failed.\n"); pr_err("sepol: copy sepol_data failed.\n");
return -1; return -1;
} }
@@ -301,8 +303,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
goto exit; goto exit;
} }
if (get_object(perm_buf, sepol4, sizeof(perm_buf), &p) < if (get_object(perm_buf, sepol4, sizeof(perm_buf), &p) < 0) {
0) {
pr_err("sepol: copy perm failed.\n"); pr_err("sepol: copy perm failed.\n");
goto exit; goto exit;
} }
@@ -343,13 +344,12 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
pr_err("sepol: copy cls failed.\n"); pr_err("sepol: copy cls failed.\n");
goto exit; goto exit;
} }
if (strncpy_from_user(operation, sepol4, if (strncpy_from_user(operation, sepol4, sizeof(operation)) <
sizeof(operation)) < 0) { 0) {
pr_err("sepol: copy operation failed.\n"); pr_err("sepol: copy operation failed.\n");
goto exit; goto exit;
} }
if (strncpy_from_user(perm_set, sepol5, sizeof(perm_set)) < if (strncpy_from_user(perm_set, sepol5, sizeof(perm_set)) < 0) {
0) {
pr_err("sepol: copy perm_set failed.\n"); pr_err("sepol: copy perm_set failed.\n");
goto exit; goto exit;
} }
@@ -450,8 +450,8 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
if (sepol5 == NULL) { if (sepol5 == NULL) {
real_object = NULL; real_object = NULL;
} else { } else {
if (strncpy_from_user(object, sepol5, if (strncpy_from_user(object, sepol5, sizeof(object)) <
sizeof(object)) < 0) { 0) {
pr_err("sepol: copy object failed.\n"); pr_err("sepol: copy object failed.\n");
goto exit; goto exit;
} }
@@ -510,8 +510,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
pr_err("sepol: copy path failed.\n"); pr_err("sepol: copy path failed.\n");
goto exit; goto exit;
} }
if (strncpy_from_user(context, sepol3, sizeof(context)) < if (strncpy_from_user(context, sepol3, sizeof(context)) < 0) {
0) {
pr_err("sepol: copy context failed.\n"); pr_err("sepol: copy context failed.\n");
goto exit; goto exit;
} }

View File

@@ -36,7 +36,8 @@ static int transive_to_domain(const char *domain)
} }
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0) #if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)
bool __maybe_unused is_ksu_transition(const struct task_security_struct *old_tsec, bool __maybe_unused
is_ksu_transition(const struct task_security_struct *old_tsec,
const struct task_security_struct *new_tsec) const struct task_security_struct *new_tsec)
{ {
static u32 ksu_sid; static u32 ksu_sid;
@@ -45,7 +46,8 @@ bool __maybe_unused is_ksu_transition(const struct task_security_struct *old_tse
bool allowed = false; bool allowed = false;
if (!ksu_sid) if (!ksu_sid)
security_secctx_to_secid(KERNEL_SU_DOMAIN, strlen(KERNEL_SU_DOMAIN), &ksu_sid); security_secctx_to_secid(KERNEL_SU_DOMAIN,
strlen(KERNEL_SU_DOMAIN), &ksu_sid);
if (security_secid_to_secctx(old_tsec->sid, &secdata, &seclen)) if (security_secid_to_secctx(old_tsec->sid, &secdata, &seclen))
return false; return false;

View File

@@ -4,7 +4,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/version.h> #include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || defined(KSU_COMPAT_HAS_SELINUX_STATE) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || \
defined(KSU_COMPAT_HAS_SELINUX_STATE)
#define KSU_COMPAT_USE_SELINUX_STATE #define KSU_COMPAT_USE_SELINUX_STATE
#endif #endif

View File

@@ -657,9 +657,8 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
struct ebitmap *new_type_attr_map_array = struct ebitmap *new_type_attr_map_array = ksu_realloc(
ksu_realloc(db->type_attr_map_array, db->type_attr_map_array, value * sizeof(struct ebitmap),
value * sizeof(struct ebitmap),
(value - 1) * sizeof(struct ebitmap)); (value - 1) * sizeof(struct ebitmap));
if (!new_type_attr_map_array) { if (!new_type_attr_map_array) {
@@ -667,9 +666,8 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
return false; return false;
} }
struct type_datum **new_type_val_to_struct = struct type_datum **new_type_val_to_struct = ksu_realloc(
ksu_realloc(db->type_val_to_struct, db->type_val_to_struct, sizeof(*db->type_val_to_struct) * value,
sizeof(*db->type_val_to_struct) * value,
sizeof(*db->type_val_to_struct) * (value - 1)); sizeof(*db->type_val_to_struct) * (value - 1));
if (!new_type_val_to_struct) { if (!new_type_val_to_struct) {
@@ -677,9 +675,8 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
return false; return false;
} }
char **new_val_to_name_types = char **new_val_to_name_types = ksu_realloc(
ksu_realloc(db->sym_val_to_name[SYM_TYPES], db->sym_val_to_name[SYM_TYPES], sizeof(char *) * value,
sizeof(char *) * value,
sizeof(char *) * (value - 1)); sizeof(char *) * (value - 1));
if (!new_val_to_name_types) { if (!new_val_to_name_types) {
pr_err("add_type: alloc val_to_name failed\n"); pr_err("add_type: alloc val_to_name failed\n");
@@ -727,10 +724,9 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
return false; return false;
} }
char **new_val_to_name_types = char **new_val_to_name_types = krealloc(
krealloc(db->sym_val_to_name[SYM_TYPES], db->sym_val_to_name[SYM_TYPES],
sizeof(char *) * db->symtab[SYM_TYPES].nprim, sizeof(char *) * db->symtab[SYM_TYPES].nprim, GFP_KERNEL);
GFP_KERNEL);
if (!new_val_to_name_types) { if (!new_val_to_name_types) {
pr_err("add_type: alloc val_to_name failed\n"); pr_err("add_type: alloc val_to_name failed\n");
return false; return false;

View File

@@ -63,7 +63,8 @@ static int get_pkg_from_apk_path(char *pkg, const char *path)
return 0; return 0;
} }
static void crown_manager(const char *apk, struct list_head *uid_data, int signature_index) static void crown_manager(const char *apk, struct list_head *uid_data,
int signature_index)
{ {
char pkg[KSU_MAX_PACKAGE_NAME]; char pkg[KSU_MAX_PACKAGE_NAME];
if (get_pkg_from_apk_path(pkg, apk) < 0) { if (get_pkg_from_apk_path(pkg, apk) < 0) {
@@ -86,7 +87,8 @@ static void crown_manager(const char *apk, struct list_head *uid_data, int signa
list_for_each_entry(np, list, list) { list_for_each_entry(np, list, list) {
if (strncmp(np->package, pkg, KSU_MAX_PACKAGE_NAME) == 0) { if (strncmp(np->package, pkg, KSU_MAX_PACKAGE_NAME) == 0) {
pr_info("Crowning manager: %s(uid=%d, signature_index=%d)\n", pkg, np->uid, signature_index); pr_info("Crowning manager: %s(uid=%d, signature_index=%d)\n",
pkg, np->uid, signature_index);
if (signature_index == 1 || signature_index == 2) { if (signature_index == 1 || signature_index == 2) {
ksu_add_manager(np->uid, signature_index); ksu_add_manager(np->uid, signature_index);
@@ -173,7 +175,8 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
if (d_type == DT_DIR && my_ctx->depth > 0 && if (d_type == DT_DIR && my_ctx->depth > 0 &&
(my_ctx->stop && !*my_ctx->stop)) { (my_ctx->stop && !*my_ctx->stop)) {
struct data_path *data = kmalloc(sizeof(struct data_path), GFP_ATOMIC); struct data_path *data =
kmalloc(sizeof(struct data_path), GFP_ATOMIC);
if (!data) { if (!data) {
pr_err("Failed to allocate memory for %s\n", dirpath); pr_err("Failed to allocate memory for %s\n", dirpath);
@@ -184,12 +187,15 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
data->depth = my_ctx->depth - 1; data->depth = my_ctx->depth - 1;
list_add_tail(&data->list, my_ctx->data_path_list); list_add_tail(&data->list, my_ctx->data_path_list);
} else { } else {
if ((namelen == 8) && (strncmp(name, "base.apk", namelen) == 0)) { if ((namelen == 8) &&
(strncmp(name, "base.apk", namelen) == 0)) {
struct apk_path_hash *pos, *n; struct apk_path_hash *pos, *n;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
unsigned int hash = full_name_hash(dirpath, strlen(dirpath)); unsigned int hash =
full_name_hash(dirpath, strlen(dirpath));
#else #else
unsigned int hash = full_name_hash(NULL, dirpath, strlen(dirpath)); unsigned int hash =
full_name_hash(NULL, dirpath, strlen(dirpath));
#endif #endif
list_for_each_entry(pos, &apk_path_hash_list, list) { list_for_each_entry(pos, &apk_path_hash_list, list) {
if (hash == pos->hash) { if (hash == pos->hash) {
@@ -199,19 +205,25 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
} }
int signature_index = -1; int signature_index = -1;
bool is_multi_manager = ksu_is_multi_manager_apk(dirpath, &signature_index); bool is_multi_manager = ksu_is_multi_manager_apk(
dirpath, &signature_index);
pr_info("Found new base.apk at path: %s, is_multi_manager: %d, signature_index: %d\n", pr_info("Found new base.apk at path: %s, is_multi_manager: %d, signature_index: %d\n",
dirpath, is_multi_manager, signature_index); dirpath, is_multi_manager, signature_index);
if (is_multi_manager && (signature_index == 1 || signature_index == 2)) { if (is_multi_manager &&
crown_manager(dirpath, my_ctx->private_data, signature_index); (signature_index == 1 || signature_index == 2)) {
crown_manager(dirpath, my_ctx->private_data,
signature_index);
struct apk_path_hash *apk_data = kmalloc(sizeof(struct apk_path_hash), GFP_ATOMIC); struct apk_path_hash *apk_data =
kmalloc(sizeof(struct apk_path_hash),
GFP_ATOMIC);
if (apk_data) { if (apk_data) {
apk_data->hash = hash; apk_data->hash = hash;
apk_data->exists = true; apk_data->exists = true;
list_add_tail(&apk_data->list, &apk_path_hash_list); list_add_tail(&apk_data->list,
&apk_path_hash_list);
} }
} else if (is_manager_apk(dirpath)) { } else if (is_manager_apk(dirpath)) {
@@ -219,16 +231,20 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
*my_ctx->stop = 1; *my_ctx->stop = 1;
// Manager found, clear APK cache list // Manager found, clear APK cache list
list_for_each_entry_safe(pos, n, &apk_path_hash_list, list) { list_for_each_entry_safe(
pos, n, &apk_path_hash_list, list) {
list_del(&pos->list); list_del(&pos->list);
kfree(pos); kfree(pos);
} }
} else { } else {
struct apk_path_hash *apk_data = kmalloc(sizeof(struct apk_path_hash), GFP_ATOMIC); struct apk_path_hash *apk_data =
kmalloc(sizeof(struct apk_path_hash),
GFP_ATOMIC);
if (apk_data) { if (apk_data) {
apk_data->hash = hash; apk_data->hash = hash;
apk_data->exists = true; apk_data->exists = true;
list_add_tail(&apk_data->list, &apk_path_hash_list); list_add_tail(&apk_data->list,
&apk_path_hash_list);
} }
} }
} }
@@ -261,35 +277,46 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
struct data_path *pos, *n; struct data_path *pos, *n;
list_for_each_entry_safe(pos, n, &data_path_list, list) { list_for_each_entry_safe(pos, n, &data_path_list, list) {
struct my_dir_context ctx = { .ctx.actor = my_actor, struct my_dir_context ctx = {
.ctx.actor = my_actor,
.data_path_list = &data_path_list, .data_path_list = &data_path_list,
.parent_dir = pos->dirpath, .parent_dir = pos->dirpath,
.private_data = uid_data, .private_data = uid_data,
.depth = pos->depth, .depth = pos->depth,
.stop = &stop }; .stop = &stop
};
struct file *file; struct file *file;
if (!stop) { if (!stop) {
file = ksu_filp_open_compat(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0); file = ksu_filp_open_compat(
pos->dirpath, O_RDONLY | O_NOFOLLOW, 0);
if (IS_ERR(file)) { if (IS_ERR(file)) {
pr_err("Failed to open directory: %s, err: %ld\n", pos->dirpath, PTR_ERR(file)); pr_err("Failed to open directory: %s, err: %ld\n",
pos->dirpath, PTR_ERR(file));
goto skip_iterate; goto skip_iterate;
} }
// grab magic on first folder, which is /data/app // grab magic on first folder, which is /data/app
if (!data_app_magic) { if (!data_app_magic) {
if (file->f_inode->i_sb->s_magic) { if (file->f_inode->i_sb->s_magic) {
data_app_magic = file->f_inode->i_sb->s_magic; data_app_magic =
pr_info("%s: dir: %s got magic! 0x%lx\n", __func__, pos->dirpath, data_app_magic); file->f_inode->i_sb
->s_magic;
pr_info("%s: dir: %s got magic! 0x%lx\n",
__func__, pos->dirpath,
data_app_magic);
} else { } else {
filp_close(file, NULL); filp_close(file, NULL);
goto skip_iterate; goto skip_iterate;
} }
} }
if (file->f_inode->i_sb->s_magic != data_app_magic) { if (file->f_inode->i_sb->s_magic !=
pr_info("%s: skip: %s magic: 0x%lx expected: 0x%lx\n", __func__, pos->dirpath, data_app_magic) {
file->f_inode->i_sb->s_magic, data_app_magic); pr_info("%s: skip: %s magic: 0x%lx expected: 0x%lx\n",
__func__, pos->dirpath,
file->f_inode->i_sb->s_magic,
data_app_magic);
filp_close(file, NULL); filp_close(file, NULL);
goto skip_iterate; goto skip_iterate;
} }