Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 676

kernel-2.6.18-238.el5.src.rpm

From: David Teigland <teigland@redhat.com>
Date: Tue, 19 Aug 2008 13:38:53 -0500
Subject: [dlm] user.c input validation fixes
Message-id: 20080819183853.GA24260@redhat.com
O-Subject: [RHEL5.3 PATCH] dlm: user.c input validation fixes
Bugzilla: 458760
RH-Acked-by: Bob Peterson <rpeterso@redhat.com>

bz 458760 kernel: dlm: dlm/user.c input validation fixes [rhel-5.3]

brew build including this patch
(will send when brew is back)

upstream commit:

commit cb79f1998d89821a4dbac47f59a46ee3fbbf3c61
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sat Jan 26 16:49:44 2008 -0500

    dlm: dlm/user.c input validation fixes

    a) in device_write(): add sentinel NUL byte, making sure that lspace.name wi
    be NUL-terminated
    b) in compat_input() be keep it simple about the amounts of data we are copy

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: David Teigland <teigland@redhat.com>

diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 72f4286..302cf0c 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -84,7 +84,7 @@ struct dlm_lock_result32 {
 
 static void compat_input(struct dlm_write_request *kb,
 			 struct dlm_write_request32 *kb32,
-			 int max_namelen)
+			 size_t count)
 {
 	kb->version[0] = kb32->version[0];
 	kb->version[1] = kb32->version[1];
@@ -96,7 +96,8 @@ static void compat_input(struct dlm_write_request *kb,
 	    kb->cmd == DLM_USER_REMOVE_LOCKSPACE) {
 		kb->i.lspace.flags = kb32->i.lspace.flags;
 		kb->i.lspace.minor = kb32->i.lspace.minor;
-		strcpy(kb->i.lspace.name, kb32->i.lspace.name);
+		memcpy(kb->i.lspace.name, kb32->i.lspace.name, count -
+		       offsetof(struct dlm_write_request32, i.lspace.name));
 	} else if (kb->cmd == DLM_USER_PURGE) {
 		kb->i.purge.nodeid = kb32->i.purge.nodeid;
 		kb->i.purge.pid = kb32->i.purge.pid;
@@ -114,10 +115,8 @@ static void compat_input(struct dlm_write_request *kb,
 		kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
 		kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
 		memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
-		if (kb->i.lock.namelen <= max_namelen)
-			memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen);
-		else
-			kb->i.lock.namelen = max_namelen;
+		memcpy(kb->i.lock.name, kb32->i.lock.name, count -
+		       offsetof(struct dlm_write_request32, i.lock.name));
 	}
 }
 
@@ -509,7 +508,7 @@ static ssize_t device_write(struct file *file, const char __user *buf,
 #endif
 		return -EINVAL;
 
-	kbuf = kmalloc(count, GFP_KERNEL);
+	kbuf = kzalloc(count + 1, GFP_KERNEL);
 	if (!kbuf)
 		return -ENOMEM;
 
@@ -527,14 +526,14 @@ static ssize_t device_write(struct file *file, const char __user *buf,
 	if (!kbuf->is64bit) {
 		struct dlm_write_request32 *k32buf;
 		k32buf = (struct dlm_write_request32 *)kbuf;
-		kbuf = kmalloc(count + (sizeof(struct dlm_write_request) -
+		kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) -
 			       sizeof(struct dlm_write_request32)), GFP_KERNEL);
 		if (!kbuf)
 			return -ENOMEM;
 
 		if (proc)
 			set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
-		compat_input(kbuf, k32buf, count - sizeof(struct dlm_write_request32));
+		compat_input(kbuf, k32buf, count + 1);
 		kfree(k32buf);
 	}
 #endif