Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242563
b: refs/heads/master
c: f868120
h: refs/heads/master
i:
  242561: cc6bbfc
  242559: c88e064
v: v3
  • Loading branch information
Milan Broz authored and Alasdair G Kergon committed Mar 24, 2011
1 parent 831bb99 commit a764321
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6bb43b5d1f54fb44c0408d86d5e71e4405a3ebe1
refs/heads/master: f868120549fc1664b2c451d4b9882a363928c698
23 changes: 21 additions & 2 deletions trunk/drivers/md/dm-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1504,24 +1504,36 @@ static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
{
struct dm_ioctl tmp, *dmi;
int secure_data;

if (copy_from_user(&tmp, user, sizeof(tmp) - sizeof(tmp.data)))
return -EFAULT;

if (tmp.data_size < (sizeof(tmp) - sizeof(tmp.data)))
return -EINVAL;

secure_data = tmp.flags & DM_SECURE_DATA_FLAG;

dmi = vmalloc(tmp.data_size);
if (!dmi)
if (!dmi) {
if (secure_data && clear_user(user, tmp.data_size))
return -EFAULT;
return -ENOMEM;
}

if (copy_from_user(dmi, user, tmp.data_size))
goto bad;

/* Wipe the user buffer so we do not return it to userspace */
if (secure_data && clear_user(user, tmp.data_size))
goto bad;

*param = dmi;
return 0;

bad:
if (secure_data)
memset(dmi, 0, tmp.data_size);
vfree(dmi);
return -EFAULT;
}
Expand All @@ -1531,6 +1543,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
/* Always clear this flag */
param->flags &= ~DM_BUFFER_FULL_FLAG;
param->flags &= ~DM_UEVENT_GENERATED_FLAG;
param->flags &= ~DM_SECURE_DATA_FLAG;

/* Ignores parameters */
if (cmd == DM_REMOVE_ALL_CMD ||
Expand Down Expand Up @@ -1558,6 +1571,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
{
int r = 0;
int wipe_buffer;
unsigned int cmd;
struct dm_ioctl *uninitialized_var(param);
ioctl_fn fn = NULL;
Expand Down Expand Up @@ -1602,13 +1616,15 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
* Copy the parameters into kernel space.
*/
r = copy_params(user, &param);
input_param_size = param->data_size;

current->flags &= ~PF_MEMALLOC;

if (r)
return r;

input_param_size = param->data_size;
wipe_buffer = param->flags & DM_SECURE_DATA_FLAG;

r = validate_params(cmd, param);
if (r)
goto out;
Expand All @@ -1623,6 +1639,9 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
r = -EFAULT;

out:
if (wipe_buffer)
memset(param, 0, input_param_size);

vfree(param);
return r;
}
Expand Down
12 changes: 9 additions & 3 deletions trunk/include/linux/dm-ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,9 @@ enum {
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)

#define DM_VERSION_MAJOR 4
#define DM_VERSION_MINOR 19
#define DM_VERSION_PATCHLEVEL 1
#define DM_VERSION_EXTRA "-ioctl (2011-01-07)"
#define DM_VERSION_MINOR 20
#define DM_VERSION_PATCHLEVEL 0
#define DM_VERSION_EXTRA "-ioctl (2011-02-02)"

/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
Expand Down Expand Up @@ -328,4 +328,10 @@ enum {
*/
#define DM_UUID_FLAG (1 << 14) /* In */

/*
* If set, all buffers are wiped after use. Use when sending
* or requesting sensitive data such as an encryption key.
*/
#define DM_SECURE_DATA_FLAG (1 << 15) /* In */

#endif /* _LINUX_DM_IOCTL_H */

0 comments on commit a764321

Please sign in to comment.