Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1594952 > unrolled thread
| Started by | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| First post | 2017-03-08 10:00 +0100 |
| Last post | 2017-03-08 15:40 +0100 |
| Articles | 9 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH 0/5] fs, xfs refcount conversions Elena Reshetova <elena.reshetova@intel.com> - 2017-03-08 10:00 +0100
[PATCH 5/5] fs, xfs: convert xfs_rui_log_item.rui_refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-08 10:00 +0100
[PATCH 1/5] fs, xfs: convert xfs_bui_log_item.bui_refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-08 10:00 +0100
[PATCH 2/5] fs, xfs: convert xfs_efi_log_item.efi_refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-08 10:00 +0100
[PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-08 12:40 +0100
Re: [PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t Christoph Hellwig <hch@infradead.org> - 2017-03-08 17:00 +0100
Re: [PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t Kees Cook <keescook@chromium.org> - 2017-03-08 23:10 +0100
RE: [PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-03-09 08:00 +0100
[PATCH 4/5] fs, xfs: convert xfs_cui_log_item.cui_refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-08 15:40 +0100
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-08 10:00 +0100 |
| Subject | [PATCH 0/5] fs, xfs refcount conversions |
| Message-ID | <tiFBU-3WM-7@gated-at.bofh.it> |
v3:
* fixed header file inclusion
Now when new refcount_t type and API are finally merged
(see include/linux/refcount.h), the following
patches convert various refcounters in the xfs susystem from atomic_t
to refcount_t. By doing this we prevent intentional or accidental
underflows or overflows that can led to use-after-free vulnerabilities.
Elena Reshetova (5):
fs, xfs: convert xfs_bui_log_item.bui_refcount from atomic_t to
refcount_t
fs, xfs: convert xfs_efi_log_item.efi_refcount from atomic_t to
refcount_t
fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t
fs, xfs: convert xfs_cui_log_item.cui_refcount from atomic_t to
refcount_t
fs, xfs: convert xfs_rui_log_item.rui_refcount from atomic_t to
refcount_t
fs/xfs/xfs_bmap_item.c | 4 ++--
fs/xfs/xfs_bmap_item.h | 2 +-
fs/xfs/xfs_extfree_item.c | 4 ++--
fs/xfs/xfs_extfree_item.h | 2 +-
fs/xfs/xfs_linux.h | 1 +
fs/xfs/xfs_log.c | 10 +++++-----
fs/xfs/xfs_log_priv.h | 2 +-
fs/xfs/xfs_refcount_item.c | 4 ++--
fs/xfs/xfs_refcount_item.h | 2 +-
fs/xfs/xfs_rmap_item.c | 4 ++--
fs/xfs/xfs_rmap_item.h | 2 +-
11 files changed, 19 insertions(+), 18 deletions(-)
--
2.7.4
[toc] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-08 10:00 +0100 |
| Subject | [PATCH 5/5] fs, xfs: convert xfs_rui_log_item.rui_refcount from atomic_t to refcount_t |
| Message-ID | <tiFBU-3WM-17@gated-at.bofh.it> |
| In reply to | #1594952 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
fs/xfs/xfs_rmap_item.c | 4 ++--
fs/xfs/xfs_rmap_item.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index 73c8278..5e1664a 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -204,7 +204,7 @@ xfs_rui_init(
ruip->rui_format.rui_nextents = nextents;
ruip->rui_format.rui_id = (uintptr_t)(void *)ruip;
atomic_set(&ruip->rui_next_extent, 0);
- atomic_set(&ruip->rui_refcount, 2);
+ refcount_set(&ruip->rui_refcount, 2);
return ruip;
}
@@ -243,7 +243,7 @@ void
xfs_rui_release(
struct xfs_rui_log_item *ruip)
{
- if (atomic_dec_and_test(&ruip->rui_refcount)) {
+ if (refcount_dec_and_test(&ruip->rui_refcount)) {
xfs_trans_ail_remove(&ruip->rui_item, SHUTDOWN_LOG_IO_ERROR);
xfs_rui_item_free(ruip);
}
diff --git a/fs/xfs/xfs_rmap_item.h b/fs/xfs/xfs_rmap_item.h
index 340c968..1e425a9 100644
--- a/fs/xfs/xfs_rmap_item.h
+++ b/fs/xfs/xfs_rmap_item.h
@@ -64,7 +64,7 @@ struct kmem_zone;
*/
struct xfs_rui_log_item {
struct xfs_log_item rui_item;
- atomic_t rui_refcount;
+ refcount_t rui_refcount;
atomic_t rui_next_extent;
unsigned long rui_flags; /* misc flags */
struct xfs_rui_log_format rui_format;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-08 10:00 +0100 |
| Subject | [PATCH 1/5] fs, xfs: convert xfs_bui_log_item.bui_refcount from atomic_t to refcount_t |
| Message-ID | <tiFBU-3WM-11@gated-at.bofh.it> |
| In reply to | #1594952 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
fs/xfs/xfs_bmap_item.c | 4 ++--
fs/xfs/xfs_bmap_item.h | 2 +-
fs/xfs/xfs_linux.h | 1 +
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index 9bf57c7..33104ad 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -199,7 +199,7 @@ xfs_bui_init(
buip->bui_format.bui_nextents = XFS_BUI_MAX_FAST_EXTENTS;
buip->bui_format.bui_id = (uintptr_t)(void *)buip;
atomic_set(&buip->bui_next_extent, 0);
- atomic_set(&buip->bui_refcount, 2);
+ refcount_set(&buip->bui_refcount, 2);
return buip;
}
@@ -215,7 +215,7 @@ void
xfs_bui_release(
struct xfs_bui_log_item *buip)
{
- if (atomic_dec_and_test(&buip->bui_refcount)) {
+ if (refcount_dec_and_test(&buip->bui_refcount)) {
xfs_trans_ail_remove(&buip->bui_item, SHUTDOWN_LOG_IO_ERROR);
xfs_bui_item_free(buip);
}
diff --git a/fs/xfs/xfs_bmap_item.h b/fs/xfs/xfs_bmap_item.h
index c867daa..7048b14 100644
--- a/fs/xfs/xfs_bmap_item.h
+++ b/fs/xfs/xfs_bmap_item.h
@@ -61,7 +61,7 @@ struct kmem_zone;
*/
struct xfs_bui_log_item {
struct xfs_log_item bui_item;
- atomic_t bui_refcount;
+ refcount_t bui_refcount;
atomic_t bui_next_extent;
unsigned long bui_flags; /* misc flags */
struct xfs_bui_log_format bui_format;
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index 7a989de..09b0396 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -19,6 +19,7 @@
#define __XFS_LINUX__
#include <linux/types.h>
+#include <linux/refcount.h>
/*
* Kernel specific type declarations for XFS
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-08 10:00 +0100 |
| Subject | [PATCH 2/5] fs, xfs: convert xfs_efi_log_item.efi_refcount from atomic_t to refcount_t |
| Message-ID | <tiFBU-3WM-19@gated-at.bofh.it> |
| In reply to | #1594952 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
fs/xfs/xfs_extfree_item.c | 4 ++--
fs/xfs/xfs_extfree_item.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index d7bc149..4e0acf0 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -220,7 +220,7 @@ xfs_efi_init(
efip->efi_format.efi_nextents = nextents;
efip->efi_format.efi_id = (uintptr_t)(void *)efip;
atomic_set(&efip->efi_next_extent, 0);
- atomic_set(&efip->efi_refcount, 2);
+ refcount_set(&efip->efi_refcount, 2);
return efip;
}
@@ -290,7 +290,7 @@ void
xfs_efi_release(
struct xfs_efi_log_item *efip)
{
- if (atomic_dec_and_test(&efip->efi_refcount)) {
+ if (refcount_dec_and_test(&efip->efi_refcount)) {
xfs_trans_ail_remove(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR);
xfs_efi_item_free(efip);
}
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index a32c794..fadf736 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -64,7 +64,7 @@ struct kmem_zone;
*/
typedef struct xfs_efi_log_item {
xfs_log_item_t efi_item;
- atomic_t efi_refcount;
+ refcount_t efi_refcount;
atomic_t efi_next_extent;
unsigned long efi_flags; /* misc flags */
xfs_efi_log_format_t efi_format;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-08 12:40 +0100 |
| Subject | [PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t |
| Message-ID | <tiI6K-5Wo-13@gated-at.bofh.it> |
| In reply to | #1594952 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
fs/xfs/xfs_log.c | 10 +++++-----
fs/xfs/xfs_log_priv.h | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index b1469f0..c127fa0 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -3500,8 +3500,8 @@ void
xfs_log_ticket_put(
xlog_ticket_t *ticket)
{
- ASSERT(atomic_read(&ticket->t_ref) > 0);
- if (atomic_dec_and_test(&ticket->t_ref))
+ ASSERT(refcount_read(&ticket->t_ref) > 0);
+ if (refcount_dec_and_test(&ticket->t_ref))
kmem_zone_free(xfs_log_ticket_zone, ticket);
}
@@ -3509,8 +3509,8 @@ xlog_ticket_t *
xfs_log_ticket_get(
xlog_ticket_t *ticket)
{
- ASSERT(atomic_read(&ticket->t_ref) > 0);
- atomic_inc(&ticket->t_ref);
+ ASSERT(refcount_read(&ticket->t_ref) > 0);
+ refcount_inc(&ticket->t_ref);
return ticket;
}
@@ -3632,7 +3632,7 @@ xlog_ticket_alloc(
unit_res = xfs_log_calc_unit_res(log->l_mp, unit_bytes);
- atomic_set(&tic->t_ref, 1);
+ refcount_set(&tic->t_ref, 1);
tic->t_task = current;
INIT_LIST_HEAD(&tic->t_queue);
tic->t_unit_res = unit_res;
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index c2604a5..3fc4aba 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -168,7 +168,7 @@ typedef struct xlog_ticket {
struct list_head t_queue; /* reserve/write queue */
struct task_struct *t_task; /* task that owns this ticket */
xlog_tid_t t_tid; /* transaction identifier : 4 */
- atomic_t t_ref; /* ticket reference count : 4 */
+ refcount_t t_ref; /* ticket reference count : 4 */
int t_curr_res; /* current reservation in bytes : 4 */
int t_unit_res; /* unit reservation in bytes : 4 */
char t_ocnt; /* original count : 1 */
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@infradead.org> |
|---|---|
| Date | 2017-03-08 17:00 +0100 |
| Subject | Re: [PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t |
| Message-ID | <tiMam-bQ-25@gated-at.bofh.it> |
| In reply to | #1595079 |
> - ASSERT(atomic_read(&ticket->t_ref) > 0); > - atomic_inc(&ticket->t_ref); > + ASSERT(refcount_read(&ticket->t_ref) > 0); > + refcount_inc(&ticket->t_ref); With strict refcount semantics refcount_inc should check that the count is larger than 0, otherwise we'd need to use recount_inc_not_zero or whatever you're going to call it. Is that something the recount code does / could do?
[toc] | [prev] | [next] | [standalone]
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Date | 2017-03-08 23:10 +0100 |
| Subject | Re: [PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t |
| Message-ID | <tiRWp-4gI-9@gated-at.bofh.it> |
| In reply to | #1595312 |
On Wed, Mar 8, 2017 at 7:50 AM, Christoph Hellwig <hch@infradead.org> wrote: >> - ASSERT(atomic_read(&ticket->t_ref) > 0); >> - atomic_inc(&ticket->t_ref); >> + ASSERT(refcount_read(&ticket->t_ref) > 0); >> + refcount_inc(&ticket->t_ref); > > With strict refcount semantics refcount_inc should check that > the count is larger than 0, otherwise we'd need to use > recount_inc_not_zero or whatever you're going to call it. > > Is that something the recount code does / could do? Yes, refcount_inc() will not increment from 0 and WARNs. It looks like xfs's ASSERT is also a warn (though with XFS-specific formatting), so perhaps the ASSERT could be dropped? IIUC, Elena's approach to these changes was to be conservative about removing the existing checks. -Kees -- Kees Cook Pixel Security
[toc] | [prev] | [next] | [standalone]
| From | "Reshetova, Elena" <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-09 08:00 +0100 |
| Subject | RE: [PATCH 3/5] fs, xfs: convert xlog_ticket.t_ref from atomic_t to refcount_t |
| Message-ID | <tj0dl-1m3-17@gated-at.bofh.it> |
| In reply to | #1595549 |
> On Wed, Mar 8, 2017 at 7:50 AM, Christoph Hellwig <hch@infradead.org> wrote: > >> - ASSERT(atomic_read(&ticket->t_ref) > 0); > >> - atomic_inc(&ticket->t_ref); > >> + ASSERT(refcount_read(&ticket->t_ref) > 0); > >> + refcount_inc(&ticket->t_ref); > > > > With strict refcount semantics refcount_inc should check that > > the count is larger than 0, otherwise we'd need to use > > recount_inc_not_zero or whatever you're going to call it. > > > > Is that something the recount code does / could do? > > Yes, refcount_inc() will not increment from 0 and WARNs. It looks like > xfs's ASSERT is also a warn (though with XFS-specific formatting), so > perhaps the ASSERT could be dropped? IIUC, Elena's approach to these > changes was to be conservative about removing the existing checks. I am removing the existing WARNs now where they are 100% not needed, but leaving the ones like this ASSERT, because I am thinking that you might have test cases that are dependent on these ASSERTs with specific formatting and I don't want to break them. If you don't need them, I can remove them also. Best Regards, Elena > > -Kees > > -- > Kees Cook > Pixel Security
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-08 15:40 +0100 |
| Subject | [PATCH 4/5] fs, xfs: convert xfs_cui_log_item.cui_refcount from atomic_t to refcount_t |
| Message-ID | <tiKUW-7Oh-3@gated-at.bofh.it> |
| In reply to | #1594952 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
fs/xfs/xfs_refcount_item.c | 4 ++--
fs/xfs/xfs_refcount_item.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index 6e4c744..61bc570 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -205,7 +205,7 @@ xfs_cui_init(
cuip->cui_format.cui_nextents = nextents;
cuip->cui_format.cui_id = (uintptr_t)(void *)cuip;
atomic_set(&cuip->cui_next_extent, 0);
- atomic_set(&cuip->cui_refcount, 2);
+ refcount_set(&cuip->cui_refcount, 2);
return cuip;
}
@@ -221,7 +221,7 @@ void
xfs_cui_release(
struct xfs_cui_log_item *cuip)
{
- if (atomic_dec_and_test(&cuip->cui_refcount)) {
+ if (refcount_dec_and_test(&cuip->cui_refcount)) {
xfs_trans_ail_remove(&cuip->cui_item, SHUTDOWN_LOG_IO_ERROR);
xfs_cui_item_free(cuip);
}
diff --git a/fs/xfs/xfs_refcount_item.h b/fs/xfs/xfs_refcount_item.h
index 5b74ddd..abc0377 100644
--- a/fs/xfs/xfs_refcount_item.h
+++ b/fs/xfs/xfs_refcount_item.h
@@ -63,7 +63,7 @@ struct kmem_zone;
*/
struct xfs_cui_log_item {
struct xfs_log_item cui_item;
- atomic_t cui_refcount;
+ refcount_t cui_refcount;
atomic_t cui_next_extent;
unsigned long cui_flags; /* misc flags */
struct xfs_cui_log_format cui_format;
--
2.7.4
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web