diff --git a/kernel/.clang-format b/kernel/.clang-format index 10dc5a9a..48405c54 100644 --- a/kernel/.clang-format +++ b/kernel/.clang-format @@ -1,10 +1,10 @@ # 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: # -# Documentation/process/clang-format.rst +# Documentation/dev-tools/clang-format.rst # https://clang.llvm.org/docs/ClangFormat.html # https://clang.llvm.org/docs/ClangFormatStyleOptions.html # @@ -13,7 +13,7 @@ AccessModifierOffset: -4 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false -#AlignEscapedNewlines: Left # Unknown to clang-format-4.0 +AlignEscapedNewlines: Left AlignOperands: true AlignTrailingComments: false AllowAllParametersOfDeclarationOnNextLine: false @@ -37,24 +37,24 @@ BraceWrapping: AfterObjCDeclaration: false AfterStruct: false AfterUnion: false - #AfterExternBlock: false # Unknown to clang-format-5.0 + AfterExternBlock: false BeforeCatch: false BeforeElse: false IndentBraces: false - #SplitEmptyFunction: true # Unknown to clang-format-4.0 - #SplitEmptyRecord: true # Unknown to clang-format-4.0 - #SplitEmptyNamespace: true # Unknown to clang-format-4.0 + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom -#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0 +BreakBeforeInheritanceComma: false BreakBeforeTernaryOperators: false BreakConstructorInitializersBeforeComma: false -#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0 +BreakConstructorInitializers: BeforeComma BreakAfterJavaFieldAnnotations: false BreakStringLiterals: false ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' -#CompactNamespaces: false # Unknown to clang-format-4.0 +CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerIndentWidth: 8 ContinuationIndentWidth: 8 @@ -62,39 +62,61 @@ Cpp11BracedListStyle: false DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false -#FixNamespaceComments: false # Unknown to clang-format-4.0 +FixNamespaceComments: false # 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'," \ -# | sort | uniq +# | LC_ALL=C sort -u 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' - 'ata_for_each_dev' - 'ata_for_each_link' - - '__ata_qc_for_each' - 'ata_qc_for_each' - 'ata_qc_for_each_raw' - 'ata_qc_for_each_with_internal' - 'ax25_for_each' - 'ax25_uid_for_each' - - '__bio_for_each_bvec' - 'bio_for_each_bvec' - 'bio_for_each_bvec_all' + - 'bio_for_each_folio_all' - 'bio_for_each_integrity_vec' - - '__bio_for_each_segment' - 'bio_for_each_segment' - 'bio_for_each_segment_all' - 'bio_list_for_each' - '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_rcu' + - 'bpf_for_each' + - 'bpf_for_each_reg_in_vstate' + - 'bpf_for_each_reg_in_vstate_mask' - 'bpf_for_each_spilled_reg' + - 'bpf_object__for_each_map' + - 'bpf_object__for_each_program' - 'btree_for_each_safe128' - 'btree_for_each_safe32' - 'btree_for_each_safe64' @@ -102,6 +124,8 @@ ForEachMacros: - 'card_for_each_dev' - 'cgroup_taskset_for_each' - '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_idx' - 'cpufreq_for_each_valid_entry' @@ -109,8 +133,30 @@ ForEachMacros: - 'css_for_each_child' - 'css_for_each_descendant_post' - '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_scoped' + - 'dma_fence_array_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' - 'drm_atomic_crtc_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_modeset' - '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_connector_iter' - 'drm_for_each_crtc' + - 'drm_for_each_crtc_reverse' - 'drm_for_each_encoder' - 'drm_for_each_encoder_mask' - 'drm_for_each_fb' @@ -129,19 +178,64 @@ ForEachMacros: - 'drm_for_each_plane' - 'drm_for_each_plane_mask' - '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_node' - 'drm_mm_for_each_node_in_range' - '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' + - 'for_each_acpi_consumer_dev' + - 'for_each_acpi_dev_match' - 'for_each_active_dev_scope' - 'for_each_active_drhd_unit' - 'for_each_active_iommu' + - 'for_each_active_irq' + - 'for_each_active_route' - '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_scoped' + - 'for_each_bench' - 'for_each_bio' - 'for_each_board_func_rsrc' + - 'for_each_btf_ext_rec' + - 'for_each_btf_ext_sec' - 'for_each_bvec' + - 'for_each_capable_rdt_resource' - 'for_each_card_auxs' - 'for_each_card_auxs_safe' - 'for_each_card_components' @@ -154,22 +248,32 @@ ForEachMacros: - 'for_each_card_widgets_safe' - 'for_each_cgroup_storage_type' - '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_from' + - 'for_each_clear_bitrange' + - 'for_each_clear_bitrange_from' + - 'for_each_cmd' - 'for_each_cmsghdr' + - 'for_each_collection' + - 'for_each_comp_order' - 'for_each_compatible_node' - 'for_each_component_dais' - 'for_each_component_dais_safe' - - 'for_each_comp_order' + - 'for_each_conduit' - 'for_each_console' + - 'for_each_console_srcu' - 'for_each_cpu' - '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_dapm_widgets' + - 'for_each_dedup_cand' - 'for_each_dev_addr' - 'for_each_dev_scope' - - 'for_each_displayid_db' - 'for_each_dma_cap_mask' - 'for_each_dpcm_be' - 'for_each_dpcm_be_rollback' @@ -182,107 +286,160 @@ ForEachMacros: - 'for_each_element' - 'for_each_element_extid' - 'for_each_element_id' + - 'for_each_enabled_cpu' - 'for_each_endpoint_of_node' + - 'for_each_event' + - 'for_each_event_tps' - 'for_each_evictable_lru' - 'for_each_fib6_node_rt_rcu' - '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_range' - 'for_each_free_mem_range_reverse' - '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_hwgpio' + - 'for_each_hwgpio_in_range' - '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_ip_tunnel_rcu' + - 'for_each_irq_desc' - 'for_each_irq_nr' + - 'for_each_lang' + - 'for_each_link_ch_maps' - 'for_each_link_codecs' - 'for_each_link_cpus' - 'for_each_link_platforms' - 'for_each_lru' - 'for_each_matching_node' - 'for_each_matching_node_and_match' - - 'for_each_member' - - 'for_each_mem_region' - - 'for_each_memblock_type' - - 'for_each_memcg_cache_index' + - 'for_each_media_entity_data_link' - 'for_each_mem_pfn_range' - - '__for_each_mem_range' - 'for_each_mem_range' - - '__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_msi_entry' - - 'for_each_msi_entry_safe' + - 'for_each_missing_reg' + - '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_continue_reverse' + - 'for_each_net_rcu' - 'for_each_netdev' - 'for_each_netdev_continue' - 'for_each_netdev_continue_rcu' - 'for_each_netdev_continue_reverse' + - 'for_each_netdev_dump' - 'for_each_netdev_feature' - 'for_each_netdev_in_bond_rcu' - 'for_each_netdev_rcu' - 'for_each_netdev_reverse' - 'for_each_netdev_safe' - - 'for_each_net_rcu' - 'for_each_new_connector_in_state' - 'for_each_new_crtc_in_state' - 'for_each_new_mst_mgr_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_reg' + - 'for_each_nhlt_endpoint' + - 'for_each_nhlt_endpoint_fmtcfg' + - 'for_each_nhlt_fmtcfg' - 'for_each_node' - 'for_each_node_by_name' - 'for_each_node_by_type' - 'for_each_node_mask' + - 'for_each_node_numadist' - 'for_each_node_state' - 'for_each_node_with_cpus' - 'for_each_node_with_property' - 'for_each_nonreserved_multicast_dest_pgid' + - 'for_each_numa_hop_mask' - 'for_each_of_allnodes' - 'for_each_of_allnodes_from' - 'for_each_of_cpu_node' + - 'for_each_of_graph_port' + - 'for_each_of_graph_port_endpoint' - 'for_each_of_pci_range' - 'for_each_old_connector_in_state' - 'for_each_old_crtc_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_crtc_in_state' - 'for_each_oldnew_mst_mgr_in_state' - 'for_each_oldnew_plane_in_state' - 'for_each_oldnew_plane_in_state_reverse' - '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_wrap' - 'for_each_online_node' - 'for_each_online_pgdat' + - 'for_each_or_bit' + - 'for_each_page_ext' + - 'for_each_path' - 'for_each_pci_bridge' - 'for_each_pci_dev' - - 'for_each_pci_msi_entry' - 'for_each_pcm_streams' - 'for_each_physmem_range' - 'for_each_populated_zone' - 'for_each_possible_cpu' + - 'for_each_possible_cpu_wrap' + - 'for_each_present_blessed_reg' - 'for_each_present_cpu' + - 'for_each_present_section_nr' - 'for_each_prime_number' - 'for_each_prime_number_from' + - 'for_each_probe_cache_entry' - 'for_each_process' - '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_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_in_range' + - 'for_each_reserved_child_of_node' - 'for_each_reserved_mem_range' - 'for_each_reserved_mem_region' + - 'for_each_rtd_ch_maps' - 'for_each_rtd_codec_dais' - - 'for_each_rtd_codec_dais_rollback' - 'for_each_rtd_components' - 'for_each_rtd_cpu_dais' - - 'for_each_rtd_cpu_dais_rollback' - '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_from' + - 'for_each_set_bit_wrap' + - 'for_each_set_bitrange' + - 'for_each_set_bitrange_from' - 'for_each_set_clump8' - 'for_each_sg' - 'for_each_sg_dma_page' @@ -292,22 +449,37 @@ ForEachMacros: - 'for_each_sgtable_page' - 'for_each_sgtable_sg' - 'for_each_sibling_event' + - 'for_each_sta_active_link' - 'for_each_subelement' - 'for_each_subelement_extid' - '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_token' - '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_zone' - 'for_each_zone_zonelist' - 'for_each_zone_zonelist_nodemask' + - 'func_for_each_insn' - 'fwnode_for_each_available_child_node' - 'fwnode_for_each_child_node' + - 'fwnode_for_each_parent_node' - 'fwnode_graph_for_each_endpoint' - 'gadget_for_each_ep' - 'genradix_for_each' - 'genradix_for_each_from' + - 'genradix_for_each_reverse' - 'hash_for_each' - 'hash_for_each_possible' - 'hash_for_each_possible_rcu' @@ -315,7 +487,13 @@ ForEachMacros: - 'hash_for_each_possible_safe' - 'hash_for_each_rcu' - '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' + - 'hists__for_each_format' + - 'hists__for_each_sort_list' - 'hlist_bl_for_each_entry' - 'hlist_bl_for_each_entry_rcu' - 'hlist_bl_for_each_entry_safe' @@ -330,7 +508,7 @@ ForEachMacros: - 'hlist_for_each_entry_rcu_bh' - 'hlist_for_each_entry_rcu_notrace' - 'hlist_for_each_entry_safe' - - '__hlist_for_each_rcu' + - 'hlist_for_each_entry_srcu' - 'hlist_for_each_safe' - 'hlist_nulls_for_each_entry' - 'hlist_nulls_for_each_entry_from' @@ -338,17 +516,19 @@ ForEachMacros: - 'hlist_nulls_for_each_entry_safe' - 'i3c_bus_for_each_i2cdev' - '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_continue' - 'idr_for_each_entry_continue_ul' - 'idr_for_each_entry_ul' + - 'iio_for_each_active_channel' - 'in_dev_for_each_ifa_rcu' - 'in_dev_for_each_ifa_rtnl' + - 'in_dev_for_each_ifa_rtnl_net' - '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_safe' - 'klp_for_each_func' @@ -359,7 +539,9 @@ ForEachMacros: - 'klp_for_each_object_static' - 'kunit_suite_for_each_test_case' - 'kvm_for_each_memslot' + - 'kvm_for_each_memslot_in_gfn_range' - 'kvm_for_each_vcpu' + - 'libbpf_nla_for_each_attr' - 'list_for_each' - 'list_for_each_codec' - 'list_for_each_codec_safe' @@ -378,29 +560,53 @@ ForEachMacros: - 'list_for_each_entry_safe_continue' - 'list_for_each_entry_safe_from' - 'list_for_each_entry_safe_reverse' + - 'list_for_each_entry_srcu' + - 'list_for_each_from' - 'list_for_each_prev' - 'list_for_each_prev_safe' + - 'list_for_each_rcu' - 'list_for_each_safe' - 'llist_for_each' - 'llist_for_each_entry' - 'llist_for_each_entry_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' - 'media_device_for_each_entity' - 'media_device_for_each_intf' - 'media_device_for_each_link' - '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' + - '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_private' - 'netdev_for_each_lower_private_rcu' - '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_upper_dev_rcu' - 'netdev_hw_addr_list_for_each' - 'nft_rule_for_each_expr' - 'nla_for_each_attr' + - 'nla_for_each_attr_type' - 'nla_for_each_nested' + - 'nla_for_each_nested_type' - 'nlmsg_for_each_attr' - 'nlmsg_for_each_msg' - 'nr_neigh_for_each' @@ -411,8 +617,26 @@ ForEachMacros: - 'of_property_for_each_string' - 'of_property_for_each_u32' - 'pci_bus_for_each_resource' + - 'pci_dev_for_each_resource' + - 'pcl_for_each_chunk' + - 'pcl_for_each_segment' - '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_continue' - 'plist_for_each_entry' @@ -426,6 +650,7 @@ ForEachMacros: - 'queue_for_each_hw_ctx' - 'radix_tree_for_each_slot' - 'radix_tree_for_each_tagged' + - 'rb_for_each' - 'rbtree_postorder_for_each_entry_safe' - 'rdma_for_each_block' - 'rdma_for_each_port' @@ -443,18 +668,24 @@ ForEachMacros: - 'rht_for_each_from' - 'rht_for_each_rcu' - 'rht_for_each_rcu_from' - - '__rq_for_each_bio' - 'rq_for_each_bvec' - '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_sg' - 'sctp_for_each_hentry' - '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' - - '__shost_for_each_device' - 'shost_for_each_device' - 'sk_for_each' - 'sk_for_each_bound' + - 'sk_for_each_bound_safe' - 'sk_for_each_entry_offset_rcu' - 'sk_for_each_from' - 'sk_for_each_rcu' @@ -468,8 +699,20 @@ ForEachMacros: - 'snd_soc_dapm_widget_for_each_path_safe' - 'snd_soc_dapm_widget_for_each_sink_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' + - 'tcf_act_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_rcu' - 'usb_hub_for_each_child' @@ -479,7 +722,15 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - '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' + - 'workloads__for_each' - 'xa_for_each' - 'xa_for_each_marked' - 'xa_for_each_range' @@ -492,15 +743,20 @@ ForEachMacros: - 'xbc_node_for_each_array_value' - 'xbc_node_for_each_child' - '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' -#IncludeBlocks: Preserve # Unknown to clang-format-5.0 +IncludeBlocks: Preserve IncludeCategories: - Regex: '.*' Priority: 1 IncludeIsMainRegex: '(Test)?$' IndentCaseLabels: false -#IndentPPDirectives: None # Unknown to clang-format-5.0 +IndentGotoLabels: false +IndentPPDirectives: None IndentWidth: 8 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave @@ -510,13 +766,13 @@ MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None -#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0 +ObjCBinPackProtocolList: Auto ObjCBlockIndentWidth: 8 ObjCSpaceAfterProperty: true ObjCSpaceBeforeProtocolList: true # Taken from git's rules -#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0 +PenaltyBreakAssignment: 10 PenaltyBreakBeforeFirstCallParameter: 30 PenaltyBreakComment: 10 PenaltyBreakFirstLessLess: 0 @@ -527,14 +783,14 @@ PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: false SortIncludes: false -#SortUsingDeclarations: false # Unknown to clang-format-4.0 +SortUsingDeclarations: false SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true -#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0 -#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0 -SpaceBeforeParens: ControlStatements -#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0 +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatementsExceptForEachMacros +SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false diff --git a/kernel/allowlist.c b/kernel/allowlist.c index 01f71f1d..31d19101 100644 --- a/kernel/allowlist.c +++ b/kernel/allowlist.c @@ -31,7 +31,8 @@ static DEFINE_MUTEX(allowlist_mutex); static struct root_profile default_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 void remove_uid_from_arr(uid_t uid) @@ -72,7 +73,7 @@ static void init_default_profiles() default_root_profile.groups_count = 1; default_root_profile.groups[0] = 0; memcpy(&default_root_profile.capabilities.effective, &full_cap, - sizeof(default_root_profile.capabilities.effective)); + sizeof(default_root_profile.capabilities.effective)); default_root_profile.namespaces = 0; strcpy(default_root_profile.selinux_domain, KSU_DEFAULT_SELINUX_DOMAIN); @@ -102,7 +103,7 @@ void ksu_show_allow_list(void) struct perm_data *p = NULL; struct list_head *pos = NULL; pr_info("ksu_show_allow_list\n"); - list_for_each (pos, &allow_list) { + list_for_each(pos, &allow_list) { p = list_entry(pos, struct perm_data, list); pr_info("uid :%d, allow: %d\n", p->profile.current_uid, p->profile.allow_su); @@ -118,7 +119,8 @@ static void ksu_grant_root_to_shell() .current_uid = 2000, }; 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); } #endif @@ -129,7 +131,7 @@ bool ksu_get_app_profile(struct app_profile *profile) struct list_head *pos = NULL; bool found = false; - list_for_each (pos, &allow_list) { + list_for_each(pos, &allow_list) { p = list_entry(pos, struct perm_data, list); bool uid_match = profile->current_uid == p->profile.current_uid; if (uid_match) { @@ -144,9 +146,10 @@ exit: return found; } -static inline bool forbid_system_uid(uid_t uid) { - #define SHELL_UID 2000 - #define SYSTEM_UID 1000 +static inline bool forbid_system_uid(uid_t uid) +{ +#define SHELL_UID 2000 +#define SYSTEM_UID 1000 return uid < SHELL_UID && uid != SYSTEM_UID; } @@ -185,7 +188,7 @@ bool ksu_set_app_profile(struct app_profile *profile, bool persist) return false; } - list_for_each (pos, &allow_list) { + list_for_each(pos, &allow_list) { p = list_entry(pos, struct perm_data, list); // both uid and package must match, otherwise it will break multiple package with different user id if (profile->current_uid == p->profile.current_uid && @@ -220,9 +223,11 @@ bool ksu_set_app_profile(struct app_profile *profile, bool persist) out: if (profile->current_uid <= BITMAP_UID_MAX) { 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 - 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 { if (profile->allow_su) { /* @@ -234,7 +239,8 @@ out: WARN_ON(1); return false; } - allow_list_arr[allow_list_pointer++] = profile->current_uid; + allow_list_arr[allow_list_pointer++] = + profile->current_uid; } else { remove_uid_from_arr(profile->current_uid); } @@ -274,13 +280,15 @@ bool __ksu_is_allow_uid(uid_t uid) 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! return true; } 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 { for (i = 0; i < allow_list_pointer; i++) { 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) { 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! return false; } @@ -321,7 +330,7 @@ struct root_profile *ksu_get_root_profile(uid_t uid) struct perm_data *p = NULL; struct list_head *pos = NULL; - list_for_each (pos, &allow_list) { + list_for_each(pos, &allow_list) { p = list_entry(pos, struct perm_data, list); if (uid == p->profile.current_uid && p->profile.allow_su) { if (!p->profile.rp_config.use_default) { @@ -339,7 +348,7 @@ bool ksu_get_allow_list(int *array, int *length, bool allow) struct perm_data *p = NULL; struct list_head *pos = NULL; int i = 0; - list_for_each (pos, &allow_list) { + list_for_each(pos, &allow_list) { p = list_entry(pos, struct perm_data, list); // pr_info("get_allow_list uid: %d allow: %d\n", p->uid, p->allow); if (p->profile.allow_su == allow) { @@ -359,10 +368,11 @@ void do_save_allow_list(struct work_struct *work) struct list_head *pos = NULL; loff_t off = 0; - struct file *fp = - ksu_filp_open_compat(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644); + struct file *fp = ksu_filp_open_compat( + KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644); 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; } @@ -379,7 +389,7 @@ void do_save_allow_list(struct work_struct *work) goto exit; } - list_for_each (pos, &allow_list) { + list_for_each(pos, &allow_list) { p = list_entry(pos, struct perm_data, list); pr_info("save allow list, name: %s uid: %d, allow: %d\n", p->profile.key, p->profile.current_uid, @@ -450,7 +460,8 @@ exit: 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 *n = NULL; @@ -458,7 +469,7 @@ void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data bool modified = false; // TODO: use RCU! mutex_lock(&allowlist_mutex); - list_for_each_entry_safe (np, n, &allow_list, list) { + list_for_each_entry_safe(np, n, &allow_list, list) { uid_t uid = np->profile.current_uid; char *package = np->profile.key; // we use this uid for special cases, don't prune it! @@ -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); list_del(&np->list); 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); smp_mb(); @@ -520,7 +532,7 @@ void ksu_allowlist_exit(void) // free allowlist mutex_lock(&allowlist_mutex); - list_for_each_entry_safe (np, n, &allow_list, list) { + list_for_each_entry_safe(np, n, &allow_list, list) { list_del(&np->list); kfree(np); } diff --git a/kernel/allowlist.h b/kernel/allowlist.h index e89bf71f..298caf14 100644 --- a/kernel/allowlist.h +++ b/kernel/allowlist.h @@ -17,7 +17,8 @@ bool __ksu_is_allow_uid(uid_t uid); 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_set_app_profile(struct app_profile *, bool persist); diff --git a/kernel/apk_sign.c b/kernel/apk_sign.c index ad32ef61..9deaf00a 100644 --- a/kernel/apk_sign.c +++ b/kernel/apk_sign.c @@ -29,10 +29,10 @@ static struct apk_sign_key { unsigned size; const char *sha256; } apk_sign_keys[] = { - {EXPECTED_SIZE_SHIRKNEKO, EXPECTED_HASH_SHIRKNEKO}, // SukiSU - {EXPECTED_SIZE_OTHER, EXPECTED_HASH_OTHER}, // Dynamic Sign + { EXPECTED_SIZE_SHIRKNEKO, EXPECTED_HASH_SHIRKNEKO }, // SukiSU + { EXPECTED_SIZE_OTHER, EXPECTED_HASH_OTHER }, // Dynamic Sign #ifdef EXPECTED_SIZE - {EXPECTED_SIZE, EXPECTED_HASH}, // Custom + { EXPECTED_SIZE, EXPECTED_HASH }, // Custom #endif }; @@ -82,7 +82,8 @@ static int ksu_sha256(const unsigned char *data, unsigned int datalen, crypto_free_shash(alg); 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; struct apk_sign_key sign_key; @@ -127,7 +128,7 @@ static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset, i } ksu_kernel_read_compat(fp, cert, *size4, pos); unsigned char digest[SHA256_DIGEST_SIZE]; - if (ksu_sha256(cert, *size4, digest) < 0 ) { + if (ksu_sha256(cert, *size4, digest) < 0) { pr_info("sha256 error\n"); return false; } @@ -136,8 +137,9 @@ static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset, i hash_str[SHA256_DIGEST_SIZE * 2] = '\0'; 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) { signature_valid = true; if (matched_index) { @@ -202,7 +204,8 @@ static bool has_v1_signature_file(struct file *fp) 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 }; u32 size4; @@ -279,7 +282,8 @@ static __always_inline bool check_v2_signature(char *path, bool check_multi_mana offset = 4; if (id == 0x7109871au) { 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) { v2_signing_valid = true; } @@ -327,11 +331,12 @@ clean: if (signature_index) { *signature_index = matched_index; } - + if (check_multi_manager) { // 0: ShirkNeko/SukiSU, 1: Dynamic Sign 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 false; @@ -369,10 +374,10 @@ module_param_cb(ksu_debug_manager_uid, &expected_size_ops, bool is_manager_apk(char *path) { - return check_v2_signature(path, false, NULL); + return check_v2_signature(path, false, NULL); } bool ksu_is_multi_manager_apk(char *path, int *signature_index) { - return check_v2_signature(path, true, signature_index); + return check_v2_signature(path, true, signature_index); } diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 098a9187..7af6c93c 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -127,7 +127,7 @@ static void disable_seccomp(struct task_struct *tsk) assert_spin_locked(&tsk->sighand->siglock); // disable seccomp -#if defined(CONFIG_GENERIC_ENTRY) && \ +#if defined(CONFIG_GENERIC_ENTRY) && \ LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP; #else @@ -137,8 +137,8 @@ static void disable_seccomp(struct task_struct *tsk) #ifdef CONFIG_SECCOMP tsk->seccomp.mode = 0; if (tsk->seccomp.filter) { - // TODO: Add kernel 6.11+ support - // 5.9+ have filter_count and use seccomp_filter_release + // TODO: Add kernel 6.11+ support + // 5.9+ have filter_count and use seccomp_filter_release #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) seccomp_filter_release(tsk); atomic_set(&tsk->seccomp.filter_count, 0); @@ -186,8 +186,8 @@ void escape_to_root(void) // setup capabilities // 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! - u64 cap_for_ksud = - profile->capabilities.effective | CAP_DAC_READ_SEARCH; + u64 cap_for_ksud = profile->capabilities.effective | + CAP_DAC_READ_SEARCH; memcpy(&newcreds->cap_effective, &cap_for_ksud, sizeof(newcreds->cap_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 -static void nuke_ext4_sysfs() { +static void nuke_ext4_sysfs() +{ struct path path; int err = kern_path("/data/adb/modules", 0, &path); if (err) { @@ -252,8 +253,8 @@ static void nuke_ext4_sysfs() { return; } - struct super_block* sb = path.dentry->d_inode->i_sb; - const char* name = sb->s_type->name; + struct super_block *sb = path.dentry->d_inode->i_sb; + const char *name = sb->s_type->name; if (strcmp(name, "ext4") != 0) { pr_info("nuke but module aren't mounted\n"); path_put(&path); @@ -264,7 +265,9 @@ static void nuke_ext4_sysfs() { path_put(&path); } #else -static inline void nuke_ext4_sysfs() { } +static inline void nuke_ext4_sysfs() +{ +} #endif int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, @@ -338,13 +341,16 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, // Allow root manager to get full version strings 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) - strscpy(ksu_version_full, KSU_VERSION_FULL, KSU_FULL_VERSION_STRING); + strscpy(ksu_version_full, KSU_VERSION_FULL, + KSU_FULL_VERSION_STRING); #else - strlcpy(ksu_version_full, KSU_VERSION_FULL, KSU_FULL_VERSION_STRING); + strlcpy(ksu_version_full, KSU_VERSION_FULL, + KSU_FULL_VERSION_STRING); #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); return -EFAULT; } @@ -353,32 +359,34 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, // Allow the root manager to configure dynamic signatures if (arg2 == CMD_DYNAMIC_SIGN) { - if (!from_root && !from_manager) { - return 0; - } - - struct dynamic_sign_user_config config; - - if (copy_from_user(&config, (void __user *)arg3, sizeof(config))) { - pr_err("copy dynamic sign config failed\n"); - return 0; - } - - int ret = ksu_handle_dynamic_sign(&config); - - if (ret == 0 && config.operation == DYNAMIC_SIGN_OP_GET) { - if (copy_to_user((void __user *)arg3, &config, sizeof(config))) { - pr_err("copy dynamic sign config back failed\n"); - return 0; - } - } - - if (ret == 0) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("dynamic_sign: prctl reply error\n"); - } - } - return 0; + if (!from_root && !from_manager) { + return 0; + } + + struct dynamic_sign_user_config config; + + if (copy_from_user(&config, (void __user *)arg3, + sizeof(config))) { + pr_err("copy dynamic sign config failed\n"); + return 0; + } + + int ret = ksu_handle_dynamic_sign(&config); + + if (ret == 0 && config.operation == DYNAMIC_SIGN_OP_GET) { + if (copy_to_user((void __user *)arg3, &config, + sizeof(config))) { + pr_err("copy dynamic sign config back failed\n"); + return 0; + } + } + + if (ret == 0) { + if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { + pr_err("dynamic_sign: prctl reply error\n"); + } + } + return 0; } // Allow root manager to get active managers @@ -386,12 +394,13 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, if (!from_root && !from_manager) { return 0; } - + struct manager_list_info manager_info; int ret = ksu_get_active_managers(&manager_info); - + 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"); return 0; } @@ -414,8 +423,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, pr_info("post-fs-data triggered\n"); on_post_fs_data(); // Initializing Dynamic Signatures - ksu_dynamic_sign_init(); - pr_info("Dynamic sign config loaded during post-fs-data\n"); + ksu_dynamic_sign_init(); + pr_info("Dynamic sign config loaded during post-fs-data\n"); } break; } @@ -530,23 +539,24 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, return 0; } - #ifdef CONFIG_KPM +#ifdef CONFIG_KPM // ADD: 添加KPM模块控制 - if(sukisu_is_kpm_control_code(arg2)) { + if (sukisu_is_kpm_control_code(arg2)) { int res; - pr_info("KPM: calling before arg2=%d\n", (int) arg2); + pr_info("KPM: calling before arg2=%d\n", (int)arg2); res = sukisu_handle_kpm(arg2, arg3, arg4, arg5); return 0; } - #endif +#endif if (arg2 == CMD_ENABLE_KPM) { - bool KPM_Enabled = IS_ENABLED(CONFIG_KPM); - if (copy_to_user((void __user *)arg3, &KPM_Enabled, sizeof(KPM_Enabled))) - pr_info("KPM: copy_to_user() failed\n"); - return 0; + bool KPM_Enabled = IS_ENABLED(CONFIG_KPM); + if (copy_to_user((void __user *)arg3, &KPM_Enabled, + sizeof(KPM_Enabled))) + pr_info("KPM: copy_to_user() failed\n"); + return 0; } // all other cmds are for 'root manager' @@ -654,7 +664,8 @@ static bool should_umount(struct path *path) 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) { int ret = path_umount(path, flags); @@ -662,7 +673,7 @@ static void ksu_path_umount(const char *mnt, struct path *path, int flags) pr_info("%s: path: %s ret: %d\n", __func__, mnt, ret); #endif } -#define ksu_umount_mnt(mnt, path, flags) (ksu_path_umount(mnt, path, flags)) +#define ksu_umount_mnt(mnt, path, flags) (ksu_path_umount(mnt, path, flags)) #else static void ksu_sys_umount(const char *mnt, int flags) { @@ -681,10 +692,10 @@ static void ksu_sys_umount(const char *mnt, int flags) pr_info("%s: path: %s ret: %d\n", __func__, usermnt, ret); } -#define ksu_umount_mnt(mnt, __unused, flags) \ - ({ \ - path_put(__unused); \ - ksu_sys_umount(mnt, flags); \ +#define ksu_umount_mnt(mnt, __unused, flags) \ + ({ \ + path_put(__unused); \ + ksu_sys_umount(mnt, flags); \ }) #endif @@ -781,13 +792,11 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) return 0; } - // kernel 4.4 and 4.9 -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ - defined(CONFIG_IS_HW_HISI) || \ - defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ + defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) int ksu_key_permission(key_ref_t key_ref, const struct cred *cred, - unsigned perm) + unsigned perm) { if (init_session_keyring != NULL) { return 0; @@ -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); 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 - 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 __ksu_handle_devpts(inode); } @@ -840,9 +851,8 @@ static struct security_hook_list ksu_hooks[] = { LSM_HOOK_INIT(inode_rename, ksu_inode_rename), LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid), LSM_HOOK_INIT(inode_permission, ksu_inode_permission), -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ - defined(CONFIG_IS_HW_HISI) || \ - defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ + defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) LSM_HOOK_INIT(key_permission, ksu_key_permission) #endif }; @@ -911,7 +921,7 @@ static void free_security_hook_list(struct hlist_head *head) if (!head) return; - hlist_for_each_entry_safe (entry, temp, head, list) { + hlist_for_each_entry_safe(entry, temp, head, list) { hlist_del(&entry->list); kfree(entry); } @@ -930,7 +940,7 @@ struct hlist_head *copy_security_hlist(struct hlist_head *orig) struct security_hook_list *entry; struct security_hook_list *new_entry; - hlist_for_each_entry (entry, orig, list) { + hlist_for_each_entry(entry, orig, list) { new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); if (!new_entry) { free_security_hook_list(new_head); @@ -957,7 +967,7 @@ static void *find_head_addr(void *security_ptr, int *index) for (int i = 0; i < LSM_SEARCH_MAX; i++) { struct hlist_head *head = head_start + i; struct security_hook_list *pos; - hlist_for_each_entry (pos, head, list) { + hlist_for_each_entry(pos, head, list) { if (pos->hook.capget == security_ptr) { if (index) { *index = i; @@ -970,33 +980,33 @@ static void *find_head_addr(void *security_ptr, int *index) return NULL; } -#define GET_SYMBOL_ADDR(sym) \ - ({ \ - void *addr = kallsyms_lookup_name(#sym ".cfi_jt"); \ - if (!addr) { \ - addr = kallsyms_lookup_name(#sym); \ - } \ - addr; \ +#define GET_SYMBOL_ADDR(sym) \ + ({ \ + void *addr = kallsyms_lookup_name(#sym ".cfi_jt"); \ + if (!addr) { \ + addr = kallsyms_lookup_name(#sym); \ + } \ + addr; \ }) -#define KSU_LSM_HOOK_HACK_INIT(head_ptr, name, func) \ - do { \ - static struct security_hook_list hook = { \ - .hook = { .name = func } \ - }; \ - hook.head = head_ptr; \ - hook.lsm = "ksu"; \ - struct hlist_head *new_head = copy_security_hlist(hook.head); \ - if (!new_head) { \ - pr_err("Failed to copy security list: %s\n", #name); \ - break; \ - } \ - hlist_add_tail_rcu(&hook.list, new_head); \ - if (override_security_head(hook.head, new_head, \ - sizeof(*new_head))) { \ - free_security_hook_list(new_head); \ - pr_err("Failed to hack lsm for: %s\n", #name); \ - } \ +#define KSU_LSM_HOOK_HACK_INIT(head_ptr, name, func) \ + do { \ + static struct security_hook_list hook = { \ + .hook = { .name = func } \ + }; \ + hook.head = head_ptr; \ + hook.lsm = "ksu"; \ + struct hlist_head *new_head = copy_security_hlist(hook.head); \ + if (!new_head) { \ + pr_err("Failed to copy security list: %s\n", #name); \ + break; \ + } \ + hlist_add_tail_rcu(&hook.list, new_head); \ + if (override_security_head(hook.head, new_head, \ + sizeof(*new_head))) { \ + free_security_hook_list(new_head); \ + pr_err("Failed to hack lsm for: %s\n", #name); \ + } \ } while (0) void __init ksu_lsm_hook_init(void) diff --git a/kernel/dynamic_sign.c b/kernel/dynamic_sign.c index 56c9b9e1..3abaa062 100644 --- a/kernel/dynamic_sign.c +++ b/kernel/dynamic_sign.c @@ -24,9 +24,9 @@ // Dynamic sign configuration static struct dynamic_sign_config dynamic_sign = { - .size = 0x300, - .hash = "0000000000000000000000000000000000000000000000000000000000000000", - .is_set = 0 + .size = 0x300, + .hash = "0000000000000000000000000000000000000000000000000000000000000000", + .is_set = 0 }; // Multi-manager state @@ -41,465 +41,500 @@ static struct work_struct ksu_clear_dynamic_sign_work; bool ksu_is_dynamic_sign_enabled(void) { - unsigned long flags; - bool enabled; - - spin_lock_irqsave(&dynamic_sign_lock, flags); - enabled = dynamic_sign.is_set; - spin_unlock_irqrestore(&dynamic_sign_lock, flags); - - return enabled; + unsigned long flags; + bool enabled; + + spin_lock_irqsave(&dynamic_sign_lock, flags); + enabled = dynamic_sign.is_set; + spin_unlock_irqrestore(&dynamic_sign_lock, flags); + + return enabled; } void ksu_add_manager(uid_t uid, int signature_index) { - unsigned long flags; - int i; - - if (!ksu_is_dynamic_sign_enabled()) { - pr_info("Dynamic sign not enabled, skipping multi-manager add\n"); - return; - } - - spin_lock_irqsave(&managers_lock, flags); - - // Check if manager already exists and update - for (i = 0; i < MAX_MANAGERS; i++) { - if (active_managers[i].is_active && active_managers[i].uid == uid) { - active_managers[i].signature_index = signature_index; - spin_unlock_irqrestore(&managers_lock, flags); - pr_info("Updated manager uid=%d, signature_index=%d\n", uid, signature_index); - return; - } - } - - // Find free slot for new manager - for (i = 0; i < MAX_MANAGERS; i++) { - if (!active_managers[i].is_active) { - active_managers[i].uid = uid; - active_managers[i].signature_index = signature_index; - active_managers[i].is_active = true; - spin_unlock_irqrestore(&managers_lock, flags); - pr_info("Added manager uid=%d, signature_index=%d\n", uid, signature_index); - return; - } - } - - spin_unlock_irqrestore(&managers_lock, flags); - pr_warn("Failed to add manager, no free slots\n"); + unsigned long flags; + int i; + + if (!ksu_is_dynamic_sign_enabled()) { + pr_info("Dynamic sign not enabled, skipping multi-manager add\n"); + return; + } + + spin_lock_irqsave(&managers_lock, flags); + + // Check if manager already exists and update + for (i = 0; i < MAX_MANAGERS; i++) { + if (active_managers[i].is_active && + active_managers[i].uid == uid) { + active_managers[i].signature_index = signature_index; + spin_unlock_irqrestore(&managers_lock, flags); + pr_info("Updated manager uid=%d, signature_index=%d\n", + uid, signature_index); + return; + } + } + + // Find free slot for new manager + for (i = 0; i < MAX_MANAGERS; i++) { + if (!active_managers[i].is_active) { + active_managers[i].uid = uid; + active_managers[i].signature_index = signature_index; + active_managers[i].is_active = true; + spin_unlock_irqrestore(&managers_lock, flags); + pr_info("Added manager uid=%d, signature_index=%d\n", + uid, signature_index); + return; + } + } + + spin_unlock_irqrestore(&managers_lock, flags); + pr_warn("Failed to add manager, no free slots\n"); } void ksu_remove_manager(uid_t uid) { - unsigned long flags; - int i; - - if (!ksu_is_dynamic_sign_enabled()) { - return; - } - - spin_lock_irqsave(&managers_lock, flags); - - for (i = 0; i < MAX_MANAGERS; i++) { - if (active_managers[i].is_active && active_managers[i].uid == uid) { - active_managers[i].is_active = false; - pr_info("Removed manager uid=%d\n", uid); - break; - } - } - - spin_unlock_irqrestore(&managers_lock, flags); + unsigned long flags; + int i; + + if (!ksu_is_dynamic_sign_enabled()) { + return; + } + + spin_lock_irqsave(&managers_lock, flags); + + for (i = 0; i < MAX_MANAGERS; i++) { + if (active_managers[i].is_active && + active_managers[i].uid == uid) { + active_managers[i].is_active = false; + pr_info("Removed manager uid=%d\n", uid); + break; + } + } + + spin_unlock_irqrestore(&managers_lock, flags); } bool ksu_is_any_manager(uid_t uid) { - unsigned long flags; - bool is_manager = false; - int i; - - if (!ksu_is_dynamic_sign_enabled()) { - return false; - } - - spin_lock_irqsave(&managers_lock, flags); - - for (i = 0; i < MAX_MANAGERS; i++) { - if (active_managers[i].is_active && active_managers[i].uid == uid) { - is_manager = true; - break; - } - } - - spin_unlock_irqrestore(&managers_lock, flags); - return is_manager; + unsigned long flags; + bool is_manager = false; + int i; + + if (!ksu_is_dynamic_sign_enabled()) { + return false; + } + + spin_lock_irqsave(&managers_lock, flags); + + for (i = 0; i < MAX_MANAGERS; i++) { + if (active_managers[i].is_active && + active_managers[i].uid == uid) { + is_manager = true; + break; + } + } + + spin_unlock_irqrestore(&managers_lock, flags); + return is_manager; } int ksu_get_manager_signature_index(uid_t uid) { - unsigned long flags; - int signature_index = -1; - int i; - - // Check traditional manager first - if (ksu_manager_uid != KSU_INVALID_UID && uid == ksu_manager_uid) { - return 1; - } - - if (!ksu_is_dynamic_sign_enabled()) { - return -1; - } - - spin_lock_irqsave(&managers_lock, flags); - - for (i = 0; i < MAX_MANAGERS; i++) { - if (active_managers[i].is_active && active_managers[i].uid == uid) { - signature_index = active_managers[i].signature_index; - break; - } - } - - spin_unlock_irqrestore(&managers_lock, flags); - return signature_index; + unsigned long flags; + int signature_index = -1; + int i; + + // Check traditional manager first + if (ksu_manager_uid != KSU_INVALID_UID && uid == ksu_manager_uid) { + return 1; + } + + if (!ksu_is_dynamic_sign_enabled()) { + return -1; + } + + spin_lock_irqsave(&managers_lock, flags); + + for (i = 0; i < MAX_MANAGERS; i++) { + if (active_managers[i].is_active && + active_managers[i].uid == uid) { + signature_index = active_managers[i].signature_index; + break; + } + } + + spin_unlock_irqrestore(&managers_lock, flags); + return signature_index; } static void clear_dynamic_manager(void) { - unsigned long flags; - int i; - - spin_lock_irqsave(&managers_lock, flags); - - for (i = 0; i < MAX_MANAGERS; i++) { - if (active_managers[i].is_active) { - 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].is_active = false; - } - } - - spin_unlock_irqrestore(&managers_lock, flags); + unsigned long flags; + int i; + + spin_lock_irqsave(&managers_lock, flags); + + for (i = 0; i < MAX_MANAGERS; i++) { + if (active_managers[i].is_active) { + 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].is_active = false; + } + } + + spin_unlock_irqrestore(&managers_lock, flags); } int ksu_get_active_managers(struct manager_list_info *info) { - unsigned long flags; - int i, count = 0; - - if (!info) { - return -EINVAL; - } + unsigned long flags; + int i, count = 0; - // Add traditional manager first - if (ksu_manager_uid != KSU_INVALID_UID && count < 2) { - info->managers[count].uid = ksu_manager_uid; - info->managers[count].signature_index = 0; - count++; - } - - // Add dynamic managers - if (ksu_is_dynamic_sign_enabled()) { - spin_lock_irqsave(&managers_lock, flags); - - for (i = 0; i < MAX_MANAGERS && count < 2; i++) { - if (active_managers[i].is_active) { - info->managers[count].uid = active_managers[i].uid; - info->managers[count].signature_index = active_managers[i].signature_index; - count++; - } - } - - spin_unlock_irqrestore(&managers_lock, flags); - } - - info->count = count; - return 0; + if (!info) { + return -EINVAL; + } + + // Add traditional manager first + if (ksu_manager_uid != KSU_INVALID_UID && count < 2) { + info->managers[count].uid = ksu_manager_uid; + info->managers[count].signature_index = 0; + count++; + } + + // Add dynamic managers + if (ksu_is_dynamic_sign_enabled()) { + spin_lock_irqsave(&managers_lock, flags); + + for (i = 0; i < MAX_MANAGERS && count < 2; i++) { + if (active_managers[i].is_active) { + info->managers[count].uid = + active_managers[i].uid; + info->managers[count].signature_index = + active_managers[i].signature_index; + count++; + } + } + + spin_unlock_irqrestore(&managers_lock, flags); + } + + info->count = count; + return 0; } static void do_save_dynamic_sign(struct work_struct *work) { - u32 magic = DYNAMIC_SIGN_FILE_MAGIC; - u32 version = DYNAMIC_SIGN_FILE_VERSION; - struct dynamic_sign_config config_to_save; - loff_t off = 0; - unsigned long flags; - struct file *fp; + u32 magic = DYNAMIC_SIGN_FILE_MAGIC; + u32 version = DYNAMIC_SIGN_FILE_VERSION; + struct dynamic_sign_config config_to_save; + loff_t off = 0; + unsigned long flags; + struct file *fp; - spin_lock_irqsave(&dynamic_sign_lock, flags); - config_to_save = dynamic_sign; - spin_unlock_irqrestore(&dynamic_sign_lock, flags); + spin_lock_irqsave(&dynamic_sign_lock, flags); + config_to_save = dynamic_sign; + spin_unlock_irqrestore(&dynamic_sign_lock, flags); - if (!config_to_save.is_set) { - pr_info("Dynamic sign config not set, skipping save\n"); - return; - } + if (!config_to_save.is_set) { + pr_info("Dynamic sign config not set, skipping save\n"); + return; + } - fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (IS_ERR(fp)) { - pr_err("save_dynamic_sign create file failed: %ld\n", PTR_ERR(fp)); - return; - } + fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN, + O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (IS_ERR(fp)) { + pr_err("save_dynamic_sign create file failed: %ld\n", + PTR_ERR(fp)); + return; + } - if (ksu_kernel_write_compat(fp, &magic, sizeof(magic), &off) != sizeof(magic)) { - pr_err("save_dynamic_sign write magic failed.\n"); - goto exit; - } + if (ksu_kernel_write_compat(fp, &magic, sizeof(magic), &off) != + sizeof(magic)) { + pr_err("save_dynamic_sign write magic failed.\n"); + goto exit; + } - if (ksu_kernel_write_compat(fp, &version, sizeof(version), &off) != sizeof(version)) { - pr_err("save_dynamic_sign write version failed.\n"); - goto exit; - } + if (ksu_kernel_write_compat(fp, &version, sizeof(version), &off) != + sizeof(version)) { + pr_err("save_dynamic_sign write version failed.\n"); + goto exit; + } - 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"); - goto exit; - } + 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"); + goto exit; + } - pr_info("Dynamic sign config saved successfully\n"); + pr_info("Dynamic sign config saved successfully\n"); exit: - filp_close(fp, 0); + filp_close(fp, 0); } static void do_load_dynamic_sign(struct work_struct *work) { - loff_t off = 0; - ssize_t ret = 0; - struct file *fp = NULL; - u32 magic; - u32 version; - struct dynamic_sign_config loaded_config; - unsigned long flags; - int i; + loff_t off = 0; + ssize_t ret = 0; + struct file *fp = NULL; + u32 magic; + u32 version; + struct dynamic_sign_config loaded_config; + unsigned long flags; + int i; - fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN, O_RDONLY, 0); - if (IS_ERR(fp)) { - if (PTR_ERR(fp) == -ENOENT) { - pr_info("No saved dynamic sign config found\n"); - } else { - pr_err("load_dynamic_sign open file failed: %ld\n", PTR_ERR(fp)); - } - return; - } + fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN, O_RDONLY, 0); + if (IS_ERR(fp)) { + if (PTR_ERR(fp) == -ENOENT) { + pr_info("No saved dynamic sign config found\n"); + } else { + pr_err("load_dynamic_sign open file failed: %ld\n", + PTR_ERR(fp)); + } + return; + } - if (ksu_kernel_read_compat(fp, &magic, sizeof(magic), &off) != sizeof(magic) || - magic != DYNAMIC_SIGN_FILE_MAGIC) { - pr_err("dynamic sign file invalid magic: %x!\n", magic); - goto exit; - } + if (ksu_kernel_read_compat(fp, &magic, sizeof(magic), &off) != + sizeof(magic) || + magic != DYNAMIC_SIGN_FILE_MAGIC) { + pr_err("dynamic sign file invalid magic: %x!\n", magic); + goto exit; + } - if (ksu_kernel_read_compat(fp, &version, sizeof(version), &off) != sizeof(version)) { - pr_err("dynamic sign read version failed\n"); - goto exit; - } + if (ksu_kernel_read_compat(fp, &version, sizeof(version), &off) != + sizeof(version)) { + pr_err("dynamic sign read version failed\n"); + 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); - if (ret <= 0) { - pr_info("load_dynamic_sign read err: %zd\n", ret); - goto exit; - } + ret = ksu_kernel_read_compat(fp, &loaded_config, sizeof(loaded_config), + &off); + if (ret <= 0) { + pr_info("load_dynamic_sign read err: %zd\n", ret); + goto exit; + } - if (ret != sizeof(loaded_config)) { - pr_err("load_dynamic_sign read incomplete config: %zd/%zu\n", ret, sizeof(loaded_config)); - goto exit; - } + if (ret != sizeof(loaded_config)) { + pr_err("load_dynamic_sign read incomplete config: %zd/%zu\n", + ret, sizeof(loaded_config)); + goto exit; + } - if (loaded_config.size < 0x100 || loaded_config.size > 0x1000) { - pr_err("Invalid saved config size: 0x%x\n", loaded_config.size); - goto exit; - } + if (loaded_config.size < 0x100 || loaded_config.size > 0x1000) { + pr_err("Invalid saved config size: 0x%x\n", loaded_config.size); + goto exit; + } - if (strlen(loaded_config.hash) != 64) { - pr_err("Invalid saved config hash length: %zu\n", strlen(loaded_config.hash)); - goto exit; - } + if (strlen(loaded_config.hash) != 64) { + pr_err("Invalid saved config hash length: %zu\n", + strlen(loaded_config.hash)); + goto exit; + } - // Validate hash format - for (i = 0; i < 64; i++) { - char c = loaded_config.hash[i]; - if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))) { - pr_err("Invalid saved config hash character at position %d: %c\n", i, c); - goto exit; - } - } + // Validate hash format + for (i = 0; i < 64; i++) { + char c = loaded_config.hash[i]; + if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))) { + pr_err("Invalid saved config hash character at position %d: %c\n", + i, c); + goto exit; + } + } - spin_lock_irqsave(&dynamic_sign_lock, flags); - dynamic_sign = loaded_config; - spin_unlock_irqrestore(&dynamic_sign_lock, flags); + spin_lock_irqsave(&dynamic_sign_lock, flags); + dynamic_sign = loaded_config; + spin_unlock_irqrestore(&dynamic_sign_lock, flags); - pr_info("Dynamic sign config loaded: size=0x%x, hash=%.16s...\n", - loaded_config.size, loaded_config.hash); + pr_info("Dynamic sign config loaded: size=0x%x, hash=%.16s...\n", + loaded_config.size, loaded_config.hash); exit: - filp_close(fp, 0); + filp_close(fp, 0); } static bool persistent_dynamic_sign(void) { - return ksu_queue_work(&ksu_save_dynamic_sign_work); + return ksu_queue_work(&ksu_save_dynamic_sign_work); } static void do_clear_dynamic_sign(struct work_struct *work) { - loff_t off = 0; - struct file *fp; - char zero_buffer[512]; + loff_t off = 0; + struct file *fp; + char zero_buffer[512]; - 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); - if (IS_ERR(fp)) { - pr_err("clear_dynamic_sign create file failed: %ld\n", PTR_ERR(fp)); - return; - } + fp = ksu_filp_open_compat(KERNEL_SU_DYNAMIC_SIGN, + O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (IS_ERR(fp)) { + pr_err("clear_dynamic_sign create file failed: %ld\n", + PTR_ERR(fp)); + return; + } - // Write null bytes to overwrite the file content - 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"); - } else { - pr_info("Dynamic sign config file cleared successfully\n"); - } + // Write null bytes to overwrite the file content + 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"); + } else { + pr_info("Dynamic sign config file cleared successfully\n"); + } - filp_close(fp, 0); + filp_close(fp, 0); } static bool clear_dynamic_sign_file(void) { - return ksu_queue_work(&ksu_clear_dynamic_sign_work); + return ksu_queue_work(&ksu_clear_dynamic_sign_work); } int ksu_handle_dynamic_sign(struct dynamic_sign_user_config *config) { - unsigned long flags; - int ret = 0; - int i; - - if (!config) { - return -EINVAL; - } - - switch (config->operation) { - case DYNAMIC_SIGN_OP_SET: - if (config->size < 0x100 || config->size > 0x1000) { - pr_err("invalid size: 0x%x\n", config->size); - return -EINVAL; - } - - if (strlen(config->hash) != 64) { - pr_err("invalid hash length: %zu\n", strlen(config->hash)); - return -EINVAL; - } - - // Validate hash format - for (i = 0; i < 64; i++) { - char c = config->hash[i]; - if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))) { - pr_err("invalid hash character at position %d: %c\n", i, c); - return -EINVAL; - } - } - - spin_lock_irqsave(&dynamic_sign_lock, flags); - dynamic_sign.size = config->size; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) - strscpy(dynamic_sign.hash, config->hash, sizeof(dynamic_sign.hash)); -#else - strlcpy(dynamic_sign.hash, config->hash, sizeof(dynamic_sign.hash)); -#endif - dynamic_sign.is_set = 1; - spin_unlock_irqrestore(&dynamic_sign_lock, flags); - - persistent_dynamic_sign(); - pr_info("dynamic sign updated: size=0x%x, hash=%.16s... (multi-manager enabled)\n", - config->size, config->hash); - break; - - case DYNAMIC_SIGN_OP_GET: - spin_lock_irqsave(&dynamic_sign_lock, flags); - if (dynamic_sign.is_set) { - config->size = dynamic_sign.size; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) - strscpy(config->hash, dynamic_sign.hash, sizeof(config->hash)); -#else - strlcpy(config->hash, dynamic_sign.hash, sizeof(config->hash)); -#endif - ret = 0; - } else { - ret = -ENODATA; - } - spin_unlock_irqrestore(&dynamic_sign_lock, flags); - break; - - case DYNAMIC_SIGN_OP_CLEAR: - spin_lock_irqsave(&dynamic_sign_lock, flags); - dynamic_sign.size = 0x300; - strcpy(dynamic_sign.hash, "0000000000000000000000000000000000000000000000000000000000000000"); - dynamic_sign.is_set = 0; - spin_unlock_irqrestore(&dynamic_sign_lock, flags); - - // Clear only dynamic managers, preserve default manager - clear_dynamic_manager(); - - // Clear file using the same method as save - clear_dynamic_sign_file(); - - pr_info("Dynamic sign config cleared (multi-manager disabled)\n"); - break; - - default: - pr_err("Invalid dynamic sign operation: %d\n", config->operation); - return -EINVAL; - } + unsigned long flags; + int ret = 0; + int i; - return ret; + if (!config) { + return -EINVAL; + } + + switch (config->operation) { + case DYNAMIC_SIGN_OP_SET: + if (config->size < 0x100 || config->size > 0x1000) { + pr_err("invalid size: 0x%x\n", config->size); + return -EINVAL; + } + + if (strlen(config->hash) != 64) { + pr_err("invalid hash length: %zu\n", + strlen(config->hash)); + return -EINVAL; + } + + // Validate hash format + for (i = 0; i < 64; i++) { + char c = config->hash[i]; + if (!((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'f'))) { + pr_err("invalid hash character at position %d: %c\n", + i, c); + return -EINVAL; + } + } + + spin_lock_irqsave(&dynamic_sign_lock, flags); + dynamic_sign.size = config->size; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) + strscpy(dynamic_sign.hash, config->hash, + sizeof(dynamic_sign.hash)); +#else + strlcpy(dynamic_sign.hash, config->hash, + sizeof(dynamic_sign.hash)); +#endif + dynamic_sign.is_set = 1; + spin_unlock_irqrestore(&dynamic_sign_lock, flags); + + persistent_dynamic_sign(); + pr_info("dynamic sign updated: size=0x%x, hash=%.16s... (multi-manager enabled)\n", + config->size, config->hash); + break; + + case DYNAMIC_SIGN_OP_GET: + spin_lock_irqsave(&dynamic_sign_lock, flags); + if (dynamic_sign.is_set) { + config->size = dynamic_sign.size; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) + strscpy(config->hash, dynamic_sign.hash, + sizeof(config->hash)); +#else + strlcpy(config->hash, dynamic_sign.hash, + sizeof(config->hash)); +#endif + ret = 0; + } else { + ret = -ENODATA; + } + spin_unlock_irqrestore(&dynamic_sign_lock, flags); + break; + + case DYNAMIC_SIGN_OP_CLEAR: + spin_lock_irqsave(&dynamic_sign_lock, flags); + dynamic_sign.size = 0x300; + strcpy(dynamic_sign.hash, + "0000000000000000000000000000000000000000000000000000000000000000"); + dynamic_sign.is_set = 0; + spin_unlock_irqrestore(&dynamic_sign_lock, flags); + + // Clear only dynamic managers, preserve default manager + clear_dynamic_manager(); + + // Clear file using the same method as save + clear_dynamic_sign_file(); + + pr_info("Dynamic sign config cleared (multi-manager disabled)\n"); + break; + + default: + pr_err("Invalid dynamic sign operation: %d\n", + config->operation); + return -EINVAL; + } + + return ret; } bool ksu_load_dynamic_sign(void) { - return ksu_queue_work(&ksu_load_dynamic_sign_work); + return ksu_queue_work(&ksu_load_dynamic_sign_work); } void ksu_dynamic_sign_init(void) { - int i; - - INIT_WORK(&ksu_save_dynamic_sign_work, do_save_dynamic_sign); - INIT_WORK(&ksu_load_dynamic_sign_work, do_load_dynamic_sign); - INIT_WORK(&ksu_clear_dynamic_sign_work, do_clear_dynamic_sign); - - // Initialize manager slots - for (i = 0; i < MAX_MANAGERS; i++) { - active_managers[i].is_active = false; - } + int i; - ksu_load_dynamic_sign(); - - pr_info("Dynamic sign initialized with conditional multi-manager support\n"); + INIT_WORK(&ksu_save_dynamic_sign_work, do_save_dynamic_sign); + INIT_WORK(&ksu_load_dynamic_sign_work, do_load_dynamic_sign); + INIT_WORK(&ksu_clear_dynamic_sign_work, do_clear_dynamic_sign); + + // Initialize manager slots + for (i = 0; i < MAX_MANAGERS; i++) { + active_managers[i].is_active = false; + } + + ksu_load_dynamic_sign(); + + pr_info("Dynamic sign initialized with conditional multi-manager support\n"); } void ksu_dynamic_sign_exit(void) { - clear_dynamic_manager(); - - // Save current config before exit - do_save_dynamic_sign(NULL); - pr_info("Dynamic sign exited with persistent storage\n"); + clear_dynamic_manager(); + + // Save current config before exit + do_save_dynamic_sign(NULL); + pr_info("Dynamic sign exited with persistent storage\n"); } // Get dynamic sign configuration for signature verification bool ksu_get_dynamic_sign_config(unsigned int *size, const char **hash) { - unsigned long flags; - bool valid = false; - - spin_lock_irqsave(&dynamic_sign_lock, flags); - if (dynamic_sign.is_set) { - if (size) *size = dynamic_sign.size; - if (hash) *hash = dynamic_sign.hash; - valid = true; - } - spin_unlock_irqrestore(&dynamic_sign_lock, flags); - - return valid; + unsigned long flags; + bool valid = false; + + spin_lock_irqsave(&dynamic_sign_lock, flags); + if (dynamic_sign.is_set) { + if (size) + *size = dynamic_sign.size; + if (hash) + *hash = dynamic_sign.hash; + valid = true; + } + spin_unlock_irqrestore(&dynamic_sign_lock, flags); + + return valid; } \ No newline at end of file diff --git a/kernel/dynamic_sign.h b/kernel/dynamic_sign.h index e0f93272..c79fb4d4 100644 --- a/kernel/dynamic_sign.h +++ b/kernel/dynamic_sign.h @@ -9,15 +9,15 @@ #define KERNEL_SU_DYNAMIC_SIGN "/data/adb/ksu/.dynamic_sign" struct dynamic_sign_config { - unsigned int size; - char hash[65]; - int is_set; + unsigned int size; + char hash[65]; + int is_set; }; struct manager_info { - uid_t uid; - int signature_index; - bool is_active; + uid_t uid; + int signature_index; + bool is_active; }; // Dynamic sign operations diff --git a/kernel/include/ksu_creds.h b/kernel/include/ksu_creds.h index bdcba952..98b71b59 100644 --- a/kernel/include/ksu_creds.h +++ b/kernel/include/ksu_creds.h @@ -12,28 +12,28 @@ #include #include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) && \ - defined(CONFIG_UIDGID_STRICT_TYPE_CHECKS)) || \ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) && \ + defined(CONFIG_UIDGID_STRICT_TYPE_CHECKS)) || \ LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -#define ksu_cred_uid(x) ((x)->uid.val) -#define ksu_cred_suid(x) ((x)->suid.val) -#define ksu_cred_euid(x) ((x)->euid.val) -#define ksu_cred_fsuid(x) ((x)->fsuid.val) -#define ksu_cred_gid(x) ((x)->gid.val) -#define ksu_cred_fsgid(x) ((x)->fsgid.val) -#define ksu_cred_sgid(x) ((x)->sgid.val) -#define ksu_cred_egid(x) ((x)->egid.val) -#define ksu_current_uid() (current_uid().val) +#define ksu_cred_uid(x) ((x)->uid.val) +#define ksu_cred_suid(x) ((x)->suid.val) +#define ksu_cred_euid(x) ((x)->euid.val) +#define ksu_cred_fsuid(x) ((x)->fsuid.val) +#define ksu_cred_gid(x) ((x)->gid.val) +#define ksu_cred_fsgid(x) ((x)->fsgid.val) +#define ksu_cred_sgid(x) ((x)->sgid.val) +#define ksu_cred_egid(x) ((x)->egid.val) +#define ksu_current_uid() (current_uid().val) #else -#define ksu_cred_uid(x) ((x)->uid) -#define ksu_cred_suid(x) ((x)->suid) -#define ksu_cred_euid(x) ((x)->euid) -#define ksu_cred_fsuid(x) ((x)->fsuid) -#define ksu_cred_gid(x) ((x)->gid) -#define ksu_cred_fsgid(x) ((x)->fsgid) -#define ksu_cred_sgid(x) ((x)->sgid) -#define ksu_cred_egid(x) ((x)->egid) -#define ksu_current_uid() (current_uid()) +#define ksu_cred_uid(x) ((x)->uid) +#define ksu_cred_suid(x) ((x)->suid) +#define ksu_cred_euid(x) ((x)->euid) +#define ksu_cred_fsuid(x) ((x)->fsuid) +#define ksu_cred_gid(x) ((x)->gid) +#define ksu_cred_fsgid(x) ((x)->fsgid) +#define ksu_cred_sgid(x) ((x)->sgid) +#define ksu_cred_egid(x) ((x)->egid) +#define ksu_current_uid() (current_uid()) #endif #endif diff --git a/kernel/include/ksu_hook.h b/kernel/include/ksu_hook.h index ea0b04d3..8d748cc3 100644 --- a/kernel/include/ksu_hook.h +++ b/kernel/include/ksu_hook.h @@ -22,7 +22,7 @@ int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags); // For volume button -int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, +int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); #endif diff --git a/kernel/kernel_compat.c b/kernel/kernel_compat.c index fb10951a..d8766ee7 100644 --- a/kernel/kernel_compat.c +++ b/kernel/kernel_compat.c @@ -10,9 +10,8 @@ #include "klog.h" // IWYU pragma: keep #include "kernel_compat.h" // Add check Huawei Device -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ - defined(CONFIG_IS_HW_HISI) || \ - defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ + defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) #include #include #include @@ -81,9 +80,8 @@ void ksu_android_ns_fs_check() struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ - defined(CONFIG_IS_HW_HISI) || \ - defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ + defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) if (init_session_keyring != NULL && !current_cred()->session_keyring && (current->flags & PF_WQ_WORKER)) { 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, 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); #else 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, 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); #else 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 } -#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 count) { @@ -180,7 +181,7 @@ long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, #endif long ksu_strncpy_from_user_retry(char *dst, const void __user *unsafe_addr, - long count) + long count) { long ret; diff --git a/kernel/kernel_compat.h b/kernel/kernel_compat.h index cf262d42..0510faf8 100644 --- a/kernel/kernel_compat.h +++ b/kernel/kernel_compat.h @@ -12,9 +12,9 @@ * Huawei Hisi Kernel EBITMAP Enable or Disable Flag , * From ss/ebitmap.h */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) && \ - (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) || \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) && \ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) && \ (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) #ifdef HISI_SELINUX_EBITMAP_RO #define CONFIG_IS_HW_HISI @@ -32,12 +32,11 @@ extern long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, long count); extern long ksu_strncpy_from_user_retry(char *dst, - const void __user *unsafe_addr, - long count); + const void __user *unsafe_addr, + long count); -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ - defined(CONFIG_IS_HW_HISI) || \ - defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \ + defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) extern struct key *init_session_keyring; #endif @@ -50,9 +49,9 @@ extern ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count, loff_t *pos); #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) -#define ksu_access_ok(addr, size) access_ok(addr, size) +#define ksu_access_ok(addr, size) access_ok(addr, size) #else -#define ksu_access_ok(addr, size) access_ok(VERIFY_READ, addr, size) +#define ksu_access_ok(addr, size) access_ok(VERIFY_READ, addr, size) #endif #endif diff --git a/kernel/kpm/compact.c b/kernel/kpm/compact.c index 9bece752..6c3cbb77 100644 --- a/kernel/kpm/compact.c +++ b/kernel/kpm/compact.c @@ -13,7 +13,7 @@ #include #include #include -#include /* 包含 ARM64 重定位类型定义 */ +#include /* 包含 ARM64 重定位类型定义 */ #include #include #include @@ -29,74 +29,77 @@ #include "../allowlist.h" #include "../manager.h" -unsigned long sukisu_compact_find_symbol(const char* name); +unsigned long sukisu_compact_find_symbol(const char *name); // ====================================================================== // 兼容函数 for KPM -static -int sukisu_is_su_allow_uid(uid_t uid) { - return ksu_is_allow_uid(uid) ? 1 : 0; +static int sukisu_is_su_allow_uid(uid_t uid) +{ + return ksu_is_allow_uid(uid) ? 1 : 0; } -static -int sukisu_get_ap_mod_exclude(uid_t uid) { - // Not supported - return 0; +static int sukisu_get_ap_mod_exclude(uid_t uid) +{ + // Not supported + return 0; } -static -int sukisu_is_uid_should_umount(uid_t uid) { - return ksu_uid_should_umount(uid) ? 1 : 0; +static int sukisu_is_uid_should_umount(uid_t uid) +{ + return ksu_uid_should_umount(uid) ? 1 : 0; } -static -int sukisu_is_current_uid_manager() { - return is_manager(); +static int sukisu_is_current_uid_manager() +{ + return is_manager(); } -static -uid_t sukisu_get_manager_uid() { - return ksu_manager_uid; +static uid_t sukisu_get_manager_uid() +{ + return ksu_manager_uid; } // ====================================================================== struct CompactAddressSymbol { - const char* symbol_name; - void* addr; + const char *symbol_name; + void *addr; }; -static struct CompactAddressSymbol address_symbol [] = { - { "kallsyms_lookup_name", &kallsyms_lookup_name }, - { "compact_find_symbol", &sukisu_compact_find_symbol }, - { "is_run_in_sukisu_ultra", (void*)1 }, - { "is_su_allow_uid", &sukisu_is_su_allow_uid }, - { "get_ap_mod_exclude", &sukisu_get_ap_mod_exclude }, - { "is_uid_should_umount", &sukisu_is_uid_should_umount }, - { "is_current_uid_manager", &sukisu_is_current_uid_manager }, - { "get_manager_uid", &sukisu_get_manager_uid } +static struct CompactAddressSymbol address_symbol[] = { + { "kallsyms_lookup_name", &kallsyms_lookup_name }, + { "compact_find_symbol", &sukisu_compact_find_symbol }, + { "is_run_in_sukisu_ultra", (void *)1 }, + { "is_su_allow_uid", &sukisu_is_su_allow_uid }, + { "get_ap_mod_exclude", &sukisu_get_ap_mod_exclude }, + { "is_uid_should_umount", &sukisu_is_uid_should_umount }, + { "is_current_uid_manager", &sukisu_is_current_uid_manager }, + { "get_manager_uid", &sukisu_get_manager_uid } }; -unsigned long sukisu_compact_find_symbol(const char* name) { - int i; - unsigned long addr; +unsigned long sukisu_compact_find_symbol(const char *name) +{ + int i; + unsigned long addr; - // 先自己在地址表部分查出来 - for(i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) { - struct CompactAddressSymbol* symbol = &address_symbol[i]; - if(strcmp(name, symbol->symbol_name) == 0) { - return (unsigned long) symbol->addr; - } - } + // 先自己在地址表部分查出来 + for (i = 0; + i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); + i++) { + struct CompactAddressSymbol *symbol = &address_symbol[i]; + if (strcmp(name, symbol->symbol_name) == 0) { + return (unsigned long)symbol->addr; + } + } - // 通过内核来查 - addr = kallsyms_lookup_name(name); - if(addr) { - return addr; - } + // 通过内核来查 + addr = kallsyms_lookup_name(name); + if (addr) { + return addr; + } - return 0; + return 0; } EXPORT_SYMBOL(sukisu_compact_find_symbol); diff --git a/kernel/kpm/compact.h b/kernel/kpm/compact.h index 01e8fa88..ce6d7fdd 100644 --- a/kernel/kpm/compact.h +++ b/kernel/kpm/compact.h @@ -1,6 +1,6 @@ #ifndef ___SUKISU_KPM_COMPACT_H #define ___SUKISU_KPM_COMPACT_H -unsigned long sukisu_compact_find_symbol(const char* name); +unsigned long sukisu_compact_find_symbol(const char *name); #endif \ No newline at end of file diff --git a/kernel/kpm/kpm.c b/kernel/kpm/kpm.c index 671acafc..ca4f9a89 100644 --- a/kernel/kpm/kpm.c +++ b/kernel/kpm/kpm.c @@ -23,7 +23,7 @@ #include #include #include -#include /* 包含 ARM64 重定位类型定义 */ +#include /* 包含 ARM64 重定位类型定义 */ #include #include #include @@ -38,7 +38,7 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) && defined(CONFIG_MODULES) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) && defined(CONFIG_MODULES) #include // 需要启用 CONFIG_MODULES #endif #include "kpm.h" @@ -46,81 +46,96 @@ #ifndef NO_OPTIMIZE #if defined(__GNUC__) && !defined(__clang__) - #define NO_OPTIMIZE __attribute__((optimize("O0"))) +#define NO_OPTIMIZE __attribute__((optimize("O0"))) #elif defined(__clang__) - #define NO_OPTIMIZE __attribute__((optnone)) +#define NO_OPTIMIZE __attribute__((optnone)) #else - #define NO_OPTIMIZE +#define NO_OPTIMIZE #endif #endif // ============================================================================================ -noinline -NO_OPTIMIZE -void sukisu_kpm_load_module_path(const char* path, const char* args, void* ptr, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_load_module_path). path=%s args=%s ptr=%p\n", path, args, ptr); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); +noinline NO_OPTIMIZE void sukisu_kpm_load_module_path(const char *path, + const char *args, + void *ptr, + void __user *result) +{ + // This is a KPM module stub. + int res = -1; + printk("KPM: Stub function called (sukisu_kpm_load_module_path). path=%s args=%s ptr=%p\n", + path, args, ptr); + __asm__ volatile("nop"); // 精确控制循环不被优化 + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } -noinline -NO_OPTIMIZE -void sukisu_kpm_unload_module(const char* name, void* ptr, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_unload_module). name=%s ptr=%p\n", name, ptr); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); +noinline NO_OPTIMIZE void sukisu_kpm_unload_module(const char *name, void *ptr, + void __user *result) +{ + // This is a KPM module stub. + int res = -1; + printk("KPM: Stub function called (sukisu_kpm_unload_module). name=%s ptr=%p\n", + name, ptr); + __asm__ volatile("nop"); // 精确控制循环不被优化 + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } -noinline -NO_OPTIMIZE -void sukisu_kpm_num(void __user* result) { - // This is a KPM module stub. - int res = 0; - printk("KPM: Stub function called (sukisu_kpm_num).\n"); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); +noinline NO_OPTIMIZE void sukisu_kpm_num(void __user *result) +{ + // This is a KPM module stub. + int res = 0; + printk("KPM: Stub function called (sukisu_kpm_num).\n"); + __asm__ volatile("nop"); // 精确控制循环不被优化 + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } -noinline -NO_OPTIMIZE -void sukisu_kpm_info(const char* name, void __user* out, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_info). name=%s buffer=%p\n", name, out); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); +noinline NO_OPTIMIZE void sukisu_kpm_info(const char *name, void __user *out, + void __user *result) +{ + // This is a KPM module stub. + int res = -1; + printk("KPM: Stub function called (sukisu_kpm_info). name=%s buffer=%p\n", + name, out); + __asm__ volatile("nop"); // 精确控制循环不被优化 + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } -noinline -NO_OPTIMIZE -void sukisu_kpm_list(void __user* out, unsigned int bufferSize, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_list). buffer=%p size=%d\n", out, bufferSize); - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); +noinline NO_OPTIMIZE void +sukisu_kpm_list(void __user *out, unsigned int bufferSize, void __user *result) +{ + // This is a KPM module stub. + int res = -1; + printk("KPM: Stub function called (sukisu_kpm_list). buffer=%p size=%d\n", + out, bufferSize); + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } -noinline -NO_OPTIMIZE -void sukisu_kpm_control(void __user* name, void __user* args, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_control). name=%p args=%p\n", name, args); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); +noinline NO_OPTIMIZE void +sukisu_kpm_control(void __user *name, void __user *args, void __user *result) +{ + // This is a KPM module stub. + int res = -1; + printk("KPM: Stub function called (sukisu_kpm_control). name=%p args=%p\n", + name, args); + __asm__ volatile("nop"); // 精确控制循环不被优化 + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } -noinline -NO_OPTIMIZE -void sukisu_kpm_version(void __user* out, unsigned int bufferSize, void __user* result) { - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_version). buffer=%p size=%d\n", out, bufferSize); - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); +noinline NO_OPTIMIZE void sukisu_kpm_version(void __user *out, + unsigned int bufferSize, + void __user *result) +{ + int res = -1; + printk("KPM: Stub function called (sukisu_kpm_version). buffer=%p size=%d\n", + out, bufferSize); + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } EXPORT_SYMBOL(sukisu_kpm_load_module_path); @@ -131,54 +146,66 @@ EXPORT_SYMBOL(sukisu_kpm_list); EXPORT_SYMBOL(sukisu_kpm_version); EXPORT_SYMBOL(sukisu_kpm_control); -noinline -int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) +noinline int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5) { - if(arg2 == SUKISU_KPM_LOAD) { - char kernel_load_path[256] = { 0 }; - char kernel_args_buffer[256] = { 0 }; + if (arg2 == SUKISU_KPM_LOAD) { + char kernel_load_path[256] = { 0 }; + char kernel_args_buffer[256] = { 0 }; - if(arg3 == 0) { - return -1; - } - - strncpy_from_user((char*)&kernel_load_path, (const char __user *)arg3, 255); - if(arg4 != 0) { - 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); - } else if(arg2 == SUKISU_KPM_UNLOAD) { - char kernel_name_buffer[256] = { 0 }; + if (arg3 == 0) { + return -1; + } - if(arg3 == 0) { - return -1; - } - - strncpy_from_user((char*)&kernel_name_buffer, (const char __user *)arg3, 255); - sukisu_kpm_unload_module((const char*) &kernel_name_buffer, NULL, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_NUM) { - sukisu_kpm_num((void __user*) arg5); - } else if(arg2 == SUKISU_KPM_INFO) { - char kernel_name_buffer[256] = { 0 }; + strncpy_from_user((char *)&kernel_load_path, + (const char __user *)arg3, 255); + if (arg4 != 0) { + 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); + } else if (arg2 == SUKISU_KPM_UNLOAD) { + char kernel_name_buffer[256] = { 0 }; - if(arg3 == 0 || arg4 == 0) { - return -1; - } - - strncpy_from_user((char*)&kernel_name_buffer, (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) { - sukisu_kpm_list((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_VERSION) { - sukisu_kpm_version((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_CONTROL) { - sukisu_kpm_control((char __user*) arg3, (char __user*) arg4, (void __user*) arg5); - } - return 0; + if (arg3 == 0) { + return -1; + } + + strncpy_from_user((char *)&kernel_name_buffer, + (const char __user *)arg3, 255); + sukisu_kpm_unload_module((const char *)&kernel_name_buffer, + NULL, (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_NUM) { + sukisu_kpm_num((void __user *)arg5); + } else if (arg2 == SUKISU_KPM_INFO) { + char kernel_name_buffer[256] = { 0 }; + + if (arg3 == 0 || arg4 == 0) { + return -1; + } + + strncpy_from_user((char *)&kernel_name_buffer, + (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) { + sukisu_kpm_list((char __user *)arg3, (unsigned int)arg4, + (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_VERSION) { + sukisu_kpm_version((char __user *)arg3, (unsigned int)arg4, + (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_CONTROL) { + sukisu_kpm_control((char __user *)arg3, (char __user *)arg4, + (void __user *)arg5); + } + return 0; } -int sukisu_is_kpm_control_code(unsigned long arg2) { - return (arg2 >= CMD_KPM_CONTROL && arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0; +int sukisu_is_kpm_control_code(unsigned long arg2) +{ + return (arg2 >= CMD_KPM_CONTROL && arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0; } EXPORT_SYMBOL(sukisu_handle_kpm); diff --git a/kernel/kpm/kpm.h b/kernel/kpm/kpm.h index f9f98848..60afa14f 100644 --- a/kernel/kpm/kpm.h +++ b/kernel/kpm/kpm.h @@ -1,7 +1,8 @@ #ifndef ___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); // KPM控制代码 diff --git a/kernel/kpm/super_access.c b/kernel/kpm/super_access.c index 74fd3a0c..a9589084 100644 --- a/kernel/kpm/super_access.c +++ b/kernel/kpm/super_access.c @@ -13,7 +13,7 @@ #include #include #include -#include /* 包含 ARM64 重定位类型定义 */ +#include /* 包含 ARM64 重定位类型定义 */ #include #include #include @@ -31,38 +31,37 @@ // 结构体成员元数据 struct DynamicStructMember { - const char* name; - size_t size; - size_t offset; + const char *name; + size_t size; + size_t offset; }; // 结构体元数据(包含总大小) struct DynamicStructInfo { - const char* name; - size_t count; - size_t total_size; - struct DynamicStructMember* members; + const char *name; + size_t count; + size_t total_size; + struct DynamicStructMember *members; }; // 定义结构体元数据的宏(直接使用 struct 名称) #define DYNAMIC_STRUCT_BEGIN(struct_name) \ - static struct DynamicStructMember struct_name##_members[] = { + static struct DynamicStructMember struct_name##_members[] = { +#define DEFINE_MEMBER(struct_name, member) \ + { .name = #member, \ + .size = sizeof(((struct struct_name *)0)->member), \ + .offset = offsetof(struct struct_name, member) }, -#define DEFINE_MEMBER(struct_name, member) \ - { \ - .name = #member, \ - .size = sizeof(((struct struct_name*)0)->member), \ - .offset = offsetof(struct struct_name, member) \ - }, - -#define DYNAMIC_STRUCT_END(struct_name) \ - }; \ - static struct DynamicStructInfo struct_name##_info = { \ - .name = #struct_name, \ - .count = sizeof(struct_name##_members) / sizeof(struct DynamicStructMember), \ - .total_size = sizeof(struct struct_name), \ - .members = struct_name##_members \ - }; +#define DYNAMIC_STRUCT_END(struct_name) \ + } \ + ; \ + static struct DynamicStructInfo struct_name##_info = { \ + .name = #struct_name, \ + .count = sizeof(struct_name##_members) / \ + sizeof(struct DynamicStructMember), \ + .total_size = sizeof(struct struct_name), \ + .members = struct_name##_members \ + }; // ================================================================================== @@ -76,28 +75,28 @@ struct DynamicStructInfo { // 定义元数据 DYNAMIC_STRUCT_BEGIN(mount) - DEFINE_MEMBER(mount, mnt_parent) - DEFINE_MEMBER(mount, mnt) - DEFINE_MEMBER(mount, mnt_id) - DEFINE_MEMBER(mount, mnt_group_id) - DEFINE_MEMBER(mount, mnt_expiry_mark) - DEFINE_MEMBER(mount, mnt_master) - DEFINE_MEMBER(mount, mnt_devname) +DEFINE_MEMBER(mount, mnt_parent) +DEFINE_MEMBER(mount, mnt) +DEFINE_MEMBER(mount, mnt_id) +DEFINE_MEMBER(mount, mnt_group_id) +DEFINE_MEMBER(mount, mnt_expiry_mark) +DEFINE_MEMBER(mount, mnt_master) +DEFINE_MEMBER(mount, mnt_devname) DYNAMIC_STRUCT_END(mount) DYNAMIC_STRUCT_BEGIN(vfsmount) - DEFINE_MEMBER(vfsmount, mnt_root) - DEFINE_MEMBER(vfsmount, mnt_sb) - DEFINE_MEMBER(vfsmount, mnt_flags) +DEFINE_MEMBER(vfsmount, mnt_root) +DEFINE_MEMBER(vfsmount, mnt_sb) +DEFINE_MEMBER(vfsmount, mnt_flags) DYNAMIC_STRUCT_END(vfsmount) DYNAMIC_STRUCT_BEGIN(mnt_namespace) - DEFINE_MEMBER(mnt_namespace, ns) - DEFINE_MEMBER(mnt_namespace, root) - DEFINE_MEMBER(mnt_namespace, seq) - DEFINE_MEMBER(mnt_namespace, mounts) +DEFINE_MEMBER(mnt_namespace, ns) +DEFINE_MEMBER(mnt_namespace, root) +DEFINE_MEMBER(mnt_namespace, seq) +DEFINE_MEMBER(mnt_namespace, mounts) #if LINUX_VERSION_CODE < KERNEL_VERSION_5_15 - DEFINE_MEMBER(mnt_namespace, count) +DEFINE_MEMBER(mnt_namespace, count) #endif DYNAMIC_STRUCT_END(mnt_namespace) @@ -105,15 +104,15 @@ DYNAMIC_STRUCT_END(mnt_namespace) #ifdef CONFIG_KPROBES DYNAMIC_STRUCT_BEGIN(kprobe) - DEFINE_MEMBER(kprobe, addr) - DEFINE_MEMBER(kprobe, symbol_name) - DEFINE_MEMBER(kprobe, offset) - DEFINE_MEMBER(kprobe, pre_handler) - DEFINE_MEMBER(kprobe, post_handler) +DEFINE_MEMBER(kprobe, addr) +DEFINE_MEMBER(kprobe, symbol_name) +DEFINE_MEMBER(kprobe, offset) +DEFINE_MEMBER(kprobe, pre_handler) +DEFINE_MEMBER(kprobe, post_handler) #if LINUX_VERSION_CODE < KERNEL_VERSION_5_15 - DEFINE_MEMBER(kprobe, fault_handler) +DEFINE_MEMBER(kprobe, fault_handler) #endif - DEFINE_MEMBER(kprobe, flags) +DEFINE_MEMBER(kprobe, flags) DYNAMIC_STRUCT_END(kprobe) #endif @@ -121,76 +120,75 @@ DYNAMIC_STRUCT_END(kprobe) #include DYNAMIC_STRUCT_BEGIN(vm_area_struct) - DEFINE_MEMBER(vm_area_struct,vm_start) - DEFINE_MEMBER(vm_area_struct,vm_end) - DEFINE_MEMBER(vm_area_struct,vm_flags) - DEFINE_MEMBER(vm_area_struct,anon_vma) - DEFINE_MEMBER(vm_area_struct,vm_pgoff) - DEFINE_MEMBER(vm_area_struct,vm_file) - DEFINE_MEMBER(vm_area_struct,vm_private_data) - #ifdef CONFIG_ANON_VMA_NAME - DEFINE_MEMBER(vm_area_struct, anon_name) - #endif - DEFINE_MEMBER(vm_area_struct, vm_ops) +DEFINE_MEMBER(vm_area_struct, vm_start) +DEFINE_MEMBER(vm_area_struct, vm_end) +DEFINE_MEMBER(vm_area_struct, vm_flags) +DEFINE_MEMBER(vm_area_struct, anon_vma) +DEFINE_MEMBER(vm_area_struct, vm_pgoff) +DEFINE_MEMBER(vm_area_struct, vm_file) +DEFINE_MEMBER(vm_area_struct, vm_private_data) +#ifdef CONFIG_ANON_VMA_NAME +DEFINE_MEMBER(vm_area_struct, anon_name) +#endif +DEFINE_MEMBER(vm_area_struct, vm_ops) DYNAMIC_STRUCT_END(vm_area_struct) DYNAMIC_STRUCT_BEGIN(vm_operations_struct) - DEFINE_MEMBER(vm_operations_struct, open) - DEFINE_MEMBER(vm_operations_struct, close) - DEFINE_MEMBER(vm_operations_struct, name) - DEFINE_MEMBER(vm_operations_struct, access) +DEFINE_MEMBER(vm_operations_struct, open) +DEFINE_MEMBER(vm_operations_struct, close) +DEFINE_MEMBER(vm_operations_struct, name) +DEFINE_MEMBER(vm_operations_struct, access) DYNAMIC_STRUCT_END(vm_operations_struct) #include DYNAMIC_STRUCT_BEGIN(netlink_kernel_cfg) - DEFINE_MEMBER(netlink_kernel_cfg, groups) - DEFINE_MEMBER(netlink_kernel_cfg, flags) - DEFINE_MEMBER(netlink_kernel_cfg, input) - DEFINE_MEMBER(netlink_kernel_cfg, cb_mutex) - DEFINE_MEMBER(netlink_kernel_cfg, bind) - DEFINE_MEMBER(netlink_kernel_cfg, unbind) +DEFINE_MEMBER(netlink_kernel_cfg, groups) +DEFINE_MEMBER(netlink_kernel_cfg, flags) +DEFINE_MEMBER(netlink_kernel_cfg, input) +DEFINE_MEMBER(netlink_kernel_cfg, cb_mutex) +DEFINE_MEMBER(netlink_kernel_cfg, bind) +DEFINE_MEMBER(netlink_kernel_cfg, unbind) #if LINUX_VERSION_CODE < KERNEL_VERSION_6_1 - DEFINE_MEMBER(netlink_kernel_cfg, compare) +DEFINE_MEMBER(netlink_kernel_cfg, compare) #endif DYNAMIC_STRUCT_END(netlink_kernel_cfg) - #include DYNAMIC_STRUCT_BEGIN(task_struct) - DEFINE_MEMBER(task_struct, pid) - DEFINE_MEMBER(task_struct, tgid) - DEFINE_MEMBER(task_struct, cred) - DEFINE_MEMBER(task_struct, real_cred) - DEFINE_MEMBER(task_struct, comm) - DEFINE_MEMBER(task_struct, parent) - DEFINE_MEMBER(task_struct, group_leader) - DEFINE_MEMBER(task_struct, mm) - DEFINE_MEMBER(task_struct, active_mm) -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - DEFINE_MEMBER(task_struct, pids[PIDTYPE_PID].pid) +DEFINE_MEMBER(task_struct, pid) +DEFINE_MEMBER(task_struct, tgid) +DEFINE_MEMBER(task_struct, cred) +DEFINE_MEMBER(task_struct, real_cred) +DEFINE_MEMBER(task_struct, comm) +DEFINE_MEMBER(task_struct, parent) +DEFINE_MEMBER(task_struct, group_leader) +DEFINE_MEMBER(task_struct, mm) +DEFINE_MEMBER(task_struct, active_mm) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) +DEFINE_MEMBER(task_struct, pids[PIDTYPE_PID].pid) #else - DEFINE_MEMBER(task_struct, thread_pid) +DEFINE_MEMBER(task_struct, thread_pid) #endif - DEFINE_MEMBER(task_struct, files) - DEFINE_MEMBER(task_struct, seccomp) +DEFINE_MEMBER(task_struct, files) +DEFINE_MEMBER(task_struct, seccomp) #ifdef CONFIG_THREAD_INFO_IN_TASK - DEFINE_MEMBER(task_struct, thread_info) +DEFINE_MEMBER(task_struct, thread_info) #endif #ifdef CONFIG_CGROUPS - DEFINE_MEMBER(task_struct, cgroups) +DEFINE_MEMBER(task_struct, cgroups) #endif #ifdef CONFIG_SECURITY #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) - DEFINE_MEMBER(task_struct, security) -#else - DEFINE_MEMBER(task_struct, cred) -#endif +DEFINE_MEMBER(task_struct, security) +#else +DEFINE_MEMBER(task_struct, cred) +#endif #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) - DEFINE_MEMBER(task_struct, thread) -#else - DEFINE_MEMBER(task_struct, thread_info) +DEFINE_MEMBER(task_struct, thread) +#else +DEFINE_MEMBER(task_struct, thread_info) #endif DYNAMIC_STRUCT_END(task_struct) @@ -198,38 +196,37 @@ DYNAMIC_STRUCT_END(task_struct) #define STRUCT_INFO(name) &(name##_info) -static -struct DynamicStructInfo* dynamic_struct_infos[] = { - STRUCT_INFO(mount), - STRUCT_INFO(vfsmount), - STRUCT_INFO(mnt_namespace), - #ifdef CONFIG_KPROBES - STRUCT_INFO(kprobe), - #endif - STRUCT_INFO(vm_area_struct), - STRUCT_INFO(vm_operations_struct), - STRUCT_INFO(netlink_kernel_cfg), - STRUCT_INFO(task_struct) +static struct DynamicStructInfo *dynamic_struct_infos[] = { + STRUCT_INFO(mount), + STRUCT_INFO(vfsmount), + STRUCT_INFO(mnt_namespace), +#ifdef CONFIG_KPROBES + STRUCT_INFO(kprobe), +#endif + STRUCT_INFO(vm_area_struct), + STRUCT_INFO(vm_operations_struct), + STRUCT_INFO(netlink_kernel_cfg), + STRUCT_INFO(task_struct) }; // return 0 if successful // return -1 if struct not defined -int sukisu_super_find_struct( - const char* struct_name, - size_t* out_size, - int* out_members -) { - for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { - struct DynamicStructInfo* info = dynamic_struct_infos[i]; - if(strcmp(struct_name, info->name) == 0) { - if(out_size) - *out_size = info->total_size; - if(out_members) - *out_members = info->count; - return 0; - } - } - return -1; +int sukisu_super_find_struct(const char *struct_name, size_t *out_size, + int *out_members) +{ + for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / + sizeof(dynamic_struct_infos[0])); + i++) { + struct DynamicStructInfo *info = dynamic_struct_infos[i]; + if (strcmp(struct_name, info->name) == 0) { + if (out_size) + *out_size = info->total_size; + if (out_members) + *out_members = info->count; + return 0; + } + } + return -1; } EXPORT_SYMBOL(sukisu_super_find_struct); @@ -237,61 +234,67 @@ EXPORT_SYMBOL(sukisu_super_find_struct); // return 0 if successful // return -1 if struct not defined // return -2 if member not defined -int sukisu_super_access ( - const char* struct_name, - const char* member_name, - size_t* out_offset, - size_t* out_size -) { - for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { - struct DynamicStructInfo* info = dynamic_struct_infos[i]; - if(strcmp(struct_name, info->name) == 0) { - for (size_t i1 = 0; i1 < info->count; i1++) { - if (strcmp(info->members[i1].name, member_name) == 0) { - if(out_offset) - *out_offset = info->members[i].offset; - if(out_size) - *out_size = info->members[i].size; - return 0; - } - } - return -2; - } - } - return -1; +int sukisu_super_access(const char *struct_name, const char *member_name, + size_t *out_offset, size_t *out_size) +{ + for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / + sizeof(dynamic_struct_infos[0])); + i++) { + struct DynamicStructInfo *info = dynamic_struct_infos[i]; + if (strcmp(struct_name, info->name) == 0) { + for (size_t i1 = 0; i1 < info->count; i1++) { + if (strcmp(info->members[i1].name, + member_name) == 0) { + if (out_offset) + *out_offset = + info->members[i].offset; + if (out_size) + *out_size = + info->members[i].size; + return 0; + } + } + return -2; + } + } + return -1; } EXPORT_SYMBOL(sukisu_super_access); // 动态 container_of 宏 -#define DYNAMIC_CONTAINER_OF(offset, member_ptr) ({ \ - (offset != (size_t)-1) ? (void*)((char*)(member_ptr) - offset) : NULL; \ -}) +#define DYNAMIC_CONTAINER_OF(offset, member_ptr) \ + ({ \ + (offset != (size_t)-1) ? \ + (void *)((char *)(member_ptr) - offset) : \ + NULL; \ + }) // Dynamic container_of // return 0 if success // return -1 if current struct not defined // return -2 if target member not defined -int sukisu_super_container_of( - const char* struct_name, - const char* member_name, - void* ptr, - void** out_ptr -) { - if(ptr == NULL) { - return -3; - } - for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { - struct DynamicStructInfo* info = dynamic_struct_infos[i]; - if(strcmp(struct_name, info->name) == 0) { - for (size_t i1 = 0; i1 < info->count; i1++) { - if (strcmp(info->members[i1].name, member_name) == 0) { - *out_ptr = (void*) DYNAMIC_CONTAINER_OF(info->members[i1].offset, ptr); - return 0; - } - } - return -2; - } - } - return -1; +int sukisu_super_container_of(const char *struct_name, const char *member_name, + void *ptr, void **out_ptr) +{ + if (ptr == NULL) { + return -3; + } + for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / + sizeof(dynamic_struct_infos[0])); + i++) { + struct DynamicStructInfo *info = dynamic_struct_infos[i]; + if (strcmp(struct_name, info->name) == 0) { + for (size_t i1 = 0; i1 < info->count; i1++) { + if (strcmp(info->members[i1].name, + member_name) == 0) { + *out_ptr = (void *)DYNAMIC_CONTAINER_OF( + info->members[i1].offset, ptr); + return 0; + } + } + return -2; + } + } + return -1; } EXPORT_SYMBOL(sukisu_super_container_of); \ No newline at end of file diff --git a/kernel/kpm/super_access.h b/kernel/kpm/super_access.h index 2514be89..fc1e18cf 100644 --- a/kernel/kpm/super_access.h +++ b/kernel/kpm/super_access.h @@ -8,32 +8,21 @@ // return 0 if successful // return -1 if struct not defined -int sukisu_super_find_struct( - const char* struct_name, - size_t* out_size, - int* out_members -); +int sukisu_super_find_struct(const char *struct_name, size_t *out_size, + int *out_members); // Dynamic access struct // return 0 if successful // return -1 if struct not defined // return -2 if member not defined -int sukisu_super_access ( - const char* struct_name, - const char* member_name, - size_t* out_offset, - size_t* out_size -); +int sukisu_super_access(const char *struct_name, const char *member_name, + size_t *out_offset, size_t *out_size); // Dynamic container_of // return 0 if success // return -1 if current struct not defined // return -2 if target member not defined -int sukisu_super_container_of( - const char* struct_name, - const char* member_name, - void* ptr, - void** out_ptr -); +int sukisu_super_container_of(const char *struct_name, const char *member_name, + void *ptr, void **out_ptr); #endif \ No newline at end of file diff --git a/kernel/ksu.c b/kernel/ksu.c index 0c3c58b9..90fad9eb 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -24,9 +24,15 @@ static int __init read_kernelsu_state(char *s) } __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 -bool get_ksu_state(void) { return true; } +bool get_ksu_state(void) +{ + return true; +} #endif /* CONFIG_KSU_CMDLINE */ static struct workqueue_struct *ksu_workqueue; @@ -61,8 +67,7 @@ extern void ksu_trace_unregister(); int __init kernelsu_init(void) { - pr_info("kernelsu.enabled=%d\n", - (int)get_ksu_state()); + pr_info("kernelsu.enabled=%d\n", (int)get_ksu_state()); #ifdef CONFIG_KSU_CMDLINE if (!get_ksu_state()) { @@ -72,13 +77,20 @@ int __init kernelsu_init(void) #endif #ifdef CONFIG_KSU_DEBUG - 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("*************************************************************"); + 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 ksu_core_init(); @@ -98,7 +110,7 @@ int __init kernelsu_init(void) #endif #ifdef CONFIG_KSU_TRACEPOINT_HOOK - ksu_trace_register(); + ksu_trace_register(); #endif #ifdef MODULE @@ -127,7 +139,7 @@ void kernelsu_exit(void) #endif #ifdef CONFIG_KSU_TRACEPOINT_HOOK - ksu_trace_unregister(); + ksu_trace_unregister(); #endif ksu_sucompat_exit(); diff --git a/kernel/ksu.h b/kernel/ksu.h index 257ee096..d062676c 100644 --- a/kernel/ksu.h +++ b/kernel/ksu.h @@ -42,7 +42,7 @@ #define KSU_SELINUX_DOMAIN 64 // SukiSU Ultra kernel su version full strings -#ifndef KSU_VERSION_FULL +#ifndef KSU_VERSION_FULL #define KSU_VERSION_FULL "v3.x-00000000@unknown" #endif #define KSU_FULL_VERSION_STRING 255 @@ -52,17 +52,17 @@ #define DYNAMIC_SIGN_OP_CLEAR 2 struct dynamic_sign_user_config { - unsigned int operation; - unsigned int size; - char hash[65]; + unsigned int operation; + unsigned int size; + char hash[65]; }; struct manager_list_info { - int count; - struct { - uid_t uid; - int signature_index; - } managers[2]; + int count; + struct { + uid_t uid; + int signature_index; + } managers[2]; }; struct root_profile { diff --git a/kernel/ksu_trace.c b/kernel/ksu_trace.c index 5da68913..76d581ba 100644 --- a/kernel/ksu_trace.c +++ b/kernel/ksu_trace.c @@ -1,58 +1,68 @@ #include "ksu_trace.h" - // extern kernelsu functions 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_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 int ksu_handle_execveat(int *fd, struct filename **filename_ptr, + void *argv, void *envp, 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 int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, size_t *count_ptr); -extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); +extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, + 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 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_input_handle_event(unsigned int *type, unsigned int *code, + int *value); +extern int ksu_handle_devpts(struct inode *); // end kernelsu functions - // tracepoint callback functions -void ksu_trace_execveat_hook_callback(void *data, int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags) +void ksu_trace_execveat_hook_callback(void *data, int *fd, + struct filename **filename_ptr, + void *argv, void *envp, int *flags) { if (unlikely(ksu_execveat_hook)) ksu_handle_execveat(fd, filename_ptr, argv, envp, flags); 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 *argv, void *envp, int *flags) +void ksu_trace_execveat_sucompat_hook_callback(void *data, int *fd, + struct filename **filename_ptr, + void *argv, void *envp, + int *flags) { 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, - int *mode, int *flags) +void ksu_trace_faccessat_hook_callback(void *data, int *dfd, + const char __user **filename_user, + 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, - size_t *count_ptr) +void ksu_trace_sys_read_hook_callback(void *data, unsigned int fd, + char __user **buf_ptr, size_t *count_ptr) { if (unlikely(ksu_vfs_read_hook)) ksu_handle_sys_read(fd, buf_ptr, count_ptr); } -void ksu_trace_stat_hook_callback(void *data, int *dfd, const char __user **filename_user, - int *flags) +void ksu_trace_stat_hook_callback(void *data, int *dfd, + 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, - int *value) +void ksu_trace_input_hook_callback(void *data, unsigned int *type, + unsigned int *code, int *value) { if (unlikely(ksu_input_hook)) ksu_handle_input_handle_event(type, code, value); @@ -60,31 +70,43 @@ void ksu_trace_input_hook_callback(void *data, unsigned int *type, unsigned int void ksu_trace_devpts_hook_callback(void *data, struct inode *inode) { - ksu_handle_devpts(inode); + ksu_handle_devpts(inode); } // end tracepoint callback functions - // register tracepoint callback functions void ksu_trace_register(void) { - register_trace_ksu_trace_execveat_hook(ksu_trace_execveat_hook_callback, NULL); - register_trace_ksu_trace_execveat_sucompat_hook(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_input_hook(ksu_trace_input_hook_callback, NULL); - register_trace_ksu_trace_devpts_hook(ksu_trace_devpts_hook_callback, NULL); + register_trace_ksu_trace_execveat_hook(ksu_trace_execveat_hook_callback, + NULL); + register_trace_ksu_trace_execveat_sucompat_hook( + 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_input_hook(ksu_trace_input_hook_callback, + NULL); + register_trace_ksu_trace_devpts_hook(ksu_trace_devpts_hook_callback, + NULL); } // unregister tracepoint callback functions void ksu_trace_unregister(void) { - unregister_trace_ksu_trace_execveat_hook(ksu_trace_execveat_hook_callback, NULL); - unregister_trace_ksu_trace_execveat_sucompat_hook(ksu_trace_execveat_sucompat_hook_callback, NULL); - unregister_trace_ksu_trace_faccessat_hook(ksu_trace_faccessat_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); + unregister_trace_ksu_trace_execveat_hook( + ksu_trace_execveat_hook_callback, NULL); + unregister_trace_ksu_trace_execveat_sucompat_hook( + ksu_trace_execveat_sucompat_hook_callback, NULL); + unregister_trace_ksu_trace_faccessat_hook( + ksu_trace_faccessat_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); } diff --git a/kernel/ksu_trace.h b/kernel/ksu_trace.h index db279892..8f9eb52d 100644 --- a/kernel/ksu_trace.h +++ b/kernel/ksu_trace.h @@ -8,32 +8,35 @@ #include DECLARE_TRACE(ksu_trace_execveat_hook, - TP_PROTO(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags), - TP_ARGS(fd, filename_ptr, argv, envp, flags)); + TP_PROTO(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags), + TP_ARGS(fd, filename_ptr, argv, envp, flags)); DECLARE_TRACE(ksu_trace_execveat_sucompat_hook, - TP_PROTO(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags), - TP_ARGS(fd, filename_ptr, argv, envp, flags)); + TP_PROTO(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags), + TP_ARGS(fd, filename_ptr, argv, envp, flags)); DECLARE_TRACE(ksu_trace_faccessat_hook, - TP_PROTO(int *dfd, const char __user **filename_user, int *mode, int *flags), - TP_ARGS(dfd, filename_user, mode, flags)); + TP_PROTO(int *dfd, const char __user **filename_user, int *mode, + int *flags), + TP_ARGS(dfd, filename_user, mode, flags)); DECLARE_TRACE(ksu_trace_sys_read_hook, - TP_PROTO(unsigned int fd, char __user **buf_ptr, size_t *count_ptr), - TP_ARGS(fd, buf_ptr, count_ptr)); + TP_PROTO(unsigned int fd, char __user **buf_ptr, + size_t *count_ptr), + TP_ARGS(fd, buf_ptr, count_ptr)); DECLARE_TRACE(ksu_trace_stat_hook, - TP_PROTO(int *dfd, const char __user **filename_user, int *flags), - TP_ARGS(dfd, filename_user, flags)); + TP_PROTO(int *dfd, const char __user **filename_user, int *flags), + TP_ARGS(dfd, filename_user, flags)); DECLARE_TRACE(ksu_trace_input_hook, - TP_PROTO(unsigned int *type, unsigned int *code, int *value), - TP_ARGS(type, code, value)); + TP_PROTO(unsigned int *type, unsigned int *code, int *value), + TP_ARGS(type, code, value)); -DECLARE_TRACE(ksu_trace_devpts_hook, - TP_PROTO(struct inode *inode), - TP_ARGS(inode)); +DECLARE_TRACE(ksu_trace_devpts_hook, TP_PROTO(struct inode *inode), + TP_ARGS(inode)); #endif /* _KSU_TRACE_H */ diff --git a/kernel/ksud.c b/kernel/ksud.c index da8a43a0..b071e1ac 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -88,7 +88,7 @@ void on_post_fs_data(void) pr_info("devpts sid: %d\n", ksu_devpts_sid); // End of boot state - is_boot_phase = false; + is_boot_phase = false; } #define MAX_ARG_STRINGS 0x7FFFFFFF @@ -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); if (p && !IS_ERR(p)) { char first_arg[16]; - ksu_strncpy_from_user_retry( - first_arg, p, sizeof(first_arg)); + ksu_strncpy_from_user_retry(first_arg, p, + sizeof(first_arg)); pr_info("/system/bin/init first arg: %s\n", first_arg); 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); if (p && !IS_ERR(p)) { char first_arg[16]; - ksu_strncpy_from_user_retry( - first_arg, p, sizeof(first_arg)); + ksu_strncpy_from_user_retry(first_arg, p, + sizeof(first_arg)); pr_info("/init first arg: %s\n", first_arg); if (!strcmp(first_arg, "--second-stage")) { pr_info("/init second_stage executed\n"); @@ -573,12 +573,12 @@ static void do_stop_input_hook(struct work_struct *work) } #else static int ksu_execve_ksud_common(const char __user *filename_user, - struct user_arg_ptr *argv) + struct user_arg_ptr *argv) { struct filename filename_in, *filename_p; char path[32]; long len; - + // return early if disabled. if (!ksu_execveat_hook) { return 0; @@ -597,19 +597,21 @@ static int ksu_execve_ksud_common(const char __user *filename_user, filename_in.name = path; 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, - const char __user *const __user *__argv) +int __maybe_unused +ksu_handle_execve_ksud(const char __user *filename_user, + const char __user *const __user *__argv) { struct user_arg_ptr argv = { .ptr.native = __argv }; return ksu_execve_ksud_common(filename_user, &argv); } #if defined(CONFIG_COMPAT) && defined(CONFIG_64BIT) -int __maybe_unused ksu_handle_compat_execve_ksud(const char __user *filename_user, - const compat_uptr_t __user *__argv) +int __maybe_unused ksu_handle_compat_execve_ksud( + const char __user *filename_user, const compat_uptr_t __user *__argv) { struct user_arg_ptr argv = { .ptr.compat = __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); pr_info("unregister input kprobe: %d!\n", ret); #else - if (!ksu_input_hook) { return; } + if (!ksu_input_hook) { + return; + } ksu_input_hook = false; pr_info("stop input_hook\n"); #endif diff --git a/kernel/manager.h b/kernel/manager.h index 766cfe67..53c47879 100644 --- a/kernel/manager.h +++ b/kernel/manager.h @@ -21,7 +21,8 @@ static inline bool ksu_is_manager_uid_valid() 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() diff --git a/kernel/manager_sign.h b/kernel/manager_sign.h index 4377ba8e..0e1bcb14 100644 --- a/kernel/manager_sign.h +++ b/kernel/manager_sign.h @@ -2,11 +2,13 @@ #define MANAGER_SIGN_H // ShirkNeko/KernelSU -#define EXPECTED_SIZE_SHIRKNEKO 0x35c -#define EXPECTED_HASH_SHIRKNEKO "947ae944f3de4ed4c21a7e4f7953ecf351bfa2b36239da37a34111ad29993eef" +#define EXPECTED_SIZE_SHIRKNEKO 0x35c +#define EXPECTED_HASH_SHIRKNEKO \ + "947ae944f3de4ed4c21a7e4f7953ecf351bfa2b36239da37a34111ad29993eef" // Dynamic Sign -#define EXPECTED_SIZE_OTHER 0x300 -#define EXPECTED_HASH_OTHER "0000000000000000000000000000000000000000000000000000000000000000" +#define EXPECTED_SIZE_OTHER 0x300 +#define EXPECTED_HASH_OTHER \ + "0000000000000000000000000000000000000000000000000000000000000000" #endif /* MANAGER_SIGN_H */ diff --git a/kernel/selinux/rules.c b/kernel/selinux/rules.c index 1b56fab6..93818d27 100644 --- a/kernel/selinux/rules.c +++ b/kernel/selinux/rules.c @@ -162,9 +162,9 @@ extern bool ksu_is_compat __read_mostly; // armv7l kernel compat #ifdef CONFIG_64BIT -#define usize u64 +#define usize u64 #else -#define usize u32 +#define usize u32 #endif struct sepol_data { @@ -212,7 +212,7 @@ static int get_object(char *buf, char __user *user_object, size_t buf_sz, // reset avc cache table, otherwise the new rules will not take effect if already denied static void reset_avc_cache() { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) || \ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) || \ !defined(KSU_COMPAT_USE_SELINUX_STATE) avc_ss_reset(0); selnl_notify_policyload(0); @@ -239,11 +239,13 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4) } 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)) { 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"); return -1; } @@ -301,8 +303,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4) goto exit; } - if (get_object(perm_buf, sepol4, sizeof(perm_buf), &p) < - 0) { + if (get_object(perm_buf, sepol4, sizeof(perm_buf), &p) < 0) { pr_err("sepol: copy perm failed.\n"); goto exit; } @@ -343,13 +344,12 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4) pr_err("sepol: copy cls failed.\n"); goto exit; } - if (strncpy_from_user(operation, sepol4, - sizeof(operation)) < 0) { + if (strncpy_from_user(operation, sepol4, sizeof(operation)) < + 0) { pr_err("sepol: copy operation failed.\n"); goto exit; } - if (strncpy_from_user(perm_set, sepol5, sizeof(perm_set)) < - 0) { + if (strncpy_from_user(perm_set, sepol5, sizeof(perm_set)) < 0) { pr_err("sepol: copy perm_set failed.\n"); goto exit; } @@ -450,8 +450,8 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4) if (sepol5 == NULL) { real_object = NULL; } else { - if (strncpy_from_user(object, sepol5, - sizeof(object)) < 0) { + if (strncpy_from_user(object, sepol5, sizeof(object)) < + 0) { pr_err("sepol: copy object failed.\n"); goto exit; } @@ -510,8 +510,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4) pr_err("sepol: copy path failed.\n"); goto exit; } - if (strncpy_from_user(context, sepol3, sizeof(context)) < - 0) { + if (strncpy_from_user(context, sepol3, sizeof(context)) < 0) { pr_err("sepol: copy context failed.\n"); goto exit; } diff --git a/kernel/selinux/selinux.c b/kernel/selinux/selinux.c index d5a23b94..ca67826c 100644 --- a/kernel/selinux/selinux.c +++ b/kernel/selinux/selinux.c @@ -36,8 +36,9 @@ static int transive_to_domain(const char *domain) } #if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0) -bool __maybe_unused is_ksu_transition(const struct task_security_struct *old_tsec, - const struct task_security_struct *new_tsec) +bool __maybe_unused +is_ksu_transition(const struct task_security_struct *old_tsec, + const struct task_security_struct *new_tsec) { static u32 ksu_sid; char *secdata; @@ -45,7 +46,8 @@ bool __maybe_unused is_ksu_transition(const struct task_security_struct *old_tse bool allowed = false; 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)) return false; @@ -74,11 +76,11 @@ bool getenforce(void) if (is_selinux_disabled()) { return false; } - + return __is_selinux_enforcing(); } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \ !defined(KSU_COMPAT_HAS_CURRENT_SID) /* * get the subjective security ID of the current task diff --git a/kernel/selinux/selinux.h b/kernel/selinux/selinux.h index b411dc95..b2776fdf 100644 --- a/kernel/selinux/selinux.h +++ b/kernel/selinux/selinux.h @@ -4,7 +4,8 @@ #include #include -#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 #endif diff --git a/kernel/selinux/selinux_defs.h b/kernel/selinux/selinux_defs.h index 391da8ad..11ec5a4d 100644 --- a/kernel/selinux/selinux_defs.h +++ b/kernel/selinux/selinux_defs.h @@ -12,24 +12,24 @@ #ifdef CONFIG_SECURITY_SELINUX_DISABLE #ifdef KSU_COMPAT_USE_SELINUX_STATE -#define is_selinux_disabled() (selinux_state.disabled) +#define is_selinux_disabled() (selinux_state.disabled) #else -#define is_selinux_disabled() (selinux_disabled) +#define is_selinux_disabled() (selinux_disabled) #endif #else -#define is_selinux_disabled() (0) +#define is_selinux_disabled() (0) #endif #ifdef CONFIG_SECURITY_SELINUX_DEVELOP #ifdef KSU_COMPAT_USE_SELINUX_STATE -#define __is_selinux_enforcing() (selinux_state.enforcing) -#define __setenforce(val) selinux_state.enforcing = val +#define __is_selinux_enforcing() (selinux_state.enforcing) +#define __setenforce(val) selinux_state.enforcing = val #elif defined(SAMSUNG_SELINUX_PORTING) || !defined(KSU_COMPAT_USE_SELINUX_STATE) -#define __is_selinux_enforcing() (selinux_enforcing) -#define __setenforce(val) selinux_enforcing = val +#define __is_selinux_enforcing() (selinux_enforcing) +#define __setenforce(val) selinux_enforcing = val #endif #else -#define __is_selinux_enforcing() (1) +#define __is_selinux_enforcing() (1) #define __setenforce(val) #endif diff --git a/kernel/selinux/sepolicy.c b/kernel/selinux/sepolicy.c index acdc45ad..93024855 100644 --- a/kernel/selinux/sepolicy.c +++ b/kernel/selinux/sepolicy.c @@ -62,18 +62,18 @@ static bool add_typeattribute(struct policydb *db, const char *type, // rules #define strip_av(effect, invert) ((effect == AVTAB_AUDITDENY) == !invert) -#define ksu_hash_for_each(node_ptr, n_slot, cur) \ - int i; \ - for (i = 0; i < n_slot; ++i) \ +#define ksu_hash_for_each(node_ptr, n_slot, cur) \ + int i; \ + for (i = 0; i < n_slot; ++i) \ for (cur = node_ptr[i]; cur; cur = cur->next) // htable is a struct instead of pointer above 5.8.0: // https://elixir.bootlin.com/linux/v5.8-rc1/source/security/selinux/ss/symtab.h #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) -#define ksu_hashtab_for_each(htab, cur) \ +#define ksu_hashtab_for_each(htab, cur) \ ksu_hash_for_each(htab.htable, htab.size, cur) #else -#define ksu_hashtab_for_each(htab, cur) \ +#define ksu_hashtab_for_each(htab, cur) \ ksu_hash_for_each(htab->htable, htab->size, cur) #endif @@ -84,7 +84,7 @@ static bool add_typeattribute(struct policydb *db, const char *type, #define symtab_insert(s, name, datum) hashtab_insert((s)->table, name, datum) #endif -#define avtab_for_each(avtab, cur) \ +#define avtab_for_each(avtab, cur) \ ksu_hash_for_each(avtab.htable, avtab.nslot, cur); static struct avtab_node *get_avtab_node(struct policydb *db, @@ -657,30 +657,27 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr) } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) - struct ebitmap *new_type_attr_map_array = - ksu_realloc(db->type_attr_map_array, - value * sizeof(struct ebitmap), - (value - 1) * sizeof(struct ebitmap)); + struct ebitmap *new_type_attr_map_array = ksu_realloc( + db->type_attr_map_array, value * sizeof(struct ebitmap), + (value - 1) * sizeof(struct ebitmap)); if (!new_type_attr_map_array) { pr_err("add_type: alloc type_attr_map_array failed\n"); return false; } - struct type_datum **new_type_val_to_struct = - ksu_realloc(db->type_val_to_struct, - sizeof(*db->type_val_to_struct) * value, - sizeof(*db->type_val_to_struct) * (value - 1)); + struct type_datum **new_type_val_to_struct = ksu_realloc( + db->type_val_to_struct, sizeof(*db->type_val_to_struct) * value, + sizeof(*db->type_val_to_struct) * (value - 1)); if (!new_type_val_to_struct) { pr_err("add_type: alloc type_val_to_struct failed\n"); return false; } - char **new_val_to_name_types = - ksu_realloc(db->sym_val_to_name[SYM_TYPES], - sizeof(char *) * value, - sizeof(char *) * (value - 1)); + char **new_val_to_name_types = ksu_realloc( + db->sym_val_to_name[SYM_TYPES], sizeof(char *) * value, + sizeof(char *) * (value - 1)); if (!new_val_to_name_types) { pr_err("add_type: alloc val_to_name failed\n"); return false; @@ -727,10 +724,9 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr) return false; } - char **new_val_to_name_types = - krealloc(db->sym_val_to_name[SYM_TYPES], - sizeof(char *) * db->symtab[SYM_TYPES].nprim, - GFP_KERNEL); + char **new_val_to_name_types = krealloc( + db->sym_val_to_name[SYM_TYPES], + sizeof(char *) * db->symtab[SYM_TYPES].nprim, GFP_KERNEL); if (!new_val_to_name_types) { pr_err("add_type: alloc val_to_name failed\n"); return false; diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 64928715..ecc01137 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -67,11 +67,11 @@ static inline bool __is_su_allowed(const void *ptr_to_check) return true; } -#define is_su_allowed(ptr) __is_su_allowed((const void *)ptr) +#define is_su_allowed(ptr) __is_su_allowed((const void *)ptr) static int ksu_sucompat_user_common(const char __user **filename_user, - const char *syscall_name, - const bool escalate) + const char *syscall_name, + const bool escalate) { char path[sizeof(su)]; // sizeof includes nullterm already! memset(path, 0, sizeof(path)); diff --git a/kernel/throne_tracker.c b/kernel/throne_tracker.c index 7725e1a3..429fb9ab 100644 --- a/kernel/throne_tracker.c +++ b/kernel/throne_tracker.c @@ -63,7 +63,8 @@ static int get_pkg_from_apk_path(char *pkg, const char *path) 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]; if (get_pkg_from_apk_path(pkg, apk) < 0) { @@ -84,13 +85,14 @@ static void crown_manager(const char *apk, struct list_head *uid_data, int signa struct list_head *list = (struct list_head *)uid_data; struct uid_data *np; - list_for_each_entry (np, list, list) { + list_for_each_entry(np, list, list) { 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) { ksu_add_manager(np->uid, signature_index); - + if (!ksu_is_manager_uid_valid()) { ksu_set_manager_uid(np->uid); } @@ -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 && (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) { 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; list_add_tail(&data->list, my_ctx->data_path_list); } 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; #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 - unsigned int hash = full_name_hash(NULL, dirpath, strlen(dirpath)); + unsigned int hash = + full_name_hash(NULL, dirpath, strlen(dirpath)); #endif list_for_each_entry(pos, &apk_path_hash_list, list) { if (hash == pos->hash) { @@ -199,19 +205,25 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name, } 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", dirpath, is_multi_manager, signature_index); - - if (is_multi_manager && (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); + + if (is_multi_manager && + (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); if (apk_data) { apk_data->hash = hash; 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)) { @@ -219,16 +231,20 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name, *my_ctx->stop = 1; // 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); kfree(pos); } } 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) { apk_data->hash = hash; 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; list_for_each_entry_safe(pos, n, &data_path_list, list) { - struct my_dir_context ctx = { .ctx.actor = my_actor, - .data_path_list = &data_path_list, - .parent_dir = pos->dirpath, - .private_data = uid_data, - .depth = pos->depth, - .stop = &stop }; + struct my_dir_context ctx = { + .ctx.actor = my_actor, + .data_path_list = &data_path_list, + .parent_dir = pos->dirpath, + .private_data = uid_data, + .depth = pos->depth, + .stop = &stop + }; struct file *file; 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)) { - 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; } - + // grab magic on first folder, which is /data/app if (!data_app_magic) { if (file->f_inode->i_sb->s_magic) { - 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); + 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 { filp_close(file, NULL); goto skip_iterate; } } - - if (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); + + if (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); goto skip_iterate; } @@ -318,7 +345,7 @@ static bool is_uid_exist(uid_t uid, char *package, void *data) struct uid_data *np; bool exist = false; - list_for_each_entry (np, list, list) { + list_for_each_entry(np, list, list) { if (np->uid == uid % 100000 && strncmp(np->package, package, KSU_MAX_PACKAGE_NAME) == 0) { exist = true; @@ -392,8 +419,8 @@ void track_throne() // first, check if manager_uid exist! bool manager_exist = false; bool dynamic_manager_exist = false; - - list_for_each_entry (np, &uid_list, list) { + + list_for_each_entry(np, &uid_list, list) { // if manager is installed in work profile, the uid in packages.list is still equals main profile // don't delete it in this case! int manager_uid = ksu_get_manager_uid() % 100000; @@ -402,10 +429,10 @@ void track_throne() break; } } - + // Check for dynamic managers if (!dynamic_manager_exist && ksu_is_dynamic_sign_enabled()) { - list_for_each_entry (np, &uid_list, list) { + list_for_each_entry(np, &uid_list, list) { if (ksu_is_any_manager(np->uid)) { dynamic_manager_exist = true; break; @@ -434,7 +461,7 @@ prune: ksu_prune_allowlist(is_uid_exist, &uid_list); out: // free uid_list - list_for_each_entry_safe (np, n, &uid_list, list) { + list_for_each_entry_safe(np, n, &uid_list, list) { list_del(&np->list); kfree(np); }