Re: [nfs-utils PATCH v2 1/2] libnsm.a: refactor nsm_setup_pathnames() and nsm_make_pathname()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 01 2017, Scott Mayhew wrote:

> Move the logic in nsm_setup_pathnames() and nsm_make_pathname() to
> similar generic functions in libmisc.a so that the exportfs and
> rpc.mountd programs can make use of them later.
>
> Signed-off-by: Scott Mayhew <smayhew@xxxxxxxxxx>
> ---
>  support/include/misc.h   |   3 ++
>  support/misc/Makefile.am |   2 +-
>  support/misc/file.c      | 110 +++++++++++++++++++++++++++++++++++++++++++++++
>  support/nsm/file.c       |  45 ++-----------------
>  utils/statd/Makefile.am  |   1 +
>  5 files changed, 118 insertions(+), 43 deletions(-)
>  create mode 100644 support/misc/file.c
>
> diff --git a/support/include/misc.h b/support/include/misc.h
> index eedc1fe..6f9b47c 100644
> --- a/support/include/misc.h
> +++ b/support/include/misc.h
> @@ -15,6 +15,9 @@
>  int	randomkey(unsigned char *keyout, int len);
>  int	weakrandomkey(unsigned char *keyout, int len);
>  
> +char *generic_make_pathname(const char *, const char *);
> +_Bool generic_setup_basedir(const char *, const char *, char *);
> +
>  extern int is_mountpoint(char *path);
>  
>  /* size of the file pointer buffers for rpc procfs files */
> diff --git a/support/misc/Makefile.am b/support/misc/Makefile.am
> index 1048580..8936b0d 100644
> --- a/support/misc/Makefile.am
> +++ b/support/misc/Makefile.am
> @@ -1,6 +1,6 @@
>  ## Process this file with automake to produce Makefile.in
>  
>  noinst_LIBRARIES = libmisc.a
> -libmisc_a_SOURCES = tcpwrapper.c from_local.c mountpoint.c
> +libmisc_a_SOURCES = tcpwrapper.c from_local.c mountpoint.c file.c
>  
>  MAINTAINERCLEANFILES = Makefile.in
> diff --git a/support/misc/file.c b/support/misc/file.c
> new file mode 100644
> index 0000000..ee6d264
> --- /dev/null
> +++ b/support/misc/file.c
> @@ -0,0 +1,110 @@
> +/*
> + * Copyright 2009 Oracle.  All rights reserved.
> + * Copyright 2017 Red Hat, Inc.  All rights reserved.
> + *
> + * This file is part of nfs-utils.
> + *
> + * nfs-utils is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * nfs-utils is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with nfs-utils.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <sys/stat.h>
> +
> +#include <string.h>
> +#include <libgen.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <dirent.h>
> +#include <stdlib.h>
> +#include <stdbool.h>
> +
> +#include "xlog.h"
> +#include "misc.h"
> +
> +static _Bool
> +error_check(const int len, const size_t buflen)
> +{
> +	return (len < 0) || ((size_t)len >= buflen);
> +}
> +
> +/*
> + * Returns a dynamically allocated, '\0'-terminated buffer
> + * containing an appropriate pathname, or NULL if an error
> + * occurs.  Caller must free the returned result with free(3).
> + */
> +__attribute__((__malloc__))
> +char *
> +generic_make_pathname(const char *base, const char *leaf)
> +{
> +	size_t size;
> +	char *path;
> +	int len;
> +
> +	size = strlen(base) + strlen(leaf) + 2;
> +	if (size > PATH_MAX)
> +		return NULL;
> +
> +	path = malloc(size);
> +	if (path == NULL)
> +		return NULL;
> +
> +	len = snprintf(path, size, "%s/%s", base, leaf);
> +	if (error_check(len, size)) {
> +		free(path);
> +		return NULL;
> +	}
> +
> +	return path;
> +}
> +
> +
> +/**
> + * generic_setup_basedir - set up basedir
> + * @progname: C string containing name of program, for error messages
> + * @parentdir: C string containing pathname to on-disk state, or NULL
> + * @base: C string used to contain the basedir that is set up
> + *
> + * This runs before logging is set up, so error messages are directed
> + * to stderr.
> + *
> + * Returns true and sets up our basedir, if @parentdir was valid
> + * and usable; otherwise false is returned.
> + */
> +_Bool
> +generic_setup_basedir(const char *progname, const char *parentdir, char *base)
> +{
> +	static char buf[PATH_MAX];
> +	struct stat st;
> +	char *path;
> +
> +	/* First: test length of name and whether it exists */
> +	if (lstat(parentdir, &st) == -1) {
> +		(void)fprintf(stderr, "%s: Failed to stat %s: %s",
> +				progname, parentdir, strerror(errno));
> +		return false;
> +	}
> +
> +	/* Ensure we have a clean directory pathname */
> +	strncpy(buf, parentdir, sizeof(buf));
> +	path = dirname(buf);
> +	if (*path == '.') {
> +		(void)fprintf(stderr, "%s: Unusable directory %s",
> +				progname, parentdir);
> +		return false;
> +	}
> +
> +	xlog(D_CALL, "Using %s as the state directory", parentdir);
> +	strncpy(base, parentdir, strlen(base));

This isn't good.
"base" is either nsm_base_dirname or state_base_dirname with are
both PATH_MAX long char arrays which were initialised to
e.g. /var/lib/nfs.
So strlen(base) is about 12.
So as long as parentdir is shorter than NFS_STATEDIR or NSM_DEFAULT_STATEDIR
this will work.  If it is longer, it gets truncated.

I think this should be 'strncpy(base,parentdir,PATH_MAX)' or similar.

> +	base[strlen(parentdir)] = '\0';

If parentdir is too long, this isn't safe, and if it is not too long,
you can just use strcpy()...


Apart from that:
  Reviewed-by: NeilBrown <neilb@xxxxxxxx>

(I'd rather not have that error_check() function, it just obscures the
 code I think.  But as you obviously copied it from the original making
 minimal changes, it probably makes sense to leave it as it is)

Thanks,
NeilBrown


> +	return true;
> +}
> diff --git a/support/nsm/file.c b/support/nsm/file.c
> index aafa755..865be54 100644
> --- a/support/nsm/file.c
> +++ b/support/nsm/file.c
> @@ -88,6 +88,7 @@
>  
>  #include "xlog.h"
>  #include "nsm.h"
> +#include "misc.h"
>  
>  #define RPCARGSLEN	(4 * (8 + 1))
>  #define LINELEN		(RPCARGSLEN + SM_PRIV_SIZE * 2 + 1)
> @@ -170,25 +171,7 @@ __attribute__((__malloc__))
>  static char *
>  nsm_make_pathname(const char *directory)
>  {
> -	size_t size;
> -	char *path;
> -	int len;
> -
> -	size = strlen(nsm_base_dirname) + strlen(directory) + 2;
> -	if (size > PATH_MAX)
> -		return NULL;
> -
> -	path = malloc(size);
> -	if (path == NULL)
> -		return NULL;
> -
> -	len = snprintf(path, size, "%s/%s", nsm_base_dirname, directory);
> -	if (error_check(len, size)) {
> -		free(path);
> -		return NULL;
> -	}
> -
> -	return path;
> +	return generic_make_pathname(nsm_base_dirname, directory);
>  }
>  
>  /*
> @@ -293,29 +276,7 @@ out:
>  _Bool
>  nsm_setup_pathnames(const char *progname, const char *parentdir)
>  {
> -	static char buf[PATH_MAX];
> -	struct stat st;
> -	char *path;
> -
> -	/* First: test length of name and whether it exists */
> -	if (lstat(parentdir, &st) == -1) {
> -		(void)fprintf(stderr, "%s: Failed to stat %s: %s",
> -				progname, parentdir, strerror(errno));
> -		return false;
> -	}
> -
> -	/* Ensure we have a clean directory pathname */
> -	strncpy(buf, parentdir, sizeof(buf));
> -	path = dirname(buf);
> -	if (*path == '.') {
> -		(void)fprintf(stderr, "%s: Unusable directory %s",
> -				progname, parentdir);
> -		return false;
> -	}
> -
> -	xlog(D_CALL, "Using %s as the state directory", parentdir);
> -	strncpy(nsm_base_dirname, parentdir, sizeof(nsm_base_dirname));
> -	return true;
> +	return generic_setup_basedir(progname, parentdir, nsm_base_dirname);
>  }
>  
>  /**
> diff --git a/utils/statd/Makefile.am b/utils/statd/Makefile.am
> index 152b680..ea32075 100644
> --- a/utils/statd/Makefile.am
> +++ b/utils/statd/Makefile.am
> @@ -18,6 +18,7 @@ statd_LDADD = ../../support/nsm/libnsm.a \
>  	      $(LIBWRAP) $(LIBNSL) $(LIBCAP) $(LIBTIRPC)
>  sm_notify_LDADD = ../../support/nsm/libnsm.a \
>  		  ../../support/nfs/libnfs.a \
> +	          ../../support/misc/libmisc.a \
>  		  $(LIBNSL) $(LIBCAP) $(LIBTIRPC)
>  
>  EXTRA_DIST = sim_sm_inter.x $(man8_MANS) simulate.c
> -- 
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux