Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
8d5658c9
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
8d5658c9
编写于
4月 10, 2007
作者:
T
Trond Myklebust
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
NFS: Fix a buffer overflow in the allocation of struct nfs_read/writedata
Signed-off-by:
N
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
上级
c63c7b05
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
41 addition
and
24 deletion
+41
-24
fs/nfs/direct.c
fs/nfs/direct.c
+3
-2
fs/nfs/internal.h
fs/nfs/internal.h
+12
-0
fs/nfs/pagelist.c
fs/nfs/pagelist.c
+8
-2
fs/nfs/read.c
fs/nfs/read.c
+9
-10
fs/nfs/write.c
fs/nfs/write.c
+5
-6
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+2
-2
include/linux/nfs_page.h
include/linux/nfs_page.h
+2
-2
未找到文件。
fs/nfs/direct.c
浏览文件 @
8d5658c9
...
...
@@ -54,6 +54,7 @@
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include "internal.h"
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_VFS
...
...
@@ -271,7 +272,7 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
bytes
=
min
(
rsize
,
count
);
result
=
-
ENOMEM
;
data
=
nfs_readdata_alloc
(
pgbase
+
bytes
);
data
=
nfs_readdata_alloc
(
nfs_page_array_len
(
pgbase
,
bytes
)
);
if
(
unlikely
(
!
data
))
break
;
...
...
@@ -602,7 +603,7 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
bytes
=
min
(
wsize
,
count
);
result
=
-
ENOMEM
;
data
=
nfs_writedata_alloc
(
pgbase
+
bytes
);
data
=
nfs_writedata_alloc
(
nfs_page_array_len
(
pgbase
,
bytes
)
);
if
(
unlikely
(
!
data
))
break
;
...
...
fs/nfs/internal.h
浏览文件 @
8d5658c9
...
...
@@ -231,3 +231,15 @@ unsigned int nfs_page_length(struct page *page)
}
return
0
;
}
/*
* Determine the number of pages in an array of length 'len' and
* with a base offset of 'base'
*/
static
inline
unsigned
int
nfs_page_array_len
(
unsigned
int
base
,
size_t
len
)
{
return
((
unsigned
long
)
len
+
(
unsigned
long
)
base
+
PAGE_SIZE
-
1
)
>>
PAGE_SHIFT
;
}
fs/nfs/pagelist.c
浏览文件 @
8d5658c9
...
...
@@ -18,6 +18,8 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include "internal.h"
#define NFS_PARANOIA 1
static
struct
kmem_cache
*
nfs_page_cachep
;
...
...
@@ -231,7 +233,7 @@ nfs_wait_on_request(struct nfs_page *req)
*/
void
nfs_pageio_init
(
struct
nfs_pageio_descriptor
*
desc
,
struct
inode
*
inode
,
int
(
*
doio
)(
struct
inode
*
,
struct
list_head
*
,
size_t
,
int
),
int
(
*
doio
)(
struct
inode
*
,
struct
list_head
*
,
unsigned
int
,
size_t
,
int
),
unsigned
int
bsize
,
int
io_flags
)
{
...
...
@@ -298,8 +300,10 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
* since nfs_flush_multi and nfs_pagein_multi assume you
* can have only one struct nfs_page.
*/
if
(
desc
->
pg_bsize
<
PAGE_SIZE
)
return
0
;
newlen
+=
desc
->
pg_count
;
if
(
desc
->
pg_base
+
newlen
>
desc
->
pg_bsize
)
if
(
newlen
>
desc
->
pg_bsize
)
return
0
;
prev
=
nfs_list_entry
(
desc
->
pg_list
.
prev
);
if
(
!
nfs_can_coalesce_requests
(
prev
,
req
))
...
...
@@ -320,6 +324,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
if
(
!
list_empty
(
&
desc
->
pg_list
))
{
int
error
=
desc
->
pg_doio
(
desc
->
pg_inode
,
&
desc
->
pg_list
,
nfs_page_array_len
(
desc
->
pg_base
,
desc
->
pg_count
),
desc
->
pg_count
,
desc
->
pg_ioflags
);
if
(
error
<
0
)
...
...
fs/nfs/read.c
浏览文件 @
8d5658c9
...
...
@@ -27,8 +27,8 @@
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
static
int
nfs_pagein_multi
(
struct
inode
*
,
struct
list_head
*
,
size_t
,
int
);
static
int
nfs_pagein_one
(
struct
inode
*
,
struct
list_head
*
,
size_t
,
int
);
static
int
nfs_pagein_multi
(
struct
inode
*
,
struct
list_head
*
,
unsigned
int
,
size_t
,
int
);
static
int
nfs_pagein_one
(
struct
inode
*
,
struct
list_head
*
,
unsigned
int
,
size_t
,
int
);
static
const
struct
rpc_call_ops
nfs_read_partial_ops
;
static
const
struct
rpc_call_ops
nfs_read_full_ops
;
...
...
@@ -37,9 +37,8 @@ static mempool_t *nfs_rdata_mempool;
#define MIN_POOL_READ (32)
struct
nfs_read_data
*
nfs_readdata_alloc
(
size_t
len
)
struct
nfs_read_data
*
nfs_readdata_alloc
(
unsigned
int
pagecount
)
{
unsigned
int
pagecount
=
(
len
+
PAGE_SIZE
-
1
)
>>
PAGE_SHIFT
;
struct
nfs_read_data
*
p
=
mempool_alloc
(
nfs_rdata_mempool
,
GFP_NOFS
);
if
(
p
)
{
...
...
@@ -135,9 +134,9 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
nfs_list_add_request
(
new
,
&
one_request
);
if
(
NFS_SERVER
(
inode
)
->
rsize
<
PAGE_CACHE_SIZE
)
nfs_pagein_multi
(
inode
,
&
one_request
,
len
,
0
);
nfs_pagein_multi
(
inode
,
&
one_request
,
1
,
len
,
0
);
else
nfs_pagein_one
(
inode
,
&
one_request
,
len
,
0
);
nfs_pagein_one
(
inode
,
&
one_request
,
1
,
len
,
0
);
return
0
;
}
...
...
@@ -234,7 +233,7 @@ static void nfs_execute_read(struct nfs_read_data *data)
* won't see the new data until our attribute cache is updated. This is more
* or less conventional NFS client behavior.
*/
static
int
nfs_pagein_multi
(
struct
inode
*
inode
,
struct
list_head
*
head
,
size_t
count
,
int
flags
)
static
int
nfs_pagein_multi
(
struct
inode
*
inode
,
struct
list_head
*
head
,
unsigned
int
npages
,
size_t
count
,
int
flags
)
{
struct
nfs_page
*
req
=
nfs_list_entry
(
head
->
next
);
struct
page
*
page
=
req
->
wb_page
;
...
...
@@ -250,7 +249,7 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, size_t
do
{
size_t
len
=
min
(
nbytes
,
rsize
);
data
=
nfs_readdata_alloc
(
len
);
data
=
nfs_readdata_alloc
(
1
);
if
(
!
data
)
goto
out_bad
;
INIT_LIST_HEAD
(
&
data
->
pages
);
...
...
@@ -291,13 +290,13 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, size_t
return
-
ENOMEM
;
}
static
int
nfs_pagein_one
(
struct
inode
*
inode
,
struct
list_head
*
head
,
size_t
count
,
int
flags
)
static
int
nfs_pagein_one
(
struct
inode
*
inode
,
struct
list_head
*
head
,
unsigned
int
npages
,
size_t
count
,
int
flags
)
{
struct
nfs_page
*
req
;
struct
page
**
pages
;
struct
nfs_read_data
*
data
;
data
=
nfs_readdata_alloc
(
count
);
data
=
nfs_readdata_alloc
(
npages
);
if
(
!
data
)
goto
out_bad
;
...
...
fs/nfs/write.c
浏览文件 @
8d5658c9
...
...
@@ -72,9 +72,8 @@ void nfs_commit_free(struct nfs_write_data *wdata)
call_rcu_bh
(
&
wdata
->
task
.
u
.
tk_rcu
,
nfs_commit_rcu_free
);
}
struct
nfs_write_data
*
nfs_writedata_alloc
(
size_t
len
)
struct
nfs_write_data
*
nfs_writedata_alloc
(
unsigned
int
pagecount
)
{
unsigned
int
pagecount
=
(
len
+
PAGE_SIZE
-
1
)
>>
PAGE_SHIFT
;
struct
nfs_write_data
*
p
=
mempool_alloc
(
nfs_wdata_mempool
,
GFP_NOFS
);
if
(
p
)
{
...
...
@@ -832,7 +831,7 @@ static void nfs_execute_write(struct nfs_write_data *data)
* Generate multiple small requests to write out a single
* contiguous dirty area on one page.
*/
static
int
nfs_flush_multi
(
struct
inode
*
inode
,
struct
list_head
*
head
,
size_t
count
,
int
how
)
static
int
nfs_flush_multi
(
struct
inode
*
inode
,
struct
list_head
*
head
,
unsigned
int
npages
,
size_t
count
,
int
how
)
{
struct
nfs_page
*
req
=
nfs_list_entry
(
head
->
next
);
struct
page
*
page
=
req
->
wb_page
;
...
...
@@ -848,7 +847,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, size_t c
do
{
size_t
len
=
min
(
nbytes
,
wsize
);
data
=
nfs_writedata_alloc
(
len
);
data
=
nfs_writedata_alloc
(
1
);
if
(
!
data
)
goto
out_bad
;
list_add
(
&
data
->
pages
,
&
list
);
...
...
@@ -897,13 +896,13 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, size_t c
* This is the case if nfs_updatepage detects a conflicting request
* that has been written but not committed.
*/
static
int
nfs_flush_one
(
struct
inode
*
inode
,
struct
list_head
*
head
,
size_t
count
,
int
how
)
static
int
nfs_flush_one
(
struct
inode
*
inode
,
struct
list_head
*
head
,
unsigned
int
npages
,
size_t
count
,
int
how
)
{
struct
nfs_page
*
req
;
struct
page
**
pages
;
struct
nfs_write_data
*
data
;
data
=
nfs_writedata_alloc
(
count
);
data
=
nfs_writedata_alloc
(
npages
);
if
(
!
data
)
goto
out_bad
;
...
...
include/linux/nfs_fs.h
浏览文件 @
8d5658c9
...
...
@@ -455,7 +455,7 @@ nfs_have_writebacks(struct inode *inode)
/*
* Allocate nfs_write_data structures
*/
extern
struct
nfs_write_data
*
nfs_writedata_alloc
(
size_t
len
);
extern
struct
nfs_write_data
*
nfs_writedata_alloc
(
unsigned
int
npages
);
/*
* linux/fs/nfs/read.c
...
...
@@ -469,7 +469,7 @@ extern void nfs_readdata_release(void *data);
/*
* Allocate nfs_read_data structures
*/
extern
struct
nfs_read_data
*
nfs_readdata_alloc
(
size_t
len
);
extern
struct
nfs_read_data
*
nfs_readdata_alloc
(
unsigned
int
npages
);
/*
* linux/fs/nfs3proc.c
...
...
include/linux/nfs_page.h
浏览文件 @
8d5658c9
...
...
@@ -55,7 +55,7 @@ struct nfs_pageio_descriptor {
unsigned
int
pg_base
;
struct
inode
*
pg_inode
;
int
(
*
pg_doio
)(
struct
inode
*
,
struct
list_head
*
,
size_t
,
int
);
int
(
*
pg_doio
)(
struct
inode
*
,
struct
list_head
*
,
unsigned
int
,
size_t
,
int
);
int
pg_ioflags
;
int
pg_error
;
};
...
...
@@ -75,7 +75,7 @@ extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head, struct
unsigned
long
idx_start
,
unsigned
int
npages
);
extern
void
nfs_pageio_init
(
struct
nfs_pageio_descriptor
*
desc
,
struct
inode
*
inode
,
int
(
*
doio
)(
struct
inode
*
,
struct
list_head
*
,
size_t
,
int
),
int
(
*
doio
)(
struct
inode
*
,
struct
list_head
*
,
unsigned
int
,
size_t
,
int
),
size_t
bsize
,
int
how
);
extern
int
nfs_pageio_add_request
(
struct
nfs_pageio_descriptor
*
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录