diff options
| author | Shreyas Siravara <sshreyas@fb.com> | 2017-12-07 08:00:16 -0800 | 
|---|---|---|
| committer | Jeff Darcy <jeff@pl.atyp.us> | 2017-12-08 22:33:20 +0000 | 
| commit | 1926cada4a7acf48aa7cbf5ef8bb8942ae10b522 (patch) | |
| tree | 060a48ca983a9cb6052865cf2d44ae01d8ae26a9 | |
| parent | 742a4eed244833761697646044f20675d1411292 (diff) | |
nfs: Reference count export items
Export items are used in the auth cache and need to be reference
counted to avoid use-after free bugs.
Change-Id: I5cdcdc1cc6abad26c7077d66a14f263da07678ac
BUG: 1522847
Signed-off-by: Shreyas Siravara <sshreyas@fb.com>
| -rw-r--r-- | xlators/nfs/server/src/auth-cache.c | 8 | ||||
| -rw-r--r-- | xlators/nfs/server/src/exports.c | 45 | ||||
| -rw-r--r-- | xlators/nfs/server/src/exports.h | 1 | 
3 files changed, 32 insertions, 22 deletions
diff --git a/xlators/nfs/server/src/auth-cache.c b/xlators/nfs/server/src/auth-cache.c index 2b37a7f06bd..a1aacaba61a 100644 --- a/xlators/nfs/server/src/auth-cache.c +++ b/xlators/nfs/server/src/auth-cache.c @@ -232,6 +232,8 @@ auth_cache_get (struct auth_cache *cache, char *hashkey,                  if (_auth_cache_expired (cache, lookup_res)) {                          ret = ENTRY_EXPIRED; +                        GF_REF_PUT (lookup_res->item); +                        lookup_res->item = NULL;                          /* free entry and remove from the cache */                          GF_FREE (lookup_res); @@ -473,7 +475,11 @@ cache_nfs_fh (struct auth_cache *cache, struct nfs3_fh *fh,          }          entry->timestamp = time (NULL); -        entry->item = export_item; +        /* Update entry->item if it is pointing to a different export_item */ +        if (entry->item && entry->item != export_item) { +                GF_REF_PUT (entry->item); +        } +        entry->item = GF_REF_GET (export_item);          ret = auth_cache_add (cache, hashkey, entry);          GF_REF_PUT (entry); diff --git a/xlators/nfs/server/src/exports.c b/xlators/nfs/server/src/exports.c index 83aec254040..75780587147 100644 --- a/xlators/nfs/server/src/exports.c +++ b/xlators/nfs/server/src/exports.c @@ -227,6 +227,24 @@ out:  }  /** + * _export_item_deinit -- Free memory used by an export item + * + * @expdir : Pointer to the export item to free + * + * Not for external use. + */ +static void +_export_item_deinit (struct export_item *item) +{ +        if (!item) +                return; + +        _export_options_deinit (item->opts); +        GF_FREE (item->name); +        GF_FREE (item); +} + +/**   * _export_item_init -- Initialize an export item structure   *   * @return  : success: Pointer to an allocated exports item struct @@ -240,32 +258,17 @@ _export_item_init ()          struct export_item *item = GF_CALLOC (1, sizeof (*item),                                                gf_common_mt_nfs_exports); -        if (!item) +        if (item) { +                GF_REF_INIT(item, _export_item_deinit); +        } else {                  gf_msg (GF_EXP, GF_LOG_CRITICAL, ENOMEM, NFS_MSG_NO_MEMORY,                          "Failed to allocate export item!"); +        }          return item;  }  /** - * _export_item_deinit -- Free memory used by an export item - * - * @expdir : Pointer to the export item to free - * - * Not for external use. - */ -static void -_export_item_deinit (struct export_item *item) -{ -        if (!item) -                return; - -        _export_options_deinit (item->opts); -        GF_FREE (item->name); -        GF_FREE (item); -} - -/**   * _export_host_init -- Initialize an export options struct   *   * @return  : success: Pointer to an allocated options struct @@ -355,7 +358,7 @@ static int  __exp_dict_free_walk (dict_t *dict, char *key, data_t *val, void *tmp)  {          if (val) { -                _export_item_deinit ((struct export_item *)val->data); +                GF_REF_PUT ((struct export_item *)val->data);                  val->data = NULL;                  dict_del (dict, key);          } @@ -768,7 +771,7 @@ __exp_line_ng_host_str_parse (char *str, struct export_item **exp_item)          ret = __exp_line_opt_parse (optstr, &exp_opts);          if (ret != 0) {                  /* Bubble up the error to the caller */ -                _export_item_deinit (item); +                GF_REF_PUT (item);                  goto out;          } diff --git a/xlators/nfs/server/src/exports.h b/xlators/nfs/server/src/exports.h index 0079b9a3deb..87795dadaee 100644 --- a/xlators/nfs/server/src/exports.h +++ b/xlators/nfs/server/src/exports.h @@ -55,6 +55,7 @@ struct export_options {  struct export_item {          char                  *name;  /* Name of the export item */          struct export_options *opts;  /* NFS Options */ +        GF_REF_DECL;  };  struct export_dir {  | 
