diff options
author | David Howells <dhowells@redhat.com> | 2009-08-27 13:09:06 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-27 12:22:08 -0700 |
commit | 9886e836a6a5dbd273dc55b17e713f0a188d137f (patch) | |
tree | 87f8e3d719ae43d5d5d5911d70d6c7b3aa66be32 /fs/afs/file.c | |
parent | 1e23502cc57cef33455ac7cb9111e3c6d991a894 (diff) | |
download | linux-stable-9886e836a6a5dbd273dc55b17e713f0a188d137f.tar.gz linux-stable-9886e836a6a5dbd273dc55b17e713f0a188d137f.tar.bz2 linux-stable-9886e836a6a5dbd273dc55b17e713f0a188d137f.zip |
AFS: Stop readlink() on AFS crashing due to NULL 'file' ptr
kAFS crashes when asked to read a symbolic link because page_getlink()
passes a NULL file pointer to read_mapping_page(), but afs_readpage()
expects a file pointer from which to extract a key.
Modify afs_readpage() to request the appropriate key from the calling
process's keyrings if a file struct is not supplied with one attached.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/afs/file.c')
-rw-r--r-- | fs/afs/file.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c index 0149dab365e7..681c2a7b013f 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -134,9 +134,16 @@ static int afs_readpage(struct file *file, struct page *page) inode = page->mapping->host; - ASSERT(file != NULL); - key = file->private_data; - ASSERT(key != NULL); + if (file) { + key = file->private_data; + ASSERT(key != NULL); + } else { + key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); + if (IS_ERR(key)) { + ret = PTR_ERR(key); + goto error_nokey; + } + } _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); @@ -207,12 +214,17 @@ static int afs_readpage(struct file *file, struct page *page) unlock_page(page); } + if (!file) + key_put(key); _leave(" = 0"); return 0; error: SetPageError(page); unlock_page(page); + if (!file) + key_put(key); +error_nokey: _leave(" = %d", ret); return ret; } |