From f08bf4c34a0048e4764fd1c1348205a2d49a102d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 6 May 2010 14:08:29 -0700 Subject: [PATCH] .27 patches --- ...-an-existing-key-to-the-dest-keyring.patch | 81 +++++++++++++++++++ queue-2.6.27/nfsd4-bug-in-read_buf.patch | 58 +++++++++++++ queue-2.6.27/series | 3 + ...-wrong-variable-in-fs_create_by_name.patch | 38 +++++++++ 4 files changed, 180 insertions(+) create mode 100644 queue-2.6.27/keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch create mode 100644 queue-2.6.27/nfsd4-bug-in-read_buf.patch create mode 100644 queue-2.6.27/usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch diff --git a/queue-2.6.27/keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch b/queue-2.6.27/keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch new file mode 100644 index 00000000000..594176f0bd9 --- /dev/null +++ b/queue-2.6.27/keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch @@ -0,0 +1,81 @@ +From 03449cd9eaa4fa3a7faa4a59474bafe2e90bd143 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Tue, 27 Apr 2010 13:13:08 -0700 +Subject: keys: the request_key() syscall should link an existing key to the dest keyring + +From: David Howells + +commit 03449cd9eaa4fa3a7faa4a59474bafe2e90bd143 upstream. + +The request_key() system call and request_key_and_link() should make a +link from an existing key to the destination keyring (if supplied), not +just from a new key to the destination keyring. + +This can be tested by: + + ring=`keyctl newring fred @s` + keyctl request2 user debug:a a + keyctl request user debug:a $ring + keyctl list $ring + +If it says: + + keyring is empty + +then it didn't work. If it shows something like: + + 1 key in keyring: + 1070462727: --alswrv 0 0 user: debug:a + +then it did. + +request_key() system call is meant to recursively search all your keyrings for +the key you desire, and, optionally, if it doesn't exist, call out to userspace +to create one for you. + +If request_key() finds or creates a key, it should, optionally, create a link +to that key from the destination keyring specified. + +Therefore, if, after a successful call to request_key() with a desination +keyring specified, you see the destination keyring empty, the code didn't work +correctly. + +If you see the found key in the keyring, then it did - which is what the patch +is required for. + +Signed-off-by: David Howells +Cc: James Morris +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + security/keys/request_key.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/security/keys/request_key.c ++++ b/security/keys/request_key.c +@@ -316,8 +316,10 @@ static int construct_alloc_key(struct ke + + key_already_present: + mutex_unlock(&key_construction_mutex); +- if (dest_keyring) ++ if (dest_keyring) { ++ __key_link(dest_keyring, key_ref_to_ptr(key_ref)); + up_write(&dest_keyring->sem); ++ } + mutex_unlock(&user->cons_lock); + key_put(key); + *_key = key = key_ref_to_ptr(key_ref); +@@ -396,6 +398,11 @@ struct key *request_key_and_link(struct + + if (!IS_ERR(key_ref)) { + key = key_ref_to_ptr(key_ref); ++ if (dest_keyring) { ++ construct_get_dest_keyring(&dest_keyring); ++ key_link(dest_keyring, key); ++ key_put(dest_keyring); ++ } + } else if (PTR_ERR(key_ref) != -EAGAIN) { + key = ERR_CAST(key_ref); + } else { diff --git a/queue-2.6.27/nfsd4-bug-in-read_buf.patch b/queue-2.6.27/nfsd4-bug-in-read_buf.patch new file mode 100644 index 00000000000..8e1034ab807 --- /dev/null +++ b/queue-2.6.27/nfsd4-bug-in-read_buf.patch @@ -0,0 +1,58 @@ +From 2bc3c1179c781b359d4f2f3439cb3df72afc17fc Mon Sep 17 00:00:00 2001 +From: Neil Brown +Date: Tue, 20 Apr 2010 12:16:52 +1000 +Subject: nfsd4: bug in read_buf + +From: Neil Brown + +commit 2bc3c1179c781b359d4f2f3439cb3df72afc17fc upstream. + +When read_buf is called to move over to the next page in the pagelist +of an NFSv4 request, it sets argp->end to essentially a random +number, certainly not an address within the page which argp->p now +points to. So subsequent calls to READ_BUF will think there is much +more than a page of spare space (the cast to u32 ensures an unsigned +comparison) so we can expect to fall off the end of the second +page. + +We never encountered thsi in testing because typically the only +operations which use more than two pages are write-like operations, +which have their own decoding logic. Something like a getattr after a +write may cross a page boundary, but it would be very unusual for it to +cross another boundary after that. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4xdr.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -179,10 +179,10 @@ static __be32 *read_buf(struct nfsd4_com + argp->p = page_address(argp->pagelist[0]); + argp->pagelist++; + if (argp->pagelen < PAGE_SIZE) { +- argp->end = p + (argp->pagelen>>2); ++ argp->end = argp->p + (argp->pagelen>>2); + argp->pagelen = 0; + } else { +- argp->end = p + (PAGE_SIZE>>2); ++ argp->end = argp->p + (PAGE_SIZE>>2); + argp->pagelen -= PAGE_SIZE; + } + memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); +@@ -1115,10 +1115,10 @@ nfsd4_decode_compound(struct nfsd4_compo + argp->p = page_address(argp->pagelist[0]); + argp->pagelist++; + if (argp->pagelen < PAGE_SIZE) { +- argp->end = p + (argp->pagelen>>2); ++ argp->end = argp->p + (argp->pagelen>>2); + argp->pagelen = 0; + } else { +- argp->end = p + (PAGE_SIZE>>2); ++ argp->end = argp->p + (PAGE_SIZE>>2); + argp->pagelen -= PAGE_SIZE; + } + } diff --git a/queue-2.6.27/series b/queue-2.6.27/series index cbd5b756f9a..aad8d57c3e6 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -14,3 +14,6 @@ tty-release_one_tty-forgets-to-put-pids.patch megaraid_sas-fix-for-32bit-apps.patch trace-fix-inappropriate-substraction-on-tracing_pages_allocated-in-trace_free_page.patch clockevent-prevent-dead-lock-on-clockevents_lock.patch +keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch +nfsd4-bug-in-read_buf.patch +usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch diff --git a/queue-2.6.27/usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch b/queue-2.6.27/usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch new file mode 100644 index 00000000000..cec7a64dbcf --- /dev/null +++ b/queue-2.6.27/usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch @@ -0,0 +1,38 @@ +From fa7fe7af146a7b613e36a311eefbbfb5555325d1 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 22 Apr 2010 12:00:52 +0200 +Subject: USB: fix testing the wrong variable in fs_create_by_name() + +From: Dan Carpenter + +commit fa7fe7af146a7b613e36a311eefbbfb5555325d1 upstream. + +There is a typo here. We should be testing "*dentry" which was just +assigned instead of "dentry". This could result in dereferencing an +ERR_PTR inside either usbfs_mkdir() or usbfs_create(). + +Signed-off-by: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/inode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/inode.c ++++ b/drivers/usb/core/inode.c +@@ -510,13 +510,13 @@ static int fs_create_by_name (const char + *dentry = NULL; + mutex_lock(&parent->d_inode->i_mutex); + *dentry = lookup_one_len(name, parent, strlen(name)); +- if (!IS_ERR(dentry)) { ++ if (!IS_ERR(*dentry)) { + if ((mode & S_IFMT) == S_IFDIR) + error = usbfs_mkdir (parent->d_inode, *dentry, mode); + else + error = usbfs_create (parent->d_inode, *dentry, mode); + } else +- error = PTR_ERR(dentry); ++ error = PTR_ERR(*dentry); + mutex_unlock(&parent->d_inode->i_mutex); + + return error; -- 2.47.3