Re: LDT problems with 2.1.109 and above.

Root of all evil - David Bruce (root@Hulcote.Com)
Tue, 11 Aug 1998 13:18:44 +0100 (BST)


David wrote:
> Hello all
>
> I am having problems with the iBCS module with 2.1.109 and above. This
> module uses the call gate in the default ldt as an entry point.
>
> But all programs using the module are now crashing with a segmentation
> violation. It looks like the default ldt is not being setup and the
> programs are crashing because the call gate is missing.
>
> I have had a look at the code but am unable to workout where the problem
> is but i did come across something odd while i was doing some tests. I
> modified the modify_ldt system call to copy over the default ldt when
> it sets up a new ldt (Why does it not do this normaly?) and all the
> segmentation faults went away but why? I cant work out how this could
> cause the problem to go away.
>
> Confused
> David Bruce.

I can see what the problem is now.

The kernel assumes that if current->mm->segments == NULL then the
ldt points to the default ldt. But when release_segments() is called
it is setting current->mm->segments to NULL and setting the ldt to 0.

Patch follows.

BTW can some one please tell me why the modify_ldt system call does not
copy over the default ldt when it sets up a new ldt?

regards
David Bruce.

--- linux/arch/i386/kernel/process.c.org Tue Jul 21 01:22:35 1998
+++ linux/arch/i386/kernel/process.c Tue Aug 11 11:41:09 1998
@@ -476,27 +476,30 @@
} else
free_pages((unsigned long) p, 1);
}

void release_segments(struct mm_struct *mm)
{
- void * ldt = mm->segments;
- int nr;

/* forget local segments */
- __asm__ __volatile__("movl %w0,%%fs ; movl %w0,%%gs ; lldt %w0"
+ __asm__ __volatile__("movl %w0,%%fs ; movl %w0,%%gs"
: /* no outputs */
: "r" (0));
current->tss.ldt = 0;
- /*
- * Set the GDT entry back to the default.
- */
- nr = current->tarray_ptr - &task[0];
- set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY, &default_ldt, 1);

- if (ldt) {
+ if (mm->segments) {
+ void * ldt = mm->segments;
+ int nr;
+
+ /*
+ * Set the GDT entry back to the default.
+ */
+ nr = current->tarray_ptr - &task[0];
+ set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY, &default_ldt, 1);
+ load_ldt(0);
+
mm->segments = NULL;
vfree(ldt);
}
}

/*

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html