Hi,

When you pass an initrd to UML and the size of the initrd is too big for
the current kernel memory, a panic() call is done with the message("Out
of memory").

But this message never hits the stdout as the following stack trace
dumps because there is no current_thread_info() in the UML stack, which
is still active at this time:

(gdb) bt
#0  dump_stack_print_info (log_lvl=0x6053f583 "\001d") at 
kernel/printk/printk.c:2979
#1  0x000000006047126b in __dump_stack () at lib/dump_stack.c:14
#2  dump_stack () at lib/dump_stack.c:50
#3  0x000000006046bf87 in panic (fmt=<optimized out>) at kernel/panic.c:110
#4  0x0000000060010bc7 in ___alloc_bootmem (limit=<optimized out>, 
goal=<optimized out>, align=<optimized out>, size=<optimized out>) a
t mm/bootmem.c:674
#5  __alloc_bootmem (size=55792228, align=<optimized out>, goal=<optimized 
out>) at mm/bootmem.c:696
#6  0x0000000060004eca in read_initrd () at arch/um/kernel/initrd.c:39
#7  0x0000000060004b71 in uml_postsetup () at arch/um/kernel/um_arch.c:228
#8  linux_main (argc=<optimized out>, argv=0x7fffffffdf98) at 
arch/um/kernel/um_arch.c:377
#9  0x00000000600059db in main (argc=<optimized out>, argv=0x7fffffffdf98, 
envp=<optimized out>) at arch/um/os-Linux/main.c:156

So current_thread_info() will return the stack of the UML program
itself, which is an invalid struct thread_info:
thread info= 0x7fffffffc000

so the access to current->pid, will segfault as "current" is a macro for
current_thread_info()->task->pid and task is NULL.

2978│ void dump_stack_print_info(const char *log_lvl)
2979│ {
2980│         struct thread_info * ti = current_thread_info();
2981│         printf("thread info =%p\n", ti);
2982│
2983│         printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n",
2984│                log_lvl, raw_smp_processor_id(), current->pid, 
current->comm,
2985│                print_tainted(), init_utsname()->release,
2986├>               (int)strcspn(init_utsname()->version, " "),
2987│                init_utsname()->version);


any ideas how to fix this?

I tried to add this, but this failed horribly:

diff --git a/arch/um/include/asm/thread_info.h 
b/arch/um/include/asm/thread_info.h
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -12,6 +12,11 @@
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
+#define DEBUG_CHECK_CURRENT_TI
+#ifdef DEBUG_CHECK_CURRENT_TI
+#include <kern_util.h>
+#endif
+
 struct thread_info {
        struct task_struct      *task;          /* main task structure */
        struct exec_domain      *exec_domain;   /* execution domain */
@@ -53,6 +59,12 @@ static inline struct thread_info *current_thread_info(void)
 
        asm volatile ("" : "=r" (p) : "0" (&ti));
        ti = (struct thread_info *) (((unsigned long)p) & ~mask);
+#ifdef DEBUG_CHECK_CURRENT_TI
+       if(!is_kernel_addr((void*)ti)) {
+               printk(KERN_CRIT "Access to current_thread_info() from 
non-kernel stack!\n");
+//             return &init_thread_info;
+       }
+#endif
        return ti;
 }
 
diff --git a/arch/um/include/shared/kern_util.h 
b/arch/um/include/shared/kern_util.h
index 83a91f9..545503e 100644
--- a/arch/um/include/shared/kern_util.h
+++ b/arch/um/include/shared/kern_util.h
@@ -19,6 +19,7 @@ extern int kmalloc_ok;
 #define UML_ROUND_UP(addr) \
        ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK)
 
+extern int is_kernel_addr(void* addr);
 extern unsigned long alloc_stack(int order, int atomic);
 extern void free_stack(unsigned long stack, int order);
 
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index df9191a..a1caebb 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -254,7 +255,7 @@ void __wrap_free(void *ptr)
         * there is a possibility for memory leaks.
         */
 
-       if ((addr >= uml_physmem) && (addr < high_physmem)) {
+       if (is_kernel_addr(addr)) {
                if (kmalloc_ok)
                        kfree(ptr);
        }
@@ -264,3 +265,10 @@ void __wrap_free(void *ptr)
        }
        else __real_free(ptr);
 }
+
+int is_kernel_addr(void* addr)
+{
+       if((addr >= uml_physmem) && (addr < high_physmem))
+               return 1;
+       return 0;
+}
\ No newline at end of file



------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

Reply via email to