From e3a8d0803040fb8a665e87f361b106f0636c152d Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Wed, 10 May 2006 18:46:48 -0700 Subject: [PATCH] Linux 2.6.16.16 release - fcntl_setlease local DoS (CVE-2006-1860) --- .../2.6.16.16/fs-locks.c-fix-lease_init.patch | 77 +++++++++++++++++++ releases/2.6.16.16/series | 1 + 2 files changed, 78 insertions(+) create mode 100644 releases/2.6.16.16/fs-locks.c-fix-lease_init.patch create mode 100644 releases/2.6.16.16/series diff --git a/releases/2.6.16.16/fs-locks.c-fix-lease_init.patch b/releases/2.6.16.16/fs-locks.c-fix-lease_init.patch new file mode 100644 index 00000000000..eb36c034986 --- /dev/null +++ b/releases/2.6.16.16/fs-locks.c-fix-lease_init.patch @@ -0,0 +1,77 @@ +From nobody Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sun, 7 May 2006 23:02:42 -0400 +Subject: [PATCH] fs/locks.c: Fix lease_init (CVE-2006-1860) + +It is insane to be giving lease_init() the task of freeing the lock it is +supposed to initialise, given that the lock is not guaranteed to be +allocated on the stack. This causes lockups in fcntl_setlease(). +Problem diagnosed by Daniel Hokka Zakrisson + +Also fix a slab leak in __setlease() due to an uninitialised return value. +Problem diagnosed by Björn Steinbrink. + +Signed-off-by: Trond Myklebust +Tested-by: Daniel Hokka Zakrisson +Signed-off-by: Linus Torvalds +Cc: Björn Steinbrink +Signed-off-by: Chris Wright +--- + + fs/locks.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- linux-2.6.16.15.orig/fs/locks.c ++++ linux-2.6.16.15/fs/locks.c +@@ -432,15 +432,14 @@ static struct lock_manager_operations le + */ + static int lease_init(struct file *filp, int type, struct file_lock *fl) + { ++ if (assign_type(fl, type) != 0) ++ return -EINVAL; ++ + fl->fl_owner = current->files; + fl->fl_pid = current->tgid; + + fl->fl_file = filp; + fl->fl_flags = FL_LEASE; +- if (assign_type(fl, type) != 0) { +- locks_free_lock(fl); +- return -EINVAL; +- } + fl->fl_start = 0; + fl->fl_end = OFFSET_MAX; + fl->fl_ops = NULL; +@@ -452,16 +451,19 @@ static int lease_init(struct file *filp, + static int lease_alloc(struct file *filp, int type, struct file_lock **flp) + { + struct file_lock *fl = locks_alloc_lock(); +- int error; ++ int error = -ENOMEM; + + if (fl == NULL) +- return -ENOMEM; ++ goto out; + + error = lease_init(filp, type, fl); +- if (error) +- return error; ++ if (error) { ++ locks_free_lock(fl); ++ fl = NULL; ++ } ++out: + *flp = fl; +- return 0; ++ return error; + } + + /* Check if two locks overlap each other. +@@ -1337,6 +1339,7 @@ static int __setlease(struct file *filp, + goto out; + + if (my_before != NULL) { ++ *flp = *my_before; + error = lease->fl_lmops->fl_change(my_before, arg); + goto out; + } diff --git a/releases/2.6.16.16/series b/releases/2.6.16.16/series new file mode 100644 index 00000000000..d153d2b3802 --- /dev/null +++ b/releases/2.6.16.16/series @@ -0,0 +1 @@ +fs-locks.c-fix-lease_init.patch -- 2.47.2