Re: [Qemu-devel] [PATCH] -chroot and -su options.

2008-03-04 Thread Edgar E. Iglesias
On Wed, Mar 05, 2008 at 12:51:36AM -0600, Rob Landley wrote:
> On Tuesday 04 March 2008 05:22:12 you wrote:
> > On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote:
> > > Quick and dirty patch to teach qemu application emulation how to chroot
> > > (and drop privs), so you don't have to pollute a target filesystem with
> > > host code, and/or figure out how to build qemu static in order to run a
> > > dynamic binary.
> >
> > Hi Rob,
> >
> > Right, doing the chroot from within qemu avoids the issue with polluting
> > the target/. Thanks for the example.
> >
> > The chroot approach still suffers from the need of initially having higher
> > privileges. Personally, I still prefer the sysroot option and avoid that
> > need but either way helps me.
> >
> > Best regards
> 
> Which sysroot option?  (I may have missed a patch, I'm a month behind on the 
> list.  This is just something I've meant to submit for... about a year, I 
> think.)
> 
> You can also teach a bunch of different qemu syscalls (open, unlink, mmap, 
> exec, fcntl, and 3 dozen others...) to append a prefix to its path, and 
> perhaps try to prevent them from playing games with symlinks or ".." to break 
> out of that subdir.  But that's a much, much, much more extensive/intrusive 
> patch.

Hi,

This is the updated example from my local git of how it could work, it only 
maps absolute paths.
I don't think taking care of relative paths involves much more code but so far 
this behaviour has been enough for me.
The sim simulators in GDB have a similar --sysroot option which I beleive 
behaves very similar (or equal).

Please note that I'm not trying to jail in a program for security purposes, 
just for test and debug purposes.

My original post can be found here:
http://lists.gnu.org/archive/html/qemu-devel/2008-03/msg00027.html

Best regards
-- 
Edgar E. Iglesias
Axis Communications AB

diff --git a/linux-user/main.c b/linux-user/main.c
index 0079c7a..8190dbf 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1904,6 +1904,7 @@ void usage(void)
"-hprint this help\n"
"-g port   wait gdb connection to port\n"
"-L path   set the elf interpreter prefix (default=%s)\n"
+   "-sysroot  Root for system calls with absolute file-names\n"
"-s size   set the stack size in bytes (default=%ld)\n"
"-cpu modelselect CPU (-cpu ? for list)\n"
"-drop-ld-preload  drop LD_PRELOAD for target process\n"
@@ -1943,6 +1944,7 @@ int main(int argc, char **argv)
 int gdbstub_port = 0;
 int drop_ld_preload = 0, environ_count = 0;
 char **target_environ, **wrk, **dst;
+char *sysroot = NULL;
 
 if (argc <= 1)
 usage();
@@ -2014,6 +2016,8 @@ int main(int argc, char **argv)
 drop_ld_preload = 1;
 } else if (!strcmp(r, "strace")) {
 do_strace = 1;
+} else if (!strcmp(r, "sysroot")) {
+sysroot = argv[optind++];
 } else
 {
 usage();
@@ -2030,7 +2034,10 @@ int main(int argc, char **argv)
 memset(info, 0, sizeof(struct image_info));
 
 /* Scan interp_prefix dir for replacement files. */
-init_paths(interp_prefix);
+if (sysroot)
+init_paths(sysroot, 1);
+else
+init_paths(interp_prefix, 0);
 
 if (cpu_model == NULL) {
 #if defined(TARGET_I386)
diff --git a/linux-user/path.c b/linux-user/path.c
index 7da0a8b..5b6abc9 100644
--- a/linux-user/path.c
+++ b/linux-user/path.c
@@ -25,6 +25,8 @@ struct pathelem
 };
 
 static struct pathelem *base;
+static int use_sysroot;
+static size_t sysroot_pathlen;
 
 /* First N chars of S1 match S2, and S2 is N chars long. */
 static int strneq(const char *s1, unsigned int n, const char *s2)
@@ -118,7 +120,7 @@ follow_path(const struct pathelem *cursor, const char *name)
 return NULL;
 }
 
-void init_paths(const char *prefix)
+void init_paths(const char *prefix, int sysroot)
 {
 char pref_buf[PATH_MAX];
 
@@ -135,15 +137,25 @@ void init_paths(const char *prefix)
 strcat(pref_buf, prefix);
 free(cwd);
 } else
