lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Tue, 7 Jul 2009 12:46:24 -0400
From:	Nelson Elhage <nelhage@...lice.com>
To:	Pavel Machek <pavel@....cz>
Cc:	Jeff Arnold <jbarnold@...lice.com>, linux-kernel@...r.kernel.org,
	tabbott@...lice.com, wdaher@...lice.com, andersk@...lice.com,
	price@...lice.com, geofft@...lice.com
Subject: Re: Ksplice updates for Ubuntu 9.04 Jaunty

On Sun, Jul 05, 2009 at 08:47:10PM +0200, Pavel Machek wrote:
> Lets say something adds field to task_struct. Can you handle that?

Yes. It looks like the most recent such patch that was added to a
stable tree is 3b53fbf. Applying that patch using Ksplice requires
writing about 40 semicolon-terminated lines of new code. I've included
the modified patch and the Ksplice command to apply it to a running
machine below.

Ksplice has not yet been fully honed for this case of adding fields to
data structures because this capability is rarely needed for bug-fix
patches. For now, we are carefully writing (and reviewing and testing)
these bits of new code as they are needed. In the future, these
patches that add fields to data structures will be even easier to
apply using Ksplice.

- Nelson Elhage

Once you've set up your kernel source directory for Ksplice [1], you can
apply this patch using two commands:

$ ksplice-create --patch=taskstruct.patch ~/linux-source
Ksplice update tarball written to ksplice-if5askfa.tar.gz
$ ksplice-apply ksplice-if5askfa.tar.gz

[1] http://www.ksplice.com/example-update

---
Original patch diffstat (stable tree 3b53fbf):
 include/linux/sched.h |    2 ++
 include/net/scm.h     |    5 +++--
 net/core/scm.c        |   24 +++++++++++++++++++++---
 3 files changed, 26 insertions(+), 5 deletions(-)

Modified Ksplice patch diffstat (below):
 net/core/scm.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/net/core/scm.c b/net/core/scm.c
index 10f5c65..7280c89 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -36,6 +36,25 @@
 #include <net/compat.h>
 #include <net/scm.h>
 
+#include "ksplice-patch.h"
+#include "ksplice-shadow.h"
+
+struct task_struct_shadow {
+	struct list_head	*scm_work_list;
+};
+
+#define init_new_task_struct_shadow(shadow) (shadow)->scm_work_list = NULL
+DEFINE_SHADOW_FIELD(struct task_struct, struct task_struct_shadow, GFP_ATOMIC,
+                    task_struct, init_new_task_struct_shadow);
+
+struct scm_fp_list_shadow {
+	struct list_head	list;
+	struct scm_fp_list	*fpl;
+};
+
+#define init_new_fp_list_shadow(shadow) INIT_LIST_HEAD(&(shadow)->list)
+DEFINE_SHADOW_FIELD(struct scm_fp_list, struct scm_fp_list_shadow, GFP_ATOMIC,
+                    fp_list, init_new_fp_list_shadow);
 
 /*
  *	Only allow a user to send credentials, that they could set with
@@ -58,6 +77,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
 {
 	int *fdp = (int*)CMSG_DATA(cmsg);
 	struct scm_fp_list *fpl = *fplp;
+	struct scm_fp_list_shadow *fpl_shadow;
 	struct file **fpp;
 	int i, num;
 
@@ -74,6 +94,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
 		fpl = kmalloc(sizeof(struct scm_fp_list), GFP_KERNEL);
 		if (!fpl)
 			return -ENOMEM;
+		fpl_shadow = init_fp_list_shadow(fpl, GFP_KERNEL);
+		if (!fpl_shadow) {
+			kfree(fpl);
+			return -ENOMEM;
+		}
 		*fplp = fpl;
 		fpl->count = 0;
 	}
@@ -105,10 +130,48 @@ void __scm_destroy(struct scm_cookie *scm)
 	int i;
 
 	if (fpl) {
+		struct scm_fp_list_shadow *fpl_shadow;
+		struct task_struct_shadow *current_shadow;
+
+		fpl_shadow = make_fp_list_shadow(fpl, GFP_ATOMIC);
+		if (!fpl_shadow) {
+			printk(KERN_WARNING "__scm_destroy: Unable to allocate fpl_shadow");
+			WARN_ON(1);
+			return;
+		}
+
+		current_shadow = make_task_struct_shadow(current, GFP_ATOMIC);
+		if (!current_shadow) {
+			kfree(fpl_shadow);
+			printk(KERN_WARNING "__scm_destroy: Unable to allocate current_shadow");
+			WARN_ON(1);
+			return;
+		}
+
+		fpl_shadow->fpl = fpl;
 		scm->fp = NULL;
-		for (i=fpl->count-1; i>=0; i--)
-			fput(fpl->fp[i]);
-		kfree(fpl);
+		if (current_shadow->scm_work_list) {
+			list_add_tail(&fpl_shadow->list, current_shadow->scm_work_list);
+		} else {
+			LIST_HEAD(work_list);
+
+			current_shadow->scm_work_list = &work_list;
+
+			list_add(&fpl_shadow->list, &work_list);
+			while (!list_empty(&work_list)) {
+				fpl_shadow = list_first_entry(&work_list, struct scm_fp_list_shadow, list);
+				fpl = fpl_shadow->fpl;
+
+				list_del(&fpl_shadow->list);
+				for (i=fpl->count-1; i>=0; i--)
+					fput(fpl->fp[i]);
+
+				cleanup_fp_list_shadow(fpl);
+				kfree(fpl);
+			}
+
+			cleanup_task_struct_shadow(current);
+		}
 	}
 }
 
@@ -277,6 +340,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 {
 	struct scm_fp_list *new_fpl;
+	struct scm_fp_list_shadow *new_fpl_shadow;
 	int i;
 
 	if (!fpl)
@@ -284,6 +348,12 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 
 	new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
 	if (new_fpl) {
+		new_fpl_shadow = init_fp_list_shadow(new_fpl, GFP_KERNEL);
+		if (!new_fpl_shadow) {
+			kfree(new_fpl);
+			return NULL;
+		}
+
 		for (i=fpl->count-1; i>=0; i--)
 			get_file(fpl->fp[i]);
 		memcpy(new_fpl, fpl, sizeof(*fpl));
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