diff options
| author | David Howells <dhowells@redhat.com> | 2009-08-27 08:09:06 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-27 15:22:08 -0400 |
| commit | 9886e836a6a5dbd273dc55b17e713f0a188d137f (patch) | |
| tree | 87f8e3d719ae43d5d5d5911d70d6c7b3aa66be32 | |
| parent | 1e23502cc57cef33455ac7cb9111e3c6d991a894 (diff) | |
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>
| -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) | |||
| 134 | 134 | ||
| 135 | inode = page->mapping->host; | 135 | inode = page->mapping->host; |
| 136 | 136 | ||
| 137 | ASSERT(file != NULL); | 137 | if (file) { |
| 138 | key = file->private_data; | 138 | key = file->private_data; |
| 139 | ASSERT(key != NULL); | 139 | ASSERT(key != NULL); |
| 140 | } else { | ||
| 141 | key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); | ||
| 142 | if (IS_ERR(key)) { | ||
| 143 | ret = PTR_ERR(key); | ||
| 144 | goto error_nokey; | ||
| 145 | } | ||
| 146 | } | ||
| 140 | 147 | ||
| 141 | _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); | 148 | _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); |
| 142 | 149 | ||
| @@ -207,12 +214,17 @@ static int afs_readpage(struct file *file, struct page *page) | |||
| 207 | unlock_page(page); | 214 | unlock_page(page); |
| 208 | } | 215 | } |
| 209 | 216 | ||
| 217 | if (!file) | ||
| 218 | key_put(key); | ||
| 210 | _leave(" = 0"); | 219 | _leave(" = 0"); |
| 211 | return 0; | 220 | return 0; |
| 212 | 221 | ||
| 213 | error: | 222 | error: |
| 214 | SetPageError(page); | 223 | SetPageError(page); |
| 215 | unlock_page(page); | 224 | unlock_page(page); |
| 225 | if (!file) | ||
| 226 | key_put(key); | ||
| 227 | error_nokey: | ||
| 216 | _leave(" = %d", ret); | 228 | _leave(" = %d", ret); |
| 217 | return ret; | 229 | return ret; |
| 218 | } | 230 | } |
