From: Jeff Dike <jdike@addtoit.com>
To: Zach Brown <zach.brown@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>, Chris Mason <chris.mason@oracle.com>,
LKML <linux-kernel@vger.kernel.org>,
uml-devel <user-mode-linux-devel@lists.sourceforge.net>
Subject: Re: [uml-devel] [PATCH] Syslets - Fix cachemiss_thread return value
Date: Fri, 8 Jun 2007 12:10:48 -0400 [thread overview]
Message-ID: <20070608161048.GA8147@c2.user-mode-linux.org> (raw)
In-Reply-To: <20070607232733.GM17082@mami.zabbo.net>
On Thu, Jun 07, 2007 at 04:27:33PM -0700, Zach Brown wrote:
> On Thu, May 31, 2007 at 02:19:23PM -0400, Jeff Dike wrote:
> > cachemiss_thread should explicitly return 0 or error instead of
> > task_ret_reg(current) (which is -ENOSYS anyway) because
> > async_thread_helper is careful to put the return value in eax anyway.
>
> Here's the fix I came up with for this. Untested (my test boxes are
> busy doing some aio+syslet perf runs :)). What do you guys think?
I don't like it :-)
It's better though. With the test below (a hacked up version of
aio-read.c), I still get -ENOSYS leaking out of sys_async_exec when it
tries an async setuid.
I haven't started looking into this yet.
Jeff
--
Work email - jdike at linux dot intel dot com
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include "sys.h"
/*
* Set up a syslet atom:
*/
static void
init_atom(struct syslet_uatom *atom, int nr,
void *arg_ptr0, void *arg_ptr1, void *arg_ptr2,
void *arg_ptr3, void *arg_ptr4, void *arg_ptr5,
void *ret_ptr, unsigned long flags, struct syslet_uatom *next)
{
atom->nr = nr;
atom->arg_ptr[0] = (u64)(unsigned long)arg_ptr0;
atom->arg_ptr[1] = (u64)(unsigned long)arg_ptr1;
atom->arg_ptr[2] = (u64)(unsigned long)arg_ptr2;
atom->arg_ptr[3] = (u64)(unsigned long)arg_ptr3;
atom->arg_ptr[4] = (u64)(unsigned long)arg_ptr4;
atom->arg_ptr[5] = (u64)(unsigned long)arg_ptr5;
atom->ret_ptr = (u64)(unsigned long)ret_ptr;
atom->flags = flags;
atom->next = (u64)(unsigned long)next;
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
static int collect_status(void)
{
int n = 0;
sys_async_wait(1, async_head.user_ring_idx, &async_head);
while(completion_ring[async_head.user_ring_idx] != 0){
completion_ring[async_head.user_ring_idx++] = 0;
async_head.user_ring_idx %= ARRAY_SIZE(completion_ring);
n++;
}
return n;
}
int oneshot(struct syslet_uatom *atom, int syscall)
{
struct syslet_uatom *done;
int err = -1;
init_atom(atom, __NR_getuid, NULL, NULL, NULL, NULL, NULL, NULL,
&err, SYSLET_ASYNC, NULL);
if(async_head.new_thread_stack == 0)
async_head.new_thread_stack = thread_stack_alloc();
done = sys_async_exec(atom, &async_head);
if(done == atom)
printf("setuid was synchronous\n");
else if(done == NULL){
collect_status();
}
else {
perror("async setuid");
exit(1);
}
return err;
}
int main(int argc, char *argv[])
{
struct syslet_uatom *atoms, *done;
struct stat stbuf;
char *file, *buf;
int fd, err, npages, i, len, async, sync;
if(argc < 2){
fprintf(stderr, "Usage : aio-read file\n");
exit(1);
}
file = argv[1];
fd = open(file, O_RDONLY);
if(fd < 0){
perror("open");
exit(1);
}
err = fstat(fd, &stbuf);
if(err < 0){
perror("stat");
exit(1);
}
buf = malloc(stbuf.st_size);
if(buf == NULL){
perror("malloc");
exit(1);
}
len = getpagesize();
npages = (stbuf.st_size + len - 1) / len;
atoms = malloc(npages * sizeof(struct syslet_uatom));
if(atoms == NULL){
perror("malloc atoms");
exit(1);
}
async_head_init();
async = 0;
sync = 0;
printf("head pid = %d, uid = %d\n", getpid(), getuid());
for(i = 0; i < npages; i++){
char *ptr = &buf[i * len];
init_atom(&atoms[i], __NR_sys_read, &fd, &ptr, &len,
NULL, NULL, NULL, NULL, 0, NULL);
if(async_head.new_thread_stack == 0)
async_head.new_thread_stack = thread_stack_alloc();
done = sys_async_exec(&atoms[i], &async_head);
if(done == &atoms[i]){
sync++;
continue;
}
else if(done < 0)
perror("sys_async_exec");
async++;
printf("async = %d, pid = %ld\n", async, syscall(__NR_gettid));
if(async < ARRAY_SIZE(completion_ring))
continue;
async -= collect_status();
}
while(async)
async -= collect_status();
if(setuid(500) < 0){
perror("setuid");
exit(1);
}
err = oneshot(&atoms[0], __NR_getuid);
printf("uid1 = %d\n", err);
printf("current uid1 = %d\n", getuid());
err = oneshot(&atoms[0], __NR_getuid);
printf("uid2 = %d\n", err);
printf("current uid2 = %d\n", getuid());
err = oneshot(&atoms[0], __NR_getuid);
printf("uid3 = %d\n", err);
printf("current uid3 = %d\n", getuid());
pause();
return 0;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
WARNING: multiple messages have this Message-ID (diff)
From: Jeff Dike <jdike@addtoit.com>
To: Zach Brown <zach.brown@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>, LKML <linux-kernel@vger.kernel.org>,
uml-devel <user-mode-linux-devel@lists.sourceforge.net>,
Chris Mason <chris.mason@oracle.com>
Subject: Re: [PATCH] Syslets - Fix cachemiss_thread return value
Date: Fri, 8 Jun 2007 12:10:48 -0400 [thread overview]
Message-ID: <20070608161048.GA8147@c2.user-mode-linux.org> (raw)
In-Reply-To: <20070607232733.GM17082@mami.zabbo.net>
On Thu, Jun 07, 2007 at 04:27:33PM -0700, Zach Brown wrote:
> On Thu, May 31, 2007 at 02:19:23PM -0400, Jeff Dike wrote:
> > cachemiss_thread should explicitly return 0 or error instead of
> > task_ret_reg(current) (which is -ENOSYS anyway) because
> > async_thread_helper is careful to put the return value in eax anyway.
>
> Here's the fix I came up with for this. Untested (my test boxes are
> busy doing some aio+syslet perf runs :)). What do you guys think?
I don't like it :-)
It's better though. With the test below (a hacked up version of
aio-read.c), I still get -ENOSYS leaking out of sys_async_exec when it
tries an async setuid.
I haven't started looking into this yet.
Jeff
--
Work email - jdike at linux dot intel dot com
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include "sys.h"
/*
* Set up a syslet atom:
*/
static void
init_atom(struct syslet_uatom *atom, int nr,
void *arg_ptr0, void *arg_ptr1, void *arg_ptr2,
void *arg_ptr3, void *arg_ptr4, void *arg_ptr5,
void *ret_ptr, unsigned long flags, struct syslet_uatom *next)
{
atom->nr = nr;
atom->arg_ptr[0] = (u64)(unsigned long)arg_ptr0;
atom->arg_ptr[1] = (u64)(unsigned long)arg_ptr1;
atom->arg_ptr[2] = (u64)(unsigned long)arg_ptr2;
atom->arg_ptr[3] = (u64)(unsigned long)arg_ptr3;
atom->arg_ptr[4] = (u64)(unsigned long)arg_ptr4;
atom->arg_ptr[5] = (u64)(unsigned long)arg_ptr5;
atom->ret_ptr = (u64)(unsigned long)ret_ptr;
atom->flags = flags;
atom->next = (u64)(unsigned long)next;
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
static int collect_status(void)
{
int n = 0;
sys_async_wait(1, async_head.user_ring_idx, &async_head);
while(completion_ring[async_head.user_ring_idx] != 0){
completion_ring[async_head.user_ring_idx++] = 0;
async_head.user_ring_idx %= ARRAY_SIZE(completion_ring);
n++;
}
return n;
}
int oneshot(struct syslet_uatom *atom, int syscall)
{
struct syslet_uatom *done;
int err = -1;
init_atom(atom, __NR_getuid, NULL, NULL, NULL, NULL, NULL, NULL,
&err, SYSLET_ASYNC, NULL);
if(async_head.new_thread_stack == 0)
async_head.new_thread_stack = thread_stack_alloc();
done = sys_async_exec(atom, &async_head);
if(done == atom)
printf("setuid was synchronous\n");
else if(done == NULL){
collect_status();
}
else {
perror("async setuid");
exit(1);
}
return err;
}
int main(int argc, char *argv[])
{
struct syslet_uatom *atoms, *done;
struct stat stbuf;
char *file, *buf;
int fd, err, npages, i, len, async, sync;
if(argc < 2){
fprintf(stderr, "Usage : aio-read file\n");
exit(1);
}
file = argv[1];
fd = open(file, O_RDONLY);
if(fd < 0){
perror("open");
exit(1);
}
err = fstat(fd, &stbuf);
if(err < 0){
perror("stat");
exit(1);
}
buf = malloc(stbuf.st_size);
if(buf == NULL){
perror("malloc");
exit(1);
}
len = getpagesize();
npages = (stbuf.st_size + len - 1) / len;
atoms = malloc(npages * sizeof(struct syslet_uatom));
if(atoms == NULL){
perror("malloc atoms");
exit(1);
}
async_head_init();
async = 0;
sync = 0;
printf("head pid = %d, uid = %d\n", getpid(), getuid());
for(i = 0; i < npages; i++){
char *ptr = &buf[i * len];
init_atom(&atoms[i], __NR_sys_read, &fd, &ptr, &len,
NULL, NULL, NULL, NULL, 0, NULL);
if(async_head.new_thread_stack == 0)
async_head.new_thread_stack = thread_stack_alloc();
done = sys_async_exec(&atoms[i], &async_head);
if(done == &atoms[i]){
sync++;
continue;
}
else if(done < 0)
perror("sys_async_exec");
async++;
printf("async = %d, pid = %ld\n", async, syscall(__NR_gettid));
if(async < ARRAY_SIZE(completion_ring))
continue;
async -= collect_status();
}
while(async)
async -= collect_status();
if(setuid(500) < 0){
perror("setuid");
exit(1);
}
err = oneshot(&atoms[0], __NR_getuid);
printf("uid1 = %d\n", err);
printf("current uid1 = %d\n", getuid());
err = oneshot(&atoms[0], __NR_getuid);
printf("uid2 = %d\n", err);
printf("current uid2 = %d\n", getuid());
err = oneshot(&atoms[0], __NR_getuid);
printf("uid3 = %d\n", err);
printf("current uid3 = %d\n", getuid());
pause();
return 0;
}
next prev parent reply other threads:[~2007-06-08 16:11 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-31 18:19 [uml-devel] [PATCH] Syslets - Fix cachemiss_thread return value Jeff Dike
2007-05-31 18:19 ` Jeff Dike
2007-05-31 20:09 ` [uml-devel] " Ingo Molnar
2007-05-31 20:09 ` Ingo Molnar
2007-05-31 22:07 ` [uml-devel] " Zach Brown
2007-05-31 22:07 ` Zach Brown
2007-05-31 23:39 ` [uml-devel] " Jeff Dike
2007-05-31 23:39 ` Jeff Dike
2007-06-01 0:00 ` [uml-devel] " Zach Brown
2007-06-01 0:00 ` Zach Brown
2007-06-07 23:27 ` [uml-devel] " Zach Brown
2007-06-07 23:27 ` Zach Brown
2007-06-08 16:10 ` Jeff Dike [this message]
2007-06-08 16:10 ` Jeff Dike
2007-06-08 16:26 ` [uml-devel] " Zach Brown
2007-06-08 16:26 ` Zach Brown
2007-06-08 16:33 ` [uml-devel] " Jeff Dike
2007-06-08 16:33 ` Jeff Dike
2007-06-08 16:46 ` [uml-devel] " Zach Brown
2007-06-08 16:46 ` Zach Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070608161048.GA8147@c2.user-mode-linux.org \
--to=jdike@addtoit.com \
--cc=chris.mason@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=user-mode-linux-devel@lists.sourceforge.net \
--cc=zach.brown@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.