]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/dlm-fix-length-calculation-in-compat-code.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / dlm-fix-length-calculation-in-compat-code.patch
1 From: David Teigland <teigland@redhat.com>
2 commit 1fecb1c4b62881e3689ba2dcf93072ae301b597c
3 Author: David Teigland <teigland@redhat.com>
4 Date: Wed Mar 4 11:17:23 2009 -0600
5 Subject: dlm: fix length calculation in compat code
6
7 Using offsetof() to calculate name length does not work because
8 it does not produce consistent results with with structure packing.
9 This caused memcpy to corrupt memory by copying 4 extra bytes off
10 the end of the buffer on 64 bit kernels with 32 bit userspace
11 (the only case where this 32/64 compat code is used).
12
13 The fix is to calculate name length directly from the start instead
14 of trying to derive it later using count and offsetof.
15
16 Signed-off-by: David Teigland <teigland@redhat.com>
17 Signed-off-by: Coly Li <coly.li@suse.de>
18
19 diff --git a/fs/dlm/user.c b/fs/dlm/user.c
20 index 065149e..ebce994 100644
21 --- a/fs/dlm/user.c
22 +++ b/fs/dlm/user.c
23 @@ -1,5 +1,5 @@
24 /*
25 - * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
26 + * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
27 *
28 * This copyrighted material is made available to anyone wishing to use,
29 * modify, copy, or redistribute it subject to the terms and conditions
30 @@ -84,7 +84,7 @@ struct dlm_lock_result32 {
31
32 static void compat_input(struct dlm_write_request *kb,
33 struct dlm_write_request32 *kb32,
34 - size_t count)
35 + int namelen)
36 {
37 kb->version[0] = kb32->version[0];
38 kb->version[1] = kb32->version[1];
39 @@ -96,8 +96,7 @@ static void compat_input(struct dlm_write_request *kb,
40 kb->cmd == DLM_USER_REMOVE_LOCKSPACE) {
41 kb->i.lspace.flags = kb32->i.lspace.flags;
42 kb->i.lspace.minor = kb32->i.lspace.minor;
43 - memcpy(kb->i.lspace.name, kb32->i.lspace.name, count -
44 - offsetof(struct dlm_write_request32, i.lspace.name));
45 + memcpy(kb->i.lspace.name, kb32->i.lspace.name, namelen);
46 } else if (kb->cmd == DLM_USER_PURGE) {
47 kb->i.purge.nodeid = kb32->i.purge.nodeid;
48 kb->i.purge.pid = kb32->i.purge.pid;
49 @@ -115,8 +114,7 @@ static void compat_input(struct dlm_write_request *kb,
50 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
51 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
52 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
53 - memcpy(kb->i.lock.name, kb32->i.lock.name, count -
54 - offsetof(struct dlm_write_request32, i.lock.name));
55 + memcpy(kb->i.lock.name, kb32->i.lock.name, namelen);
56 }
57 }
58
59 @@ -539,9 +537,16 @@ static ssize_t device_write(struct file *file, const char __user *buf,
60 #ifdef CONFIG_COMPAT
61 if (!kbuf->is64bit) {
62 struct dlm_write_request32 *k32buf;
63 + int namelen = 0;
64 +
65 + if (count > sizeof(struct dlm_write_request32))
66 + namelen = count - sizeof(struct dlm_write_request32);
67 +
68 k32buf = (struct dlm_write_request32 *)kbuf;
69 - kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) -
70 - sizeof(struct dlm_write_request32)), GFP_KERNEL);
71 +
72 + /* add 1 after namelen so that the name string is terminated */
73 + kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1,
74 + GFP_KERNEL);
75 if (!kbuf) {
76 kfree(k32buf);
77 return -ENOMEM;
78 @@ -549,7 +554,8 @@ static ssize_t device_write(struct file *file, const char __user *buf,
79
80 if (proc)
81 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
82 - compat_input(kbuf, k32buf, count + 1);
83 +
84 + compat_input(kbuf, k32buf, namelen);
85 kfree(k32buf);
86 }
87 #endif