@@ -121,6 +121,24 @@ static Elf64_Sym *vdso_symtab_get(struct vdso_symtab *symtab, const char *name)
121121 return NULL ;
122122}
123123
124+ /*
125+ * Return the offset in the enclave where the TCS segment can be found.
126+ * The first RW segment loaded is the TCS.
127+ */
128+ static off_t encl_get_tcs_offset (struct encl * encl )
129+ {
130+ int i ;
131+
132+ for (i = 0 ; i < encl -> nr_segments ; i ++ ) {
133+ struct encl_segment * seg = & encl -> segment_tbl [i ];
134+
135+ if (i == 0 && seg -> prot == (PROT_READ | PROT_WRITE ))
136+ return seg -> offset ;
137+ }
138+
139+ return -1 ;
140+ }
141+
124142/*
125143 * Return the offset in the enclave where the data segment can be found.
126144 * The first RW segment loaded is the TCS, skip that to get info on the
@@ -567,6 +585,59 @@ TEST_F(enclave, pte_permissions)
567585 EXPECT_EQ (self -> run .exception_addr , 0 );
568586}
569587
588+ /*
589+ * Modifying permissions of TCS page should not be possible.
590+ */
591+ TEST_F (enclave , tcs_permissions )
592+ {
593+ struct sgx_enclave_restrict_permissions ioc ;
594+ int ret , errno_save ;
595+
596+ ASSERT_TRUE (setup_test_encl (ENCL_HEAP_SIZE_DEFAULT , & self -> encl , _metadata ));
597+
598+ memset (& self -> run , 0 , sizeof (self -> run ));
599+ self -> run .tcs = self -> encl .encl_base ;
600+
601+ memset (& ioc , 0 , sizeof (ioc ));
602+
603+ /*
604+ * Ensure kernel supports needed ioctl() and system supports needed
605+ * commands.
606+ */
607+
608+ ret = ioctl (self -> encl .fd , SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS , & ioc );
609+ errno_save = ret == -1 ? errno : 0 ;
610+
611+ /*
612+ * Invalid parameters were provided during sanity check,
613+ * expect command to fail.
614+ */
615+ ASSERT_EQ (ret , -1 );
616+
617+ /* ret == -1 */
618+ if (errno_save == ENOTTY )
619+ SKIP (return ,
620+ "Kernel does not support SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS ioctl()" );
621+ else if (errno_save == ENODEV )
622+ SKIP (return , "System does not support SGX2" );
623+
624+ /*
625+ * Attempt to make TCS page read-only. This is not allowed and
626+ * should be prevented by the kernel.
627+ */
628+ ioc .offset = encl_get_tcs_offset (& self -> encl );
629+ ioc .length = PAGE_SIZE ;
630+ ioc .permissions = SGX_SECINFO_R ;
631+
632+ ret = ioctl (self -> encl .fd , SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS , & ioc );
633+ errno_save = ret == -1 ? errno : 0 ;
634+
635+ EXPECT_EQ (ret , -1 );
636+ EXPECT_EQ (errno_save , EINVAL );
637+ EXPECT_EQ (ioc .result , 0 );
638+ EXPECT_EQ (ioc .count , 0 );
639+ }
640+
570641/*
571642 * Enclave page permission test.
572643 *
0 commit comments