aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/lguest/lguest.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2009-06-13 00:26:58 -0400
committerRusty Russell <rusty@rustcorp.com.au>2009-06-12 08:56:59 -0400
commit713b15b3781240653d2b38414da3f4567dcbcf91 (patch)
tree9b6a01f00bf4aee60548d8b8cf38458863888564 /Documentation/lguest/lguest.c
parent8ebf975608aaebd7feb33d77f07ba21a6380e086 (diff)
lguest: be paranoid about guest playing with device descriptors.
We can't trust the values in the device descriptor table once the guest has booted, so keep local copies. They could set them to strange values then cause us to segv (they're 8 bit values, so they can't make our pointers go too wild). This becomes more important with the following patches which read them. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r--Documentation/lguest/lguest.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index d36fcc0f2715..e65d6cbf2419 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -126,9 +126,13 @@ struct device
126 /* The linked-list pointer. */ 126 /* The linked-list pointer. */
127 struct device *next; 127 struct device *next;
128 128
129 /* The this device's descriptor, as mapped into the Guest. */ 129 /* The device's descriptor, as mapped into the Guest. */
130 struct lguest_device_desc *desc; 130 struct lguest_device_desc *desc;
131 131
132 /* We can't trust desc values once Guest has booted: we use these. */
133 unsigned int feature_len;
134 unsigned int num_vq;
135
132 /* The name of this device, for --verbose. */ 136 /* The name of this device, for --verbose. */
133 const char *name; 137 const char *name;
134 138
@@ -245,7 +249,7 @@ static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len)
245static u8 *get_feature_bits(struct device *dev) 249static u8 *get_feature_bits(struct device *dev)
246{ 250{
247 return (u8 *)(dev->desc + 1) 251 return (u8 *)(dev->desc + 1)
248 + dev->desc->num_vq * sizeof(struct lguest_vqconfig); 252 + dev->num_vq * sizeof(struct lguest_vqconfig);
249} 253}
250 254
251/*L:100 The Launcher code itself takes us out into userspace, that scary place 255/*L:100 The Launcher code itself takes us out into userspace, that scary place
@@ -979,8 +983,8 @@ static void update_device_status(struct device *dev)
979 verbose("Resetting device %s\n", dev->name); 983 verbose("Resetting device %s\n", dev->name);
980 984
981 /* Clear any features they've acked. */ 985 /* Clear any features they've acked. */
982 memset(get_feature_bits(dev) + dev->desc->feature_len, 0, 986 memset(get_feature_bits(dev) + dev->feature_len, 0,
983 dev->desc->feature_len); 987 dev->feature_len);
984 988
985 /* Zero out the virtqueues. */ 989 /* Zero out the virtqueues. */
986 for (vq = dev->vq; vq; vq = vq->next) { 990 for (vq = dev->vq; vq; vq = vq->next) {
@@ -994,12 +998,12 @@ static void update_device_status(struct device *dev)
994 unsigned int i; 998 unsigned int i;
995 999
996 verbose("Device %s OK: offered", dev->name); 1000 verbose("Device %s OK: offered", dev->name);
997 for (i = 0; i < dev->desc->feature_len; i++) 1001 for (i = 0; i < dev->feature_len; i++)
998 verbose(" %02x", get_feature_bits(dev)[i]); 1002 verbose(" %02x", get_feature_bits(dev)[i]);
999 verbose(", accepted"); 1003 verbose(", accepted");
1000 for (i = 0; i < dev->desc->feature_len; i++) 1004 for (i = 0; i < dev->feature_len; i++)
1001 verbose(" %02x", get_feature_bits(dev) 1005 verbose(" %02x", get_feature_bits(dev)
1002 [dev->desc->feature_len+i]); 1006 [dev->feature_len+i]);
1003 1007
1004 if (dev->ready) 1008 if (dev->ready)
1005 dev->ready(dev); 1009 dev->ready(dev);
@@ -1129,8 +1133,8 @@ static void handle_input(int fd)
1129static u8 *device_config(const struct device *dev) 1133static u8 *device_config(const struct device *dev)
1130{ 1134{
1131 return (void *)(dev->desc + 1) 1135 return (void *)(dev->desc + 1)
1132 + dev->desc->num_vq * sizeof(struct lguest_vqconfig) 1136 + dev->num_vq * sizeof(struct lguest_vqconfig)
1133 + dev->desc->feature_len * 2; 1137 + dev->feature_len * 2;
1134} 1138}
1135 1139
1136/* This routine allocates a new "struct lguest_device_desc" from descriptor 1140/* This routine allocates a new "struct lguest_device_desc" from descriptor
@@ -1191,6 +1195,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
1191 * yet, otherwise we'd be overwriting them. */ 1195 * yet, otherwise we'd be overwriting them. */
1192 assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0); 1196 assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0);
1193 memcpy(device_config(dev), &vq->config, sizeof(vq->config)); 1197 memcpy(device_config(dev), &vq->config, sizeof(vq->config));
1198 dev->num_vq++;
1194 dev->desc->num_vq++; 1199 dev->desc->num_vq++;
1195 1200
1196 verbose("Virtqueue page %#lx\n", to_guest_phys(p)); 1201 verbose("Virtqueue page %#lx\n", to_guest_phys(p));
@@ -1219,7 +1224,7 @@ static void add_feature(struct device *dev, unsigned bit)
1219 /* We can't extend the feature bits once we've added config bytes */ 1224 /* We can't extend the feature bits once we've added config bytes */
1220 if (dev->desc->feature_len <= bit / CHAR_BIT) { 1225 if (dev->desc->feature_len <= bit / CHAR_BIT) {
1221 assert(dev->desc->config_len == 0); 1226 assert(dev->desc->config_len == 0);
1222 dev->desc->feature_len = (bit / CHAR_BIT) + 1; 1227 dev->feature_len = dev->desc->feature_len = (bit/CHAR_BIT) + 1;
1223 } 1228 }
1224 1229
1225 features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT)); 1230 features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT));
@@ -1259,6 +1264,8 @@ static struct device *new_device(const char *name, u16 type, int fd,
1259 dev->name = name; 1264 dev->name = name;
1260 dev->vq = NULL; 1265 dev->vq = NULL;
1261 dev->ready = NULL; 1266 dev->ready = NULL;
1267 dev->feature_len = 0;
1268 dev->num_vq = 0;
1262 1269
1263 /* Append to device list. Prepending to a single-linked list is 1270 /* Append to device list. Prepending to a single-linked list is
1264 * easier, but the user expects the devices to be arranged on the bus 1271 * easier, but the user expects the devices to be arranged on the bus