Commit 6f55b4b6 authored by Yathindra Naik's avatar Yathindra Naik

Debugging continues...

- cap grant has 2 arrays. One is for hypercalls, second is for other purpose.
- for hypercalls, I pass an index to cap_grant. But for xenstore I'm passing a list of caps.
- For some reason, guest domain cannot read console from xenstore. Need to see this.
parent fcae6417
......@@ -396,7 +396,7 @@ static struct node *read_node(struct connection *conn, const char *name)
talloc_steal(node, data.dptr);
#ifdef CONFIG_XENCAP
//if ( conn != NULL && domain_is_cap(conn) ) {
if ( conn != NULL && conn->cap_flag ) {
/* Datalen, childlen, number of permissions */
p = (uint32_t *)data.dptr;
node->num_perms = p[0];
......@@ -414,8 +414,7 @@ static struct node *read_node(struct connection *conn, const char *name)
node->children = node->data + node->datalen;
log("read_node: node->name %s, node->num_caps %d, node->num_perms %d, node->data %s\n",
node->name, node->num_caps,node->num_perms,(char*)node->data);
// }
#if 0
}
else
{
/* Datalen, childlen, number of permissions */
......@@ -431,7 +430,6 @@ static struct node *read_node(struct connection *conn, const char *name)
/* Children is strings, nul separated. */
node->children = node->data + node->datalen;
}
#endif
#endif
log("read_node: %s returning node %p\n",name, node);
return node;
......@@ -452,7 +450,7 @@ static bool write_node(struct connection *conn, const struct node *node)
log("write_node: %s\n",node->name);
#ifdef CONFIG_XENCAP
// if (conn != NULL && domain_is_cap(conn)) {
if (conn != NULL && conn->cap_flag) {
// log("write_node: node->num_caps %d, size %ld\n",node->num_caps, sizeof(node->caps[0]));
data.dsize = 4*sizeof(uint32_t)
......@@ -474,10 +472,9 @@ static bool write_node(struct connection *conn, const struct node *node)
memcpy(p, node->data, node->datalen);
p += node->datalen;
memcpy(p, node->children, node->childlen);
// }
#if 0
//else {
log("write_node: Domain not in cap_mode.\n");
}
else
{
data.dsize = 3*sizeof(uint32_t)
+ node->num_perms*sizeof(node->perms[0])
+ node->datalen + node->childlen;
......@@ -494,8 +491,7 @@ static bool write_node(struct connection *conn, const struct node *node)
p += node->datalen;
memcpy(p, node->children, node->childlen);
// }
#endif
}
#endif
if (domain_is_unprivileged(conn) && data.dsize >= quota_max_entry_size)
{
......@@ -537,8 +533,10 @@ static int caps_for_conn(struct connection *conn,
/* Owners and tools get it all... */
/* still need to identify the owners correctly .. */
if (!domain_is_unprivileged(conn))
if (!domain_is_unprivileged(conn)) {
xc_interface_close(xch);
return ret;
}
switch(perm)
{
......@@ -579,6 +577,8 @@ static int caps_for_conn(struct connection *conn,
default:
ret = 0;
}
xc_interface_close(xch);
return ret;
}
#endif
......@@ -632,6 +632,7 @@ static enum xs_perm_type ask_parents(struct connection *conn, const char *name)
/* No permission at root? We're in trouble. */
if (!node)
corrupt(conn, "No permissions file at root");
#ifdef CONFIG_XENCAP
if ( conn != NULL && conn->cap_flag ) {
log("checking read cap\n");
......@@ -681,7 +682,6 @@ struct node *get_node(struct connection *conn,
log("get_node: node->name %s node %p\n",name,node);
#ifdef CONFIG_XENCAP
if ( conn != NULL && conn->cap_flag ) {
//xprintf("get_node: \n node->caps: \n perm_type: %d \nread_cap 0x%x\nwrite_cap 0x%x\n",node->caps[0],node->caps[1],perm);
if (node) {
if (!caps_for_conn(conn, node->caps, perm)) {
errno = EACCES;
......@@ -879,7 +879,7 @@ bool xs_strings_to_caps(unsigned int num, struct capability *caps, const char *s
unsigned int i;
xc_interface *xch;
int owner_domid,to_domid;
int list[2] = {-1,-1};
struct capability list[2];
int flag = 0;
/* I'm guessing we need to handle two cases here.
......@@ -891,7 +891,7 @@ bool xs_strings_to_caps(unsigned int num, struct capability *caps, const char *s
if(xch == 0)
{
log("xs_strings_to_caps: xc_interface_open failed to get xc_handle!\n");
return false;
goto out;
}
/* First, identify the owner domain and
......@@ -907,49 +907,47 @@ bool xs_strings_to_caps(unsigned int num, struct capability *caps, const char *s
if ( caps == NULL )
{
log("xs_strings_to_caps: caps is NULL!\n");
return false;
goto out;
}
if (xc_cap_create(xch, owner_domid, &caps[0]))
{
xc_interface_close(xch);
log("xs_strings_to_caps: Error in xc_cap_create.\n");
return false;
goto out;
}
if (xc_cap_create(xch, owner_domid, &caps[1]))
{
xc_interface_close(xch);
log("xs_strings_to_caps: Error in xc_cap_create.\n");
return false;
goto out;
}
for (p = end+1, i = 1; i < num; i++) {
/* "r", "w", or "b" for both. */
switch (*p) {
case 'r':
list[0] = 0;
list[0] = caps[0];
flag = 1;
break;
case 'w':
list[0] = 1;
list[0] = caps[1];
flag = 1;
break;
case 'b':
list[0] = 0;
list[1] = 1;
list[0] = caps[0];
list[1] = caps[1];
break;
case 'n':
break;
default:
errno = EINVAL;
return false;
goto out;
}
p++;
to_domid = strtol(p, &end, 0);
if (*end || !*p) {
errno = EINVAL;
return false;
goto out;
}
if (flag)
......@@ -958,9 +956,8 @@ bool xs_strings_to_caps(unsigned int num, struct capability *caps, const char *s
/* Read or Write Caps */
if ((xc_cap_grant(xch,owner_domid,to_domid,2,&list,1)) == 1)
{
xc_interface_close(xch);
log("xs_strings_to_caps: Error in xc_cap_grant.\n");
return false;
goto out;
}
}
else
......@@ -969,15 +966,18 @@ bool xs_strings_to_caps(unsigned int num, struct capability *caps, const char *s
/* Both the flags */
if ((xc_cap_grant(xch,owner_domid,to_domid,2,&list,2)) == 1)
{
xc_interface_close(xch);
log("xs_strings_to_caps: Error in xc_cap_grant.\n");
return false;
goto out;
}
}
p = end + 1;
}
xc_interface_close(xch);
return true;
out:
xc_interface_close(xch);
return false;
}
#endif
......@@ -1082,7 +1082,7 @@ static struct node *construct_node(struct connection *conn, const char *name)
xc_interface *xch;
#ifdef CONFIG_XENCAP
// int domid = get_domid(conn);
int domid = get_domid(conn);
xch = xc_interface_open(0,0,0);
if(xch == 0)
......@@ -1097,10 +1097,18 @@ static struct node *construct_node(struct connection *conn, const char *name)
if (!parent)
parent = construct_node(conn, parentname);
if (!parent)
#ifdef CONFIG_XENCAP
goto out;
#else
return NULL;
#endif
if (domain_entry(conn) >= quota_nb_entry_per_domain)
#ifdef CONFIG_XENCAP
goto out;
#else
return NULL;
#endif
/* Add child to parent. */
base = basename(name);
......@@ -1121,26 +1129,21 @@ static struct node *construct_node(struct connection *conn, const char *name)
node->perms = talloc_memdup(node, parent->perms,
node->num_perms * sizeof(node->perms[0]));
#ifdef CONFIG_XENCAP
//node->num_caps = parent->num_caps;
//node->caps = talloc_memdup(node, parent->caps,
// node->num_caps * sizeof(node->caps[0]));
/* We need to init this later. */
node->num_caps = 2;
node->caps = talloc_array(node, struct capability, 2);
// if ( domid != -1 )
if ( domid != -1 && conn->cap_flag == 1 )
{
log("construct_node: Creating read/write caps for conn id: %d\n",conn->id);
node->num_caps = 2;
node->caps = talloc_array(node, struct capability, 2);
log("construct_node: Creating read/write caps for domid id: %d\n",domid);
if (xc_cap_create(xch, conn->id, &node->caps[0]))
if (xc_cap_create(xch, domid, &node->caps[0]))
{
xc_interface_close(xch);
log("construct_node: Error in xc_cap_create.\n");
// should return err
}
if (xc_cap_create(xch, conn->id, &node->caps[1]))
if (xc_cap_create(xch, domid, &node->caps[1]))
{
xc_interface_close(xch);
log("construct_node: Error in xc_cap_create.\n");
......@@ -1158,6 +1161,11 @@ static struct node *construct_node(struct connection *conn, const char *name)
domain_entry_inc(conn, node);
log("construct_node: returning node %p\n",node);
return node;
#ifdef CONFIG_XENCAP
out:
xc_interface_close(xch);
return NULL;
#endif
}
static int destroy_node(void *_node)
......@@ -1492,6 +1500,7 @@ static void do_get_perms(struct connection *conn, const char *name)
if ( conn != NULL && conn->cap_flag )
{
//strings = caps_to_strings(node, &len);
log("do_get_perms: domain is in capability mode! Cannot ask the caps!\n");
errno = EACCES;
send_error(conn, errno);
}
......@@ -1557,7 +1566,9 @@ static void do_set_perms(struct connection *conn, struct buffered_data *in)
}
xc_interface_close(xch);
return;
/* Note: Understand this why they do this ! */
domain_entry_dec(conn, node);
domain_entry_inc(conn, node);
}
else
{
......@@ -1820,7 +1831,11 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
/* Note: The problem here is to identify if this connection
is a part of the same transaction started by a domain
which is in cap mode. */
new->cap_flag = 1;
/* Heres a thought: Since these connections mostly don't have
any domain associated with it, lets simply grant them acess
to nodes ? */
new->cap_flag = 0;
#endif
INIT_LIST_HEAD(&new->out_list);
INIT_LIST_HEAD(&new->watches);
......@@ -1912,6 +1927,7 @@ static void manual_node(const char *name, const char *child)
node->perms = &perms;
node->num_perms = 1;
#ifdef CONFIG_XENCAP
/* Not sure about this */
node->caps = NULL;
node->num_caps = 0;
#endif
......@@ -2454,11 +2470,9 @@ int main(int argc, char *argv[])
}
}
log("xenstored after init'ing all connections\n");
max = initialize_set(&inset, &outset, *sock, *ro_sock,
&timeout);
}
log("xenstored is out of main loop\n");
}
/*
......
......@@ -182,18 +182,81 @@ int cap_create(struct domain *d, struct capability *cap)
}
/*
* Check if the domain has the required capability.
*/
int cap_check(struct domain *d, int type, struct capability *cap)
{
int i;
int ret = 0;
if ( IS_PRIV(d) )
return 1;
if ( d->domain_id < 0 || d->domain_id > 100 )
return 1;
switch(type)
{
case 1:
/* capability is a random number. */
for ( i = 0; i < NUM_HYPERCALLS; ++i )
{
if ( d->cap_space->cap_hypercalls[i].magic == cap->magic )
return 1; /* Found */
}
break;
case 2:
/* capability is a random number. */
for ( i = 0; i < NUM_CAPS; ++i )
{
if ( d->cap_space->caps[i].magic == cap->magic )
return 1; /* Found */
}
break;
}
return ret; /* Not found */
}
/*
* Grant a list of capabilities from source domain to destination domain.
*/
int cap_grant(struct domain *from, struct domain *to, int type, void *list, int size)
{
int i, index;
int *ptr = (int*)list;
int i, index, num_caps;
int ret = 0; /* success */
int *ptr = NULL;
struct capability *cap_ptr = NULL;
if ( type == 1 )
ptr = (int*)list;
if ( type == 2 )
cap_ptr = (struct capability *)list;
if ( to->cap_space != NULL )
num_caps = to->cap_space->num_caps;
else
{
TT_DBG("Domain: %d cap_space not init'ed\n",to->domain_id);
return 1;
}
TT_DBG("In cap_grant()\n");
if(from == NULL || to == NULL)
return 1;
{
TT_DBG("Domain struct is NULL\n");
return 1;
}
if ( type != 1 && type != 2 )
{
TT_DBG("Type is invalid\n");
return 1;
}
switch(type)
{
......@@ -214,52 +277,23 @@ int cap_grant(struct domain *from, struct domain *to, int type, void *list, int
/* General */
for ( i = 0; i < size; ++i )
{
index = ptr[i];
printk("cap_grant_gen: index=%d, i=%d\n",index,i);
if(index == -1)
continue;
to->cap_space->caps[index] = from->cap_space->caps[index];
TT_DBG("Granting Capability: Domain %d, Capability: 0x%x\n",to->domain_id, from->cap_space->caps[index].magic);
if ( cap_check(from,2,&cap_ptr[i]) )
{
to->cap_space->caps[num_caps] = cap_ptr[i];
to->cap_space->num_caps++;
TT_DBG("Granting Capability: Domain %d, Capability: 0x%x\n",to->domain_id, cap_ptr[i].magic);
}
else
{
TT_DBG("Granting Capability failed since cap_check failed for domain: %d\n", from->domain_id);
ret = 1;
}
}
break;
}
return 0;
}
/*
* Check if the domain has the required capability.
*/
int cap_check(struct domain *d, int type, struct capability *cap)
{
int i;
int ret = 0;
if ( IS_PRIV(d) )
return 1;
if ( d->domain_id < 0 || d->domain_id > 100 )
return 1;
// TT_DBG("In cap_check()\n");
// TT_DBG("Checking Capability: Domain %d, Cap_id: 0x%x\n",d->domain_id, cap->magic);
switch(type)
{
case 1:
/* capability is a random number. */
for ( i = 0; i < NUM_HYPERCALLS; ++i )
{
if ( d->cap_space->cap_hypercalls[i].magic == cap->magic )
return 1; /* Found */
}
break;
}
return ret; /* Not found */
return ret;
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment