@@ -137,38 +137,59 @@ static void check_valid_segment(uint16_t index, int ldt,
137
137
}
138
138
}
139
139
140
- static bool install_valid_mode (const struct user_desc * desc , uint32_t ar ,
141
- bool oldmode )
140
+ static bool install_valid_mode (const struct user_desc * d , uint32_t ar ,
141
+ bool oldmode , bool ldt )
142
142
{
143
- int ret = syscall (SYS_modify_ldt , oldmode ? 1 : 0x11 ,
144
- desc , sizeof (* desc ));
145
- if (ret < -1 )
146
- errno = - ret ;
143
+ struct user_desc desc = * d ;
144
+ int ret ;
145
+
146
+ if (!ldt ) {
147
+ #ifndef __i386__
148
+ /* No point testing set_thread_area in a 64-bit build */
149
+ return false;
150
+ #endif
151
+ if (!gdt_entry_num )
152
+ return false;
153
+ desc .entry_number = gdt_entry_num ;
154
+
155
+ ret = syscall (SYS_set_thread_area , & desc );
156
+ } else {
157
+ ret = syscall (SYS_modify_ldt , oldmode ? 1 : 0x11 ,
158
+ & desc , sizeof (desc ));
159
+
160
+ if (ret < -1 )
161
+ errno = - ret ;
162
+
163
+ if (ret != 0 && errno == ENOSYS ) {
164
+ printf ("[OK]\tmodify_ldt returned -ENOSYS\n" );
165
+ return false;
166
+ }
167
+ }
168
+
147
169
if (ret == 0 ) {
148
- uint32_t limit = desc -> limit ;
149
- if (desc -> limit_in_pages )
170
+ uint32_t limit = desc . limit ;
171
+ if (desc . limit_in_pages )
150
172
limit = (limit << 12 ) + 4095 ;
151
- check_valid_segment (desc -> entry_number , 1 , ar , limit , true);
173
+ check_valid_segment (desc . entry_number , ldt , ar , limit , true);
152
174
return true;
153
- } else if (errno == ENOSYS ) {
154
- printf ("[OK]\tmodify_ldt returned -ENOSYS\n" );
155
- return false;
156
175
} else {
157
- if (desc -> seg_32bit ) {
158
- printf ("[FAIL]\tUnexpected modify_ldt failure %d\n" ,
176
+ if (desc .seg_32bit ) {
177
+ printf ("[FAIL]\tUnexpected %s failure %d\n" ,
178
+ ldt ? "modify_ldt" : "set_thread_area" ,
159
179
errno );
160
180
nerrs ++ ;
161
181
return false;
162
182
} else {
163
- printf ("[OK]\tmodify_ldt rejected 16 bit segment\n" );
183
+ printf ("[OK]\t%s rejected 16 bit segment\n" ,
184
+ ldt ? "modify_ldt" : "set_thread_area" );
164
185
return false;
165
186
}
166
187
}
167
188
}
168
189
169
190
static bool install_valid (const struct user_desc * desc , uint32_t ar )
170
191
{
171
- return install_valid_mode (desc , ar , false);
192
+ return install_valid_mode (desc , ar , false, true );
172
193
}
173
194
174
195
static void install_invalid (const struct user_desc * desc , bool oldmode )
0 commit comments