Re: [Qemu-devel] [PATCH] -chroot and -su options.
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.
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
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
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?)
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
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
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...
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
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.
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