diff options
-rw-r--r-- | fs/dlm/user.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 065149e84f42..ebce994ab0b7 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. | 2 | * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * This copyrighted material is made available to anyone wishing to use, | 4 | * This copyrighted material is made available to anyone wishing to use, |
5 | * modify, copy, or redistribute it subject to the terms and conditions | 5 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -84,7 +84,7 @@ struct dlm_lock_result32 { | |||
84 | 84 | ||
85 | static void compat_input(struct dlm_write_request *kb, | 85 | static void compat_input(struct dlm_write_request *kb, |
86 | struct dlm_write_request32 *kb32, | 86 | struct dlm_write_request32 *kb32, |
87 | size_t count) | 87 | int namelen) |
88 | { | 88 | { |
89 | kb->version[0] = kb32->version[0]; | 89 | kb->version[0] = kb32->version[0]; |
90 | kb->version[1] = kb32->version[1]; | 90 | kb->version[1] = kb32->version[1]; |
@@ -96,8 +96,7 @@ static void compat_input(struct dlm_write_request *kb, | |||
96 | kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { | 96 | kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { |
97 | kb->i.lspace.flags = kb32->i.lspace.flags; | 97 | kb->i.lspace.flags = kb32->i.lspace.flags; |
98 | kb->i.lspace.minor = kb32->i.lspace.minor; | 98 | kb->i.lspace.minor = kb32->i.lspace.minor; |
99 | memcpy(kb->i.lspace.name, kb32->i.lspace.name, count - | 99 | memcpy(kb->i.lspace.name, kb32->i.lspace.name, namelen); |
100 | offsetof(struct dlm_write_request32, i.lspace.name)); | ||
101 | } else if (kb->cmd == DLM_USER_PURGE) { | 100 | } else if (kb->cmd == DLM_USER_PURGE) { |
102 | kb->i.purge.nodeid = kb32->i.purge.nodeid; | 101 | kb->i.purge.nodeid = kb32->i.purge.nodeid; |
103 | kb->i.purge.pid = kb32->i.purge.pid; | 102 | kb->i.purge.pid = kb32->i.purge.pid; |
@@ -115,8 +114,7 @@ static void compat_input(struct dlm_write_request *kb, | |||
115 | kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; | 114 | kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; |
116 | kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; | 115 | kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; |
117 | memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); | 116 | memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); |
118 | memcpy(kb->i.lock.name, kb32->i.lock.name, count - | 117 | memcpy(kb->i.lock.name, kb32->i.lock.name, namelen); |
119 | offsetof(struct dlm_write_request32, i.lock.name)); | ||
120 | } | 118 | } |
121 | } | 119 | } |
122 | 120 | ||
@@ -539,9 +537,16 @@ static ssize_t device_write(struct file *file, const char __user *buf, | |||
539 | #ifdef CONFIG_COMPAT | 537 | #ifdef CONFIG_COMPAT |
540 | if (!kbuf->is64bit) { | 538 | if (!kbuf->is64bit) { |
541 | struct dlm_write_request32 *k32buf; | 539 | struct dlm_write_request32 *k32buf; |
540 | int namelen = 0; | ||
541 | |||
542 | if (count > sizeof(struct dlm_write_request32)) | ||
543 | namelen = count - sizeof(struct dlm_write_request32); | ||
544 | |||
542 | k32buf = (struct dlm_write_request32 *)kbuf; | 545 | k32buf = (struct dlm_write_request32 *)kbuf; |
543 | kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) - | 546 | |
544 | sizeof(struct dlm_write_request32)), GFP_KERNEL); | 547 | /* add 1 after namelen so that the name string is terminated */ |
548 | kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1, | ||
549 | GFP_KERNEL); | ||
545 | if (!kbuf) { | 550 | if (!kbuf) { |
546 | kfree(k32buf); | 551 | kfree(k32buf); |
547 | return -ENOMEM; | 552 | return -ENOMEM; |
@@ -549,7 +554,8 @@ static ssize_t device_write(struct file *file, const char __user *buf, | |||
549 | 554 | ||
550 | if (proc) | 555 | if (proc) |
551 | set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); | 556 | set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); |
552 | compat_input(kbuf, k32buf, count + 1); | 557 | |
558 | compat_input(kbuf, k32buf, namelen); | ||
553 | kfree(k32buf); | 559 | kfree(k32buf); |
554 | } | 560 | } |
555 | #endif | 561 | #endif |