diff options
author | nalin <nalin> | 2005-03-18 01:24:22 +0000 |
---|---|---|
committer | nalin <nalin> | 2005-03-18 01:24:22 +0000 |
commit | 9a658a3de95278c308f188ed214e6fe07f66e211 (patch) | |
tree | aea308ec3f5bb7bc0d01b0e8bfaa948365d68016 | |
parent | b72c7888aec26a0b812aed9798cc6c323c588ab4 (diff) | |
download | nss_directories-9a658a3de95278c308f188ed214e6fe07f66e211.tar.gz nss_directories-9a658a3de95278c308f188ed214e6fe07f66e211.tar.xz nss_directories-9a658a3de95278c308f188ed214e6fe07f66e211.zip |
- fix a referring-to-freed-memory bug
- 0.6
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Makefile.am | 12 | ||||
-rw-r--r-- | configure.ac | 58 | ||||
-rw-r--r-- | nss_directories.spec | 18 | ||||
-rw-r--r-- | src/Makefile.am | 11 | ||||
-rw-r--r-- | src/files-parse.c | 5 | ||||
-rw-r--r-- | src/generic.c | 44 | ||||
-rw-r--r-- | src/test.c | 46 |
8 files changed, 115 insertions, 83 deletions
@@ -1,3 +1,7 @@ +2005-03-17 nalin +* src/generic.c: don't leak memory if realloc() fails. +* src/generic.c: don't refer to freed memory in getXXent_r. + 2003-11-04 nalin * src/generic.c: clear pointers when we free them so that apps which call our end.... functions again don't cause us to double-free diff --git a/Makefile.am b/Makefile.am index 5360c29..10deee3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,6 @@ DISTCHECK_CONFIGURE_FLAGS = --with-moduledir=$$dc_install_base/modules NAME = nss_directories VERSION=@VERSION@ -RELEASE=@RELEASE@ CVSTAG = $(shell echo $(NAME)-$(VERSION) | sed -e s,\\.,_,g -e s,-,_,g) tag: @@ -13,13 +12,12 @@ tag: force-tag: cvs tag -cF $(CVSTAG) -distdir = $(NAME)-$(VERSION)-$(RELEASE) archive: $(RM) -fr /tmp/$(NAME)-$(VERSION) - cd /tmp ; cvs -d $(shell cat $(top_srcdir)/CVS/Root) export -r $(CVSTAG) -d $(NAME)-$(VERSION)-$(RELEASE) $(NAME) - cd /tmp/$(NAME)-$(VERSION)-$(RELEASE) ; ./autogen.sh ; make distcheck - mv -v /tmp/$(NAME)-$(VERSION)-$(RELEASE)/$(NAME)-*.*.tar.* $(top_srcdir)/ - $(RM) -fr /tmp/$(NAME)-$(VERSION)-$(RELEASE) + cd /tmp ; cvs -d $(shell cat $(top_srcdir)/CVS/Root) export -r $(CVSTAG) -d $(NAME)-$(VERSION) $(NAME) + cd /tmp/$(NAME)-$(VERSION) ; ./autogen.sh ; make distcheck + mv -v /tmp/$(NAME)-$(VERSION)/$(NAME)-*.*.tar.* $(top_srcdir)/ + $(RM) -fr /tmp/$(NAME)-$(VERSION) srpm: archive - rpmbuild -ts $(NAME)-$(VERSION)-$(RELEASE).tar.gz + rpmbuild -ts $(NAME)-$(VERSION).tar.gz diff --git a/configure.ac b/configure.ac index 0ccbe60..a00ef0a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,52 +1,14 @@ -AC_INIT(README) -VERSION=`awk '/^Version:/ {print $NF}' ${srcdir}/nss_directories.spec` -RELEASE=`awk '/^Release:/ {print $NF}' ${srcdir}/nss_directories.spec` -AM_INIT_AUTOMAKE(nss_directories, $VERSION) +AC_INIT(nss_directories,0.6) +AC_CONFIG_SRCDIR([README]) +AM_INIT_AUTOMAKE(foreign) AM_PROG_LIBTOOL - AC_SYS_LARGEFILE - -MYPREFIX=`eval echo $prefix` -if test "$MYPREFIX" = NONE ; then - MYPREFIX="$ac_default_prefix" - MYSYSCONFDIR=`eval echo $sysconfdir | sed "s|NONE|$MYPREFIX|g"` -else - MYSYSCONFDIR=`eval echo $sysconfdir` -fi - -AC_DEFINE_UNQUOTED(SYSCONFDIR,"$MYSYSCONFDIR",[Define to the top-level data directory.]) - -AC_ARG_WITH(moduledir,[ --with-moduledir=DIR directory to install modules in (default /lib)],[moduledir="$withval"]) -if ! test -n "$moduledir" -then - moduledir=/lib -fi -AC_SUBST(moduledir) - -nss_files=`ls -1 "$moduledir"/libnss_files-*.so | head -1` -GLIBC_VERSION=`basename "$nss_files" .so | cut -f2 -d-` -if test -z "$GLIBC_VERSION" -then - GLIBC_VERSION=$PACKAGE_VERSION -fi -AC_SUBST(GLIBC_VERSION) - -if test x$GCC = xyes ; then - CFLAGS="${CFLAGS} -std=c99" - CFLAGS="${CFLAGS} -D_GNU_SOURCE" - CFLAGS="${CFLAGS} -Wall" - CFLAGS="${CFLAGS} -Waggregate-return" - CFLAGS="${CFLAGS} -Wcast-align" - CFLAGS="${CFLAGS} -Wimplicit" - CFLAGS="${CFLAGS} -Wpointer-arith" - CFLAGS="${CFLAGS} -Wstrict-prototypes" - CFLAGS="${CFLAGS} -Wuninitialized" -fi - +AM_MAINTAINER_MODE AC_SUBST(VERSION) AC_SUBST(RELEASE) -AM_CONFIG_HEADER(config.h) -AC_OUTPUT(Makefile src/Makefile) - -AC_MSG_RESULT([Reading data from sysconfdir = "$MYSYSCONFDIR".]) -AC_MSG_RESULT([Installing modules to "$moduledir".]) +AH_BOTTOM([ +#define SYSTEM_DATABASE_DIR "/etc" +]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT diff --git a/nss_directories.spec b/nss_directories.spec index 8bfe3aa..3d8fe38 100644 --- a/nss_directories.spec +++ b/nss_directories.spec @@ -1,7 +1,7 @@ Name: nss_directories -Version: 0.5 +Version: 0.6 Release: 1 -Source: %{name}-%{version}-%{release}.tar.gz +Source: %{name}-%{version}.tar.gz License: LGPL Group: System Environment/Libraries Summary: An NSS library which searches directories. @@ -14,8 +14,8 @@ services, and shadow passwords (instead of or in addition to using flat files or NIS). %prep -%setup -q -n %{name}-%{version}-%{release} -%configure --with-moduledir=/%{_lib} +%setup -q +%configure --libdir=/%{_lib} %build make @@ -28,6 +28,10 @@ install -d -m755 $RPM_BUILD_ROOT/%{_sysconfdir}/shadow.d install -d -m755 $RPM_BUILD_ROOT/%{_sysconfdir}/group.d install -d -m755 $RPM_BUILD_ROOT/%{_sysconfdir}/protocols.d install -d -m755 $RPM_BUILD_ROOT/%{_sysconfdir}/services.d +rm $RPM_BUILD_ROOT/%{_lib}/*.a +rm $RPM_BUILD_ROOT/%{_lib}/*.la +rm $RPM_BUILD_ROOT/%{_lib}/*.so +rm $RPM_BUILD_ROOT/%{_lib}/*.so.? %clean rm -fr $RPM_BUILD_ROOT @@ -35,7 +39,7 @@ rm -fr $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc README ChangeLog COPYING -/%{_lib}/libnss_directories-*.so +/%{_lib}/libnss_directories* %dir %{_sysconfdir}/passwd.d %dir %{_sysconfdir}/shadow.d %dir %{_sysconfdir}/group.d @@ -47,6 +51,10 @@ rm -fr $RPM_BUILD_ROOT %postun -p /sbin/ldconfig %changelog +* Thu Mar 17 2005 Nalin Dahyabhai <nalin@redhat.com> 0.6-1 +- fix a referring-to-freed-memory bug +- update autotools machinery + * Thu Oct 30 2003 Nalin Dahyabhai <nalin@redhat.com> 0.5-1 - include directories in the package - be more careful to stop double-frees from overzealous applications diff --git a/src/Makefile.am b/src/Makefile.am index e549142..234ebc6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,11 +1,16 @@ -moduleexecdir = @moduledir@ -moduleexec_LTLIBRARIES = libnss_directories.la +lib_LTLIBRARIES = libnss_directories.la + +if MAINTAINER_MODE +AM_CFLAGS = -Wall -Wextra +endif EXTRA_libnss_directories_la_SOURCES = \ files-parse.c \ generic.c \ parsers.h +EXTRA_programs = test + libnss_directories_la_SOURCES = \ glibc-parse.c \ group.c \ @@ -19,8 +24,6 @@ libnss_directories_la_LDFLAGS = \ -export-symbols-regex "_nss_directories_[sge].*" install-exec-hook: - mv $(DESTDIR)/$(moduleexecdir)/libnss_directories.so.2.0.0 \ - $(DESTDIR)/$(moduleexecdir)/libnss_directories-@GLIBC_VERSION@.so $(RM) -f $(DESTDIR)/$(moduleexecdir)/libnss_directories.so* $(RM) -f $(DESTDIR)/$(moduleexecdir)/libnss_directories.a $(RM) -f $(DESTDIR)/$(moduleexecdir)/libnss_directories.la diff --git a/src/files-parse.c b/src/files-parse.c index 739ee54..7d1e232 100644 --- a/src/files-parse.c +++ b/src/files-parse.c @@ -1,5 +1,5 @@ /* Common code for file-based database parsers in nss_files module. - Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1996-2000, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -67,7 +67,7 @@ struct parser_data #ifdef ENTDATA /* The function can't be exported, because the entdata structure is defined only in files-foo.c. */ -# define parser_stclass static inline +# define parser_stclass static # define nss_files_parse_hidden_def(name) #else /* Export the line parser function so it can be used in nss_db. */ @@ -171,6 +171,7 @@ nss_files_parse_hidden_def (parse_line) } static inline char ** +__attribute ((always_inline)) parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop) { char *eol, **list, **p; diff --git a/src/generic.c b/src/generic.c index 7266402..bd7f429 100644 --- a/src/generic.c +++ b/src/generic.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2002,2005 Red Hat, Inc. * * This is free software; you can redistribute it and/or modify it under * the terms of the GNU Library General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ident "$Id: generic.c,v 1.6 2003/11/04 19:34:52 nalin Exp $" +#ident "$Id: generic.c,v 1.7 2005/03/18 01:24:22 nalin Exp $" #include "../config.h" @@ -51,7 +51,7 @@ static const char *skip_names[] = { static int skip_file_by_name(const char *filename) { - int i; + unsigned int i; for (i = 0; i < sizeof(skip_names) / sizeof(skip_names[0]); i++) { if (fnmatch(skip_names[i], filename, 0) == 0) { return TRUE; @@ -64,7 +64,7 @@ skip_file_by_name(const char *filename) static char * read_line(FILE *fp) { - char *buffer; + char *buffer, *t; size_t buflen, length; buflen = CHUNK_SIZE; @@ -73,7 +73,7 @@ read_line(FILE *fp) if (buffer == NULL) { return NULL; } - memset(buffer, 0, buflen); + memset(buffer, '\0', buflen); while (fgets(buffer + length, buflen - length, fp) != NULL) { length = strlen(buffer); @@ -82,11 +82,13 @@ read_line(FILE *fp) break; } else { buflen += CHUNK_SIZE; - buffer = realloc(buffer, buflen); - if (buffer == NULL) { + t = realloc(buffer, buflen); + if (t == NULL) { + free(buffer); return NULL; } - memset(buffer + length, 0, buflen - length); + buffer = t; + memset(buffer + length, '\0', buflen - length); } } } @@ -119,10 +121,9 @@ getgen(struct STRUCTURE *result, struct dirent *ent = NULL; struct stat st; char path[PATH_MAX], *line; - long offset; /* Start reading the directory. */ - dir = opendir(SYSCONFDIR "/" DATABASE ".d"); + dir = opendir(SYSTEM_DATABASE_DIR "/" DATABASE ".d"); if (dir == NULL) { *errnop = errno; return NSS_STATUS_NOTFOUND; @@ -136,7 +137,8 @@ getgen(struct STRUCTURE *result, } /* Figure out the full name of the file. */ - snprintf(path, sizeof(path), SYSCONFDIR "/" DATABASE ".d/%s", + snprintf(path, sizeof(path), + SYSTEM_DATABASE_DIR "/" DATABASE ".d/%s", ent->d_name); /* If we can't open it, skip it. */ @@ -155,12 +157,11 @@ getgen(struct STRUCTURE *result, } /* Read the next line. */ - offset = ftell(fp); while ((line = read_line(fp)) != NULL) { /* Check that we have room to save this. */ if (strlen(line) >= buflen) { - fseek(fp, offset, SEEK_SET); free(line); + line = NULL; fclose(fp); fp = NULL; closedir(dir); @@ -176,6 +177,7 @@ getgen(struct STRUCTURE *result, errnop)) { case 0: free(line); + line = NULL; continue; break; case -1: @@ -199,6 +201,7 @@ getgen(struct STRUCTURE *result, TRUE) { *result = structure; free(line); + line = NULL; fclose(fp); fp = NULL; closedir(dir); @@ -208,7 +211,7 @@ getgen(struct STRUCTURE *result, /* Free this line. */ free(line); - offset = ftell(fp); + line = NULL; } /* Close this file. */ @@ -306,7 +309,7 @@ setent(int stayopen) /* Close and reopen the directory. */ endent(); LOCK(); - dir = opendir(SYSCONFDIR "/" DATABASE ".d"); + dir = opendir(SYSTEM_DATABASE_DIR "/" DATABASE ".d"); UNLOCK(); return (dir == NULL) ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; } @@ -358,7 +361,8 @@ getent(struct STRUCTURE *result, char *buffer, size_t buflen, int *errnop) /* Formulate the full path name and try to * open it. */ snprintf(path, sizeof(path), - SYSCONFDIR "/" DATABASE ".d/%s", + SYSTEM_DATABASE_DIR "/" + DATABASE ".d/%s", ent->d_name); fp = fopen(path, "r"); @@ -409,20 +413,25 @@ getent(struct STRUCTURE *result, char *buffer, size_t buflen, int *errnop) } /* Try to parse the line. */ - switch (parse_line(line, &structure, + strcpy(buffer, line); + switch (parse_line(buffer, &structure, (void *)buffer, buflen, errnop)) { case -1: + /* out of space */ free(line); fseek(fp, offset, SEEK_SET); errno = ERANGE; return NSS_STATUS_TRYAGAIN; break; case 0: + /* parse error (invalid format) */ free(line); + line = NULL; continue; break; case 1: + /* success */ free(line); *result = structure; UNLOCK(); @@ -434,6 +443,7 @@ getent(struct STRUCTURE *result, char *buffer, size_t buflen, int *errnop) /* Try the next entry. */ free(line); + line = NULL; } while (1); /* We never really get here, but oh well. */ diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..092d7f3 --- /dev/null +++ b/src/test.c @@ -0,0 +1,46 @@ +#include <sys/types.h> +#include <errno.h> +#include <nss.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int +main(int argc, char **argv) +{ + char *buf; + size_t size = 2; + int result; + struct passwd passwd, *pwd = NULL; + + __nss_configure_lookup ("passwd", "directories"); + + buf = malloc(size); + setpwent(); + do { + pwd = NULL; + result = getpwent_r(&passwd, buf, size, &pwd); + printf("%d: ", result); + switch (result) { + case 0: + printf("%s\n", pwd->pw_name); + break; + case ERANGE: + printf("%d is not enough, error = %s\n", size, + strerror(errno)); + size++; + free(buf); + buf = malloc(size); + result = 0; + break; + default: + printf("failed (%s)\n", strerror(result)); + _exit(1); + break; + } + } while (result == 0); + endpwent(); + return 0; +} |