diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-01-26 16:49:44 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2008-02-04 02:30:19 -0500 |
commit | cb79f1998d89821a4dbac47f59a46ee3fbbf3c61 (patch) | |
tree | 1d1f953a43d1b3aa6bd9a786637ab2c4d2c7ab19 /fs | |
parent | 043b19cdc081f586a8f4e1c93ce6c03b63c26284 (diff) |
dlm: dlm/user.c input validation fixes
a) in device_write(): add sentinel NUL byte, making sure that lspace.name will
be NUL-terminated
b) in compat_input() be keep it simple about the amounts of data we are copying.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dlm/user.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 7cbc6826239..c3060458b68 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -82,7 +82,7 @@ struct dlm_lock_result32 { | |||
82 | 82 | ||
83 | static void compat_input(struct dlm_write_request *kb, | 83 | static void compat_input(struct dlm_write_request *kb, |
84 | struct dlm_write_request32 *kb32, | 84 | struct dlm_write_request32 *kb32, |
85 | int max_namelen) | 85 | size_t count) |
86 | { | 86 | { |
87 | kb->version[0] = kb32->version[0]; | 87 | kb->version[0] = kb32->version[0]; |
88 | kb->version[1] = kb32->version[1]; | 88 | kb->version[1] = kb32->version[1]; |
@@ -94,7 +94,8 @@ static void compat_input(struct dlm_write_request *kb, | |||
94 | kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { | 94 | kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { |
95 | kb->i.lspace.flags = kb32->i.lspace.flags; | 95 | kb->i.lspace.flags = kb32->i.lspace.flags; |
96 | kb->i.lspace.minor = kb32->i.lspace.minor; | 96 | kb->i.lspace.minor = kb32->i.lspace.minor; |
97 | strcpy(kb->i.lspace.name, kb32->i.lspace.name); | 97 | memcpy(kb->i.lspace.name, kb32->i.lspace.name, count - |
98 | offsetof(struct dlm_write_request32, i.lspace.name)); | ||
98 | } else if (kb->cmd == DLM_USER_PURGE) { | 99 | } else if (kb->cmd == DLM_USER_PURGE) { |
99 | kb->i.purge.nodeid = kb32->i.purge.nodeid; | 100 | kb->i.purge.nodeid = kb32->i.purge.nodeid; |
100 | kb->i.purge.pid = kb32->i.purge.pid; | 101 | kb->i.purge.pid = kb32->i.purge.pid; |
@@ -112,11 +113,8 @@ static void compat_input(struct dlm_write_request *kb, | |||
112 | kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; | 113 | kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; |
113 | kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; | 114 | kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; |
114 | memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); | 115 | memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); |
115 | if (kb->i.lock.namelen <= max_namelen) | 116 | memcpy(kb->i.lock.name, kb32->i.lock.name, count - |
116 | memcpy(kb->i.lock.name, kb32->i.lock.name, | 117 | offsetof(struct dlm_write_request32, i.lock.name)); |
117 | kb->i.lock.namelen); | ||
118 | else | ||
119 | kb->i.lock.namelen = max_namelen; | ||
120 | } | 118 | } |
121 | } | 119 | } |
122 | 120 | ||
@@ -508,7 +506,7 @@ static ssize_t device_write(struct file *file, const char __user *buf, | |||
508 | #endif | 506 | #endif |
509 | return -EINVAL; | 507 | return -EINVAL; |
510 | 508 | ||
511 | kbuf = kmalloc(count, GFP_KERNEL); | 509 | kbuf = kzalloc(count + 1, GFP_KERNEL); |
512 | if (!kbuf) | 510 | if (!kbuf) |
513 | return -ENOMEM; | 511 | return -ENOMEM; |
514 | 512 | ||
@@ -526,15 +524,14 @@ static ssize_t device_write(struct file *file, const char __user *buf, | |||
526 | if (!kbuf->is64bit) { | 524 | if (!kbuf->is64bit) { |
527 | struct dlm_write_request32 *k32buf; | 525 | struct dlm_write_request32 *k32buf; |
528 | k32buf = (struct dlm_write_request32 *)kbuf; | 526 | k32buf = (struct dlm_write_request32 *)kbuf; |
529 | kbuf = kmalloc(count + (sizeof(struct dlm_write_request) - | 527 | kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) - |
530 | sizeof(struct dlm_write_request32)), GFP_KERNEL); | 528 | sizeof(struct dlm_write_request32)), GFP_KERNEL); |
531 | if (!kbuf) | 529 | if (!kbuf) |
532 | return -ENOMEM; | 530 | return -ENOMEM; |
533 | 531 | ||
534 | if (proc) | 532 | if (proc) |
535 | set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); | 533 | set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); |
536 | compat_input(kbuf, k32buf, | 534 | compat_input(kbuf, k32buf, count + 1); |
537 | count - sizeof(struct dlm_write_request32)); | ||
538 | kfree(k32buf); | 535 | kfree(k32buf); |
539 | } | 536 | } |
540 | #endif | 537 | #endif |