@@ -57,7 +57,7 @@ struct dl_cfi_info
5757static void
5858dl_check_legacy_object (struct link_map * m , struct dl_cfi_info * info )
5959{
60- /* Iterate through the dependencies and disable if needed here */
60+ /* Iterate through the dependencies and record legacy objects */
6161 struct link_map * l = NULL ;
6262 unsigned int i ;
6363 i = m -> l_searchlist .r_nlist ;
@@ -86,7 +86,11 @@ dl_check_legacy_object (struct link_map *m, struct dl_cfi_info *info)
8686 | ~(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
8787 | GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS ));
8888
89- /* Bookkeeping legacy objects */
89+ /* Bookkeeping first found mismatch object for both lp/ss.
90+ These information would only be used by dlopen check for now.
91+ A dependency with a feature on will be record as legacy if the task
92+ did not enable the feature, however it is safe because the following
93+ check will only be performed if the task has the feature on. */
9094#ifdef __riscv_landing_pad
9195 if ((info -> feature_1_legacy & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED ) == 0
9296 && ((info -> enable_feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED )
@@ -208,8 +212,8 @@ dl_cfi_check_dlopen (struct link_map *m, struct dl_cfi_info *info)
208212 _dl_signal_error (0 , m -> l_initfini [legacy_obj ]-> l_name , "dlopen" , msg );
209213
210214 if (disable_feature_1 != 0 )
211- // FIXME: Disable CFI here
212- int res = -1 ;
215+ {
216+ int res = dl_cfi_disable_cfi ( disable_feature_1 ) ;
213217 if (res )
214218 {
215219 msg = N_ ("can't disable CFI feature" );
@@ -223,14 +227,29 @@ dl_cfi_check_dlopen (struct link_map *m, struct dl_cfi_info *info)
223227attribute_hidden void
224228_dl_cfi_setup_features (unsigned int feature_1 )
225229{
226- /* Since prctl could fail to enable some features
227- use prctl to get enabled features again and sync it back. */
230+ /* Enable features. Shadow stack is enabled earlier as it should
231+ * be enabled in a function that never returns. */
232+ #ifdef __riscv_landing_pad
233+ dl_cfi_enable_lp (feature_1 );
234+ #endif /* __riscv_landing_pad */
235+
236+ /* Since we could failed to enable some features,
237+ get enabled features from system again and sync it back. */
238+ int status = dl_cfi_get_cfi_status ();
239+ GL (dl_riscv_feature_1 ) = status | (GL (dl_riscv_feature_1 ) &
240+ ~(GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS
241+ | GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED ));
242+
243+ /* Lock features if set to always_on */
228244#ifdef __riscv_landing_pad
229- if (feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED )
230- INTERNAL_SYSCALL_CALL (prctl , PR_SET_INDIR_BR_LP_STATUS ,
231- PR_INDIR_BR_LP_ENABLE , 0 , 0 , 0 );
245+ if (GL (dl_riscv_feature_control ).lp == cfi_always_on )
246+ dl_cfi_lock_cfi (GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED );
232247#endif /* __riscv_landing_pad */
233- /* FIXME: Read enabled features from kernel and re-sync */
248+ #ifdef __riscv_shadow_stack
249+ if (GL (dl_riscv_feature_control ).ss == cfi_always_on )
250+ dl_cfi_lock_cfi (GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS );
251+ #endif /* __riscv_shadow_stack */
252+ /* FIXME: Should we terminate if failed to lock under always on mode? */
234253}
235254
236255/* Enable CFI for l and its dependencies. */
@@ -287,7 +306,6 @@ _dl_cfi_check (struct link_map *l, const char *program)
287306 info .feature_1_legacy_ss = 0 ;
288307#endif
289308
290- info .feature_1_enabled = GL (dl_riscv_feature_1 );
291309 info .feature_1_legacy = 0 ;
292310
293311#ifdef SHARED
0 commit comments