fs, nfs: convert nfs_client.cl_count from atomic_t to refcount_t
atomic_t variables are currently used to implement reference counters with the following properties: - counter is initialized to 1 using atomic_set() - a resource is freed upon counter reaching zero - once counter reaches zero, its further increments aren't allowed - counter schema uses basic atomic operations (set, inc, inc_not_zero, dec_and_test, etc.) Such atomic variables should be converted to a newly provided refcount_t type and API that prevents accidental counter overflows and underflows. This is important since overflows and underflows can lead to use-after-free situation and be exploitable. The variable nfs_client.cl_count is used as pure reference counter. Convert it to refcount_t and fix up the operations. Suggested-by: Kees Cook <keescook@chromium.org> Reviewed-by: David Windsor <dwindsor@gmail.com> Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:

committed by
Anna Schumaker

parent
2f62b5aa48
commit
212bf41d88
@@ -471,10 +471,10 @@ filelayout_read_pagelist(struct nfs_pgio_header *hdr)
|
||||
return PNFS_NOT_ATTEMPTED;
|
||||
|
||||
dprintk("%s USE DS: %s cl_count %d\n", __func__,
|
||||
ds->ds_remotestr, atomic_read(&ds->ds_clp->cl_count));
|
||||
ds->ds_remotestr, refcount_read(&ds->ds_clp->cl_count));
|
||||
|
||||
/* No multipath support. Use first DS */
|
||||
atomic_inc(&ds->ds_clp->cl_count);
|
||||
refcount_inc(&ds->ds_clp->cl_count);
|
||||
hdr->ds_clp = ds->ds_clp;
|
||||
hdr->ds_commit_idx = idx;
|
||||
fh = nfs4_fl_select_ds_fh(lseg, j);
|
||||
@@ -515,10 +515,10 @@ filelayout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
|
||||
|
||||
dprintk("%s ino %lu sync %d req %zu@%llu DS: %s cl_count %d\n",
|
||||
__func__, hdr->inode->i_ino, sync, (size_t) hdr->args.count,
|
||||
offset, ds->ds_remotestr, atomic_read(&ds->ds_clp->cl_count));
|
||||
offset, ds->ds_remotestr, refcount_read(&ds->ds_clp->cl_count));
|
||||
|
||||
hdr->pgio_done_cb = filelayout_write_done_cb;
|
||||
atomic_inc(&ds->ds_clp->cl_count);
|
||||
refcount_inc(&ds->ds_clp->cl_count);
|
||||
hdr->ds_clp = ds->ds_clp;
|
||||
hdr->ds_commit_idx = idx;
|
||||
fh = nfs4_fl_select_ds_fh(lseg, j);
|
||||
@@ -1064,9 +1064,9 @@ static int filelayout_initiate_commit(struct nfs_commit_data *data, int how)
|
||||
goto out_err;
|
||||
|
||||
dprintk("%s ino %lu, how %d cl_count %d\n", __func__,
|
||||
data->inode->i_ino, how, atomic_read(&ds->ds_clp->cl_count));
|
||||
data->inode->i_ino, how, refcount_read(&ds->ds_clp->cl_count));
|
||||
data->commit_done_cb = filelayout_commit_done_cb;
|
||||
atomic_inc(&ds->ds_clp->cl_count);
|
||||
refcount_inc(&ds->ds_clp->cl_count);
|
||||
data->ds_clp = ds->ds_clp;
|
||||
fh = select_ds_fh_from_commit(lseg, data->ds_commit_index);
|
||||
if (fh)
|
||||
|
Reference in New Issue
Block a user