-strcpy(pref_buf,prefix + 1);
-
-base = new_entry("", NULL, pref_buf);
-base = add_dir_maybe(base);
-if (base->num_entries == 0) {
-free (base);
-base = NULL;
+  strcpy(pref_buf, prefix + 1);
+
+use_sysroot = sysroot;
+if (sysroot) {
+base = malloc(sizeof (*base));
+sysroot_pathlen = strlen(pref_buf);
+base->pathname = malloc(sysroot_pathlen + PATH_MAX + 1);
+base->pathname[0] = '/';
+memcpy(base->pathname + 1, pref_buf, sysroot_pathlen);
+sysroot_pathlen++;
 } else {
-set_parents(base, base);
+base = new_entry("", NULL, pref_buf);
+base = add_dir_maybe(base);
+if (base->num_entries == 0) {
+free (base);
+base = NULL;
+} else {
+set_parents(base, base);
+  

Re: [Qemu-devel] [PATCH] -chroot and -su options.

2008-03-04 Thread Rob Landley
On Tuesday 04 March 2008 05:22:12 you wrote:
> On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote:
> > Quick and dirty patch to teach qemu application emulation how to chroot
> > (and drop privs), so you don't have to pollute a target filesystem with
> > host code, and/or figure out how to build qemu static in order to run a
> > dynamic binary.
>
> Hi Rob,
>
> Right, doing the chroot from within qemu avoids the issue with polluting
> the target/. Thanks for the example.
>
> The chroot approach still suffers from the need of initially having higher
> privileges. Personally, I still prefer the sysroot option and avoid that
> need but either way helps me.
>
> Best regards

Which sysroot option?  (I may have missed a patch, I'm a month behind on the 
list.  This is just something I've meant to submit for... about a year, I 
think.)

You can also teach a bunch of different qemu syscalls (open, unlink, mmap, 
exec, fcntl, and 3 dozen others...) to append a prefix to its path, and 
perhaps try to prevent them from playing games with symlinks or ".." to break 
out of that subdir.  But that's a much, much, much more extensive/intrusive 
patch.

Rob
-- 
"One of my most productive days was throwing away 1000 lines of code."
  - Ken Thompson.




[Qemu-devel] [PATCH] Support redirect -curses over a character driver

2008-03-04 Thread Anthony Liguori
I love the -curses feature but I really wanted to use it over a telnet:
character device.  This patch enables this and changes the syntax of the
 -curses argument to take a character device.  'stdio' is special cased to not
go through a character device.  The rest use a pty to proxy the data to the
character device.  curses insists on a pty so we limit this feature to
everything but WIN32 since I don't believe Windows supports ptys.

Using this patch, you can now do something like '-curses telnet::1028,nowait'.
To get the old behavior, just use '-curses stdio'.

Signed-off-by: Anthony Liguori <[EMAIL PROTECTED]>

diff --git a/console.h b/console.h
index b8a5c6d..43e1284 100644
--- a/console.h
+++ b/console.h
@@ -141,7 +141,7 @@ int vnc_display_password(DisplayState *ds, const char 
*password);
 void do_info_vnc(void);
 
 /* curses.c */
-void curses_display_init(DisplayState *ds, int full_screen);
+void curses_display_init(DisplayState *ds, CharDriverState *chr, int 
full_screen);
 
 /* x_keymap.c */
 extern uint8_t _translate_keycode(const int key);
diff --git a/curses.c b/curses.c
index 87aa9b3..a020dd1 100644
--- a/curses.c
+++ b/curses.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #endif
 
 #define FONT_HEIGHT 16
@@ -41,6 +42,7 @@ static console_ch_t screen[160 * 100];
 static WINDOW *screenpad = NULL;
 static int width, height, gwidth, gheight, invalidate;
 static int px, py, sminx, sminy, smaxx, smaxy;
+static int slave;
 
 static void curses_update(DisplayState *ds, int x, int y, int w, int h)
 {
@@ -278,16 +280,102 @@ static void curses_atexit(void)
 curses_cleanup(NULL);
 }
 
-static void curses_setup(void)
+#ifndef _WIN32
+static void pty_read_proxy(void *opaque)
+{
+CharDriverState *chr = opaque;
+char buffer[4096];
+ssize_t len;
+
+do {
+   len = read(slave, buffer, sizeof(buffer));
+} while (len == -1 && errno == EINTR);
+
+if (len > 0)
+   qemu_chr_write(chr, buffer, len);
+}
+
+static void chr_read_proxy(void *opaque, const uint8_t *buf, int size)
+{
+ssize_t len;
+size_t offset = 0;
+
+do {
+   len = write(slave, buf + offset, size - offset);
+   if (len == -1 && (errno == EINTR || errno == EAGAIN))
+   continue;
+   if (len > 0)
+   offset += len;
+} while (offset < size && len > 0);
+
+if (offset != size)
+   fprintf(stderr, "curses: short write to slave pty\n");
+}
+
+static int chr_can_read_proxy(void *opaque)
+{
+return 1024;
+}
+
+static void chr_event_proxy(void *opaque, int event)
+{
+if (event == CHR_EVENT_RESET)
+   invalidate = 1;
+}
+#endif
+
+static void curses_setup(CharDriverState *chr)
 {
 int i, colour_default[8] = {
 COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN,
 COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE,
 };
 
+#ifndef _WIN32
+if (chr) {
+   struct termios term;
+   FILE *fin, *fout;
+   SCREEN *screen;
+   int master;
+
+   if (openpty(&master, &slave, NULL, NULL, NULL) == -1) {
+   fprintf(stderr, "fatal: could not open pty\n");
+   exit(1);
+   }
+
+   tcgetattr(master, &term);
+   cfmakeraw(&term);
+   tcsetattr(master, 0, &term);
+
+   tcgetattr(slave, &term);
+   cfmakeraw(&term);
+   tcsetattr(slave, 0, &term);
+
+   fout = fdopen(master, "w");
+   fin = fdopen(master, "r");
+
+   if (fout == NULL || fin == NULL) {
+   fprintf(stderr, "fatal: could not reopen pty\n");
+   exit(1);
+   }
+
+   qemu_set_fd_handler2(slave, NULL, pty_read_proxy, NULL, chr);
+   qemu_chr_add_handlers(chr, chr_can_read_proxy, chr_read_proxy,
+ chr_event_proxy, chr);
+
+   screen = newterm(getenv("TERM"), fout, fin);
+   set_term(screen);
+
+   /* we won't get resizes so we need to start out telling curses the
+  proper size */
+   resize_term(25, 80);
+} else
+#endif
+   initscr();
+
 /* input as raw as possible, let everything be interpreted
  * by the guest system */
-initscr(); noecho(); intrflush(stdscr, FALSE);
+noecho(); intrflush(stdscr, FALSE);
 nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
 start_color(); raw(); scrollok(stdscr, FALSE);
 
@@ -332,7 +420,7 @@ static void curses_keyboard_setup(void)
 }
 }
 
-void curses_display_init(DisplayState *ds, int full_screen)
+void curses_display_init(DisplayState *ds, CharDriverState *chr, int 
full_screen)
 {
 #ifndef _WIN32
 if (!isatty(1)) {
@@ -341,7 +429,7 @@ void curses_display_init(DisplayState *ds, int full_screen)
 }
 #endif
 
-curses_setup();
+curses_setup(chr);
 curses_keyboard_setup();
 atexit(curses_atexit);
 
diff --git a/vl.c b/vl.c
index d5a1dbc..16c9900 100644
--- a/vl.c
+++ b/vl.c
@@ -172,7 +172,6 @@ BlockDriverState *bs_snapshots;
 int vga_ram_size;
 static DisplayState display_state;
 int nographic;
-int curses;
 const char* keyboard_layout = 

[Qemu-devel] qemu/tcg tcg-op.h

2008-03-04 Thread Paul Brook
CVSROOT:/sources/qemu
Module name:qemu
Changes by: Paul Brook  08/03/04 23:52:48

Modified files:
tcg: tcg-op.h 

Log message:
32-bit host sign extension fix (Juergen Lock).

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/tcg/tcg-op.h?cvsroot=qemu&r1=1.7&r2=1.8




[Qemu-devel] patch: tcg bug (was: Re: qemu 2008-03-02 snapshot FreeBSD 7.0/amd64 guest regression) (tcg?)

2008-03-04 Thread Juergen Lock
On Mon, Mar 03, 2008 at 01:01:34AM +0100, Juergen Lock wrote:
> On Sun, Mar 02, 2008 at 09:47:02PM +0100, Juergen Lock wrote:
> > Hi!
> > 
> >  I've prepared a FreeBSD qemu-devel port update, as already mentioned
> > on the freebsd-emulation list, and found the FreeBSD 7.0/amd64 isos
> > now pagefault repeatedly, saying:
> > 
> > panic: page fault
> > cpuid = 0
> > kernel trap 12 with interrupts disabled
> > 
> > 
> > Fatal trap 12: page fault while in kernel mode
> > cpuid = 0; apic id = 00
> > fault virtual address   = 0x20
> > fault code  = supervisor read data, page not present
> > instruction pointer = 0x8:0x8046c704
> > trap number = 12
> > frame pointer   = 0x10:0x0
> > ...
> > 
> > 0x8046c704 in the 7.0-RELEASE kernel used on the isos is
> > in _thread_lock_flags:
> > 
> > (kgdb) disassemble _thread_lock_flags 
> > Dump of assembler code for function _thread_lock_flags:
> > 0x8046c6e0 <_thread_lock_flags+0>:  push   %r14
> > 0x8046c6e2 <_thread_lock_flags+2>:  mov%rdi,%r14
> > 0x8046c6e5 <_thread_lock_flags+5>:  push   %r13
> > 0x8046c6e7 <_thread_lock_flags+7>:  push   %r12
> > 0x8046c6e9 <_thread_lock_flags+9>:  push   %rbp
> > 0x8046c6ea <_thread_lock_flags+10>: push   %rbx
> > 0x8046c6eb <_thread_lock_flags+11>: mov%gs:0x0,%r13
> > 0x8046c6f4 <_thread_lock_flags+20>: xor%r12d,%r12d
> > 0x8046c6f7 <_thread_lock_flags+23>: callq  0x8071df80 
> > 
> > 0x8046c6fc <_thread_lock_flags+28>: mov(%r14),%rbp
> > 0x8046c6ff <_thread_lock_flags+31>: mov$0x4,%eax
> > 0x8046c704 <_thread_lock_flags+36>: lock cmpxchg %r13,0x20(%rbp)
> > 0x8046c70a <_thread_lock_flags+42>: sete   %al
> > 0x8046c70d <_thread_lock_flags+45>: test   %al,%al
> > 0x8046c70f <_thread_lock_flags+47>: jne0x8046c799 
> > <_thread_lock_flags+185>
> > 0x8046c715 <_thread_lock_flags+53>: mov0x20(%rbp),%rdx
> > 0x8046c719 <_thread_lock_flags+57>: cmp%r13,%rdx
> > 0x8046c71c <_thread_lock_flags+60>: je 0x8046c7cd 
> > <_thread_lock_flags+237>
> > 0x8046c722 <_thread_lock_flags+66>: callq  0x8071c4e0 
> > 
> > ---Type  to continue, or q  to quit---
> > 0x8046c727 <_thread_lock_flags+71>: jmp0x8046c73c 
> > <_thread_lock_flags+92>
> > 0x8046c729 <_thread_lock_flags+73>: data16
> > ...
> > 
> >  so this looks like either %rbp is indeed zero or that cmpxchg insn isnt
> > getting correctly translated.  If you want to reproduce just boot the 35 MB
> > 7.0-RELEASE-amd64-bootonly.iso in qemu-system-x86_64 (without kqemu); you
> > can find mirrors via
> > http://mirrorlist.freebsd.org/
> > (search for isos, amd64 architecture, I used 7.0 as you can see.)
> > 
> >  Oh, if you want to look at the live kernel you can boot the
> > 7.0-RELEASE-amd64-livefs.iso in 0.9.1 with the previously mentioned
> > patch (see
> > http://www.nabble.com/forum/ViewPost.jtp?post=14921171
> > ), select fixit->cdrom in the menu that comes up after choosing
> > the keyboard layout, and run `kgdb /dist/boot/kernel/kernel /dev/mem'.
> 
> Update: looks like the bug is i386 host only, at least I got a report
> of amd64 host working. (will try to confirm later...)

Ok, confirmed.  Tho the real problem was another fault that I must
have overlooked at first:  There's a movsbq at (in this kernel)
vm_phys_free_pages+4 that gets sign extended wrong, 1 gets turned into
0x10001 in %r8 at vm_phys_free_pages+9, which causes the offset into
vm_phys_segs (0x80a68340) to end up as 0x200020 instead of
0x20, causing the first fault at vm_phys_free_pages+43, which then only
seems to trigger the repeated faults mentioned above.

(kgdb) disassemble vm_phys_free_pages
Dump of assembler code for function vm_phys_free_pages:
0x80692ae0 :  push   %r12
0x80692ae2 :  push   %rbp
0x80692ae3 :  push   %rbx
0x80692ae4 :  movsbq 0x61(%rdi),%r8
0x80692ae9 :  mov%esi,%ebx
0x80692aeb : mov0x40(%rdi),%rbp
0x80692aef : shl$0x5,%r8
0x80692af3 : cmp$0xb,%esi
0x80692af6 : lea
0x80a68340(%r8),%r12
0x80692afd : jg 0x80692c4e 

0x80692b03 : lea0xc(%rbx),%ecx
0x80692b06 : mov$0x1,%eax
0x80692b0b : mov
0x80a68340(%r8),%rdx
0x80692b12 : shl%cl,%eax
0x80692b14 : cltq   
0x80692b16 : xor%rbp,%rax
0x80692b19 : cmp%rdx,%rax
...

 I'll attch the fix for qemu/tcg/tcg-op.h (the same bug was in the
movswq case).

 More interesting for the ppl reading -emulation might be a patch I applied
to kgdb, to be able to do `kgdb -r <32bit-box>:1234 kernel.debug' from the
amd64 box to talk to qemu -s -S (yeah I ended up using a debug kernel for
this

[Qemu-devel] qemu/hw sun4m.c

2008-03-04 Thread Blue Swirl
CVSROOT:/cvsroot/qemu
Module name:qemu
Changes by: Blue Swirl   08/03/04 20:29:59

Modified files:
hw : sun4m.c 

Log message:
 Show IRQ set or reset (Robert Reif)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/hw/sun4m.c?cvsroot=qemu&r1=1.86&r2=1.87




[Qemu-devel] qemu/hw slavio_timer.c

2008-03-04 Thread Blue Swirl
CVSROOT:/cvsroot/qemu
Module name:qemu
Changes by: Blue Swirl   08/03/04 20:29:03

Modified files:
hw : slavio_timer.c 

Log message:
 Remove unneeded qemu_irq_lower (Robert Reif)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/hw/slavio_timer.c?cvsroot=qemu&r1=1.30&r2=1.31




[Qemu-devel] qemu/target-sparc exec.h helper.h op.c op_helpe...

2008-03-04 Thread Blue Swirl
CVSROOT:/cvsroot/qemu
Module name:qemu
Changes by: Blue Swirl   08/03/04 20:00:18

Modified files:
target-sparc   : exec.h helper.h op.c op_helper.c translate.c 

Log message:
 Convert float helpers to TCG, fix fabsq in the process

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sparc/exec.h?cvsroot=qemu&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sparc/helper.h?cvsroot=qemu&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sparc/op.c?cvsroot=qemu&r1=1.51&r2=1.52
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sparc/op_helper.c?cvsroot=qemu&r1=1.67&r2=1.68
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sparc/translate.c?cvsroot=qemu&r1=1.94&r2=1.95




[Qemu-devel] qemu/target-sparc translate.c

2008-03-04 Thread Blue Swirl
CVSROOT:/cvsroot/qemu
Module name:qemu
Changes by: Blue Swirl   08/03/04 19:56:06

Modified files:
target-sparc   : translate.c 

Log message:
 Convert fmovr to TCG

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sparc/translate.c?cvsroot=qemu&r1=1.93&r2=1.94




Re: [Qemu-devel] [PATCH] -chroot and -su options.

2008-03-04 Thread Edgar E. Iglesias
On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote:
> Quick and dirty patch to teach qemu application emulation how to chroot (and
> drop privs), so you don't have to pollute a target filesystem with host code,
> and/or figure out how to build qemu static in order to run a dynamic binary.

Hi Rob,

Right, doing the chroot from within qemu avoids the issue with polluting the 
target/. Thanks for the example.
 
The chroot approach still suffers from the need of initially having higher 
privileges. Personally, I still prefer the sysroot option and avoid that need 
but either way helps me.

Best regards
-- 
Edgar E. Iglesias
Axis Communications AB