diff -NurpP linux-2.6.17.7-vs2.1.1-rc27.7/drivers/block/loop.c linux-2.6.17.7-vs2.1.1-rc28/drivers/block/loop.c --- linux-2.6.17.7-vs2.1.1-rc27.7/drivers/block/loop.c 2006-07-29 01:36:13 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28/drivers/block/loop.c 2006-08-04 19:59:58 +0200 @@ -819,6 +819,7 @@ static int loop_set_fd(struct loop_devic lo->lo_blocksize = lo_blocksize; lo->lo_device = bdev; lo->lo_flags = lo_flags; + lo->lo_xid = vx_current_xid(); lo->lo_backing_file = file; lo->transfer = NULL; lo->ioctl = NULL; @@ -928,6 +929,7 @@ static int loop_clr_fd(struct loop_devic lo->lo_sizelimit = 0; lo->lo_encrypt_key_size = 0; lo->lo_flags = 0; + lo->lo_xid = 0; memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); @@ -1184,6 +1186,9 @@ static int lo_open(struct inode *inode, { struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + if (!vx_check(lo->lo_xid, VX_IDENT)) + return -EACCES; + mutex_lock(&lo->lo_ctl_mutex); lo->lo_refcnt++; mutex_unlock(&lo->lo_ctl_mutex); diff -NurpP linux-2.6.17.7-vs2.1.1-rc27.7/drivers/md/dm.c linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c --- linux-2.6.17.7-vs2.1.1-rc27.7/drivers/md/dm.c 2006-06-18 04:53:11 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c 2006-08-04 20:44:02 +0200 @@ -66,6 +66,7 @@ struct mapped_device { struct semaphore suspend_lock; rwlock_t map_lock; atomic_t holders; + xid_t xid; unsigned long flags; @@ -219,6 +220,8 @@ static int dm_blk_open(struct inode *ino struct mapped_device *md; md = inode->i_bdev->bd_disk->private_data; + if (!vx_check(md->xid, VX_IDENT)) + return -EACCES; dm_get(md); return 0; } @@ -850,6 +853,7 @@ static struct mapped_device *alloc_dev(u rwlock_init(&md->map_lock); atomic_set(&md->holders, 1); atomic_set(&md->event_nr, 0); + md->xid = vx_current_xid(); md->queue = blk_alloc_queue(GFP_KERNEL); if (!md->queue) diff -NurpP linux-2.6.17.7-vs2.1.1-rc27.7/include/linux/loop.h linux-2.6.17.7-vs2.1.1-rc28/include/linux/loop.h --- linux-2.6.17.7-vs2.1.1-rc27.7/include/linux/loop.h 2006-06-18 04:55:19 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28/include/linux/loop.h 2006-08-04 20:07:26 +0200 @@ -45,6 +45,7 @@ struct loop_device { struct loop_func_table *lo_encryption; __u32 lo_init[2]; uid_t lo_key_owner; /* Who set the key */ + xid_t lo_xid; int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); diff -u linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c --- linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c 2006-08-06 06:10:42 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c 2006-08-06 06:10:42 +0200 @@ -951,7 +951,7 @@ struct loop_func_table *xfer; if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid && - !capable(CAP_SYS_ADMIN)) + !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) return -EPERM; if (lo->lo_state != Lo_bound) return -ENXIO; @@ -1031,7 +1031,8 @@ memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE); info->lo_encrypt_type = lo->lo_encryption ? lo->lo_encryption->number : 0; - if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) { + if (lo->lo_encrypt_key_size && + vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) { info->lo_encrypt_key_size = lo->lo_encrypt_key_size; memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, lo->lo_encrypt_key_size); diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/include/linux/vserver/context.h linux-2.6.17.7-vs2.1.1-rc28.1/include/linux/vserver/context.h --- linux-2.6.17.7-vs2.1.1-rc28/include/linux/vserver/context.h 2006-07-30 16:50:15 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28.1/include/linux/vserver/context.h 2006-08-06 05:52:41 +0200 @@ -78,6 +78,8 @@ #define VXC_BINARY_MOUNT 0x00040000 #define VXC_QUOTA_CTL 0x00100000 +#define VXC_ADMIN_MAPPER 0x00200000 +#define VXC_ADMIN_CLOOP 0x00400000 /* context state changes */ diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.c --- linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c 2006-08-04 20:44:02 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.c 2006-08-06 06:14:06 +0200 @@ -355,6 +355,14 @@ int dm_set_geometry(struct mapped_device return 0; } +/* + * Get the xid associated with a dm device + */ +xid_t dm_get_xid(struct mapped_device *md) +{ + return md->xid; +} + /*----------------------------------------------------------------- * CRUD START: * A more elegant soln is in the works that uses the queue diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.h linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.h --- linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.h 2006-06-18 04:53:11 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.h 2006-08-06 05:21:14 +0200 @@ -92,6 +92,8 @@ int dm_suspended(struct mapped_device *m int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); +xid_t dm_get_xid(struct mapped_device *md); + /*----------------------------------------------------------------- * Functions for manipulating a table. Tables are also reference * counted. diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm-ioctl.c linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm-ioctl.c --- linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm-ioctl.c 2006-06-18 04:53:10 +0200 +++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm-ioctl.c 2006-08-06 06:13:41 +0200 @@ -102,7 +102,8 @@ static struct hash_cell *__get_name_cell unsigned int h = hash_str(str); list_for_each_entry (hc, _name_buckets + h, name_list) - if (!strcmp(hc->name, str)) + if (vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT) && + !strcmp(hc->name, str)) return hc; return NULL; @@ -114,7 +115,8 @@ static struct hash_cell *__get_uuid_cell unsigned int h = hash_str(str); list_for_each_entry (hc, _uuid_buckets + h, uuid_list) - if (!strcmp(hc->uuid, str)) + if (vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT) && + !strcmp(hc->uuid, str)) return hc; return NULL; @@ -344,6 +346,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl static int remove_all(struct dm_ioctl *param, size_t param_size) { + if (!vx_check(0, VX_ADMIN)) + return -EPERM; + dm_hash_remove_all(); param->data_size = 0; return 0; @@ -391,6 +396,8 @@ static int list_devices(struct dm_ioctl */ for (i = 0; i < NUM_BUCKETS; i++) { list_for_each_entry (hc, _name_buckets + i, name_list) { + if (!vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT)) + continue; needed += sizeof(struct dm_name_list); needed += strlen(hc->name) + 1; needed += ALIGN_MASK; @@ -414,6 +421,8 @@ static int list_devices(struct dm_ioctl */ for (i = 0; i < NUM_BUCKETS; i++) { list_for_each_entry (hc, _name_buckets + i, name_list) { + if (!vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT)) + continue; if (old_nl) old_nl->next = (uint32_t) ((void *) nl - (void *) old_nl); @@ -1390,8 +1399,8 @@ static int ctl_ioctl(struct inode *inode ioctl_fn fn = NULL; size_t param_size; - /* only root can play with this */ - if (!capable(CAP_SYS_ADMIN)) + /* only root and certain contexts can play with this */ + if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER)) return -EACCES; if (_IOC_TYPE(command) != DM_IOCTL)