- Remove some always-true checks (checking for unsigned < 0).

- Only check largs->num against max_ldt_segment on amd64 for I386_SET_LDT
  when descriptors are provided.  Specifically, allow the 'start == 0'
  and 'num == 0' special case used to free all LDT entries that previously
  failed with EINVAL.

Submitted by:	clang via rdivacky (some of 1)
Reviewed by:	kib
This commit is contained in:
jhb 2011-01-18 16:43:01 +00:00
parent 2f51f05968
commit 292fcec2b7
2 changed files with 6 additions and 7 deletions

View File

@ -95,14 +95,14 @@ sysarch_ldt(struct thread *td, struct sysarch_args *uap, int uap_space)
largs = &la;
} else
largs = (struct i386_ldt_args *)uap->parms;
if (largs->num > max_ldt_segment || largs->num <= 0)
return (EINVAL);
switch (uap->op) {
case I386_GET_LDT:
error = amd64_get_ldt(td, largs);
break;
case I386_SET_LDT:
if (largs->descs != NULL && largs->num > max_ldt_segment)
return (EINVAL);
set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
if (largs->descs != NULL) {
lp = (struct user_segment_descriptor *)
@ -539,7 +539,7 @@ amd64_set_ldt(td, uap, descs)
/* Free descriptors */
if (uap->start == 0 && uap->num == 0)
uap->num = max_ldt_segment;
if (uap->num <= 0)
if (uap->num == 0)
return (EINVAL);
if ((pldt = mdp->md_ldt) == NULL ||
uap->start >= max_ldt_segment)
@ -559,7 +559,7 @@ amd64_set_ldt(td, uap, descs)
/* verify range of descriptors to modify */
largest_ld = uap->start + uap->num;
if (uap->start >= max_ldt_segment ||
uap->num < 0 || largest_ld > max_ldt_segment)
largest_ld > max_ldt_segment)
return (EINVAL);
}

View File

@ -623,7 +623,7 @@ i386_set_ldt(td, uap, descs)
uap->start = NLDT;
uap->num = MAX_LD - NLDT;
}
if (uap->num <= 0)
if (uap->num == 0)
return (EINVAL);
mtx_lock_spin(&dt_lock);
if ((pldt = mdp->md_ldt) == NULL ||
@ -644,8 +644,7 @@ i386_set_ldt(td, uap, descs)
if (!(uap->start == LDT_AUTO_ALLOC && uap->num == 1)) {
/* verify range of descriptors to modify */
largest_ld = uap->start + uap->num;
if (uap->start >= MAX_LD ||
uap->num < 0 || largest_ld > MAX_LD) {
if (uap->start >= MAX_LD || largest_ld > MAX_LD) {
return (EINVAL);
}
}