Here is a patch for knfsd-981022. It fixes some bugs:
1. Fix buffer overruns from Peter Benie <pjb1008@cus.cam.ac.uk>.
2. Fix hostname matching.
3. Correctly handle dupilcations in /etc/exports.
4. Add -F flag to statd.
I will make a full release when the kernel is stable again.
-- H.J. Lu (hjl@gnu.org)--- Index: support/export/export.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/support/export/export.c,v retrieving revision 1.9 diff -u -p -r1.9 export.c --- support/export/export.c 1998/10/01 00:31:35 1.9 +++ support/export/export.c 1998/10/28 16:36:02 @@ -27,11 +27,28 @@ int export_read(char *fname) { struct exportent *eep; + nfs_export *exp; setexportent(fname, "r"); while ((eep = getexportent()) != NULL) { - if (!export_lookup(eep->e_hostname, eep->e_path)) - export_create(eep); + exp = export_lookup(eep->e_hostname, eep->e_path); + if (!exp) + export_create(eep); + else { + if (exp->m_export.e_flags != eep->e_flags) { + xlog(L_ERROR, "incompatible dupilcated export entries:"); + xlog(L_ERROR, "\t%s:%s (0x%x) [IGNORED]", eep->e_hostname, + eep->e_path, eep->e_flags); + xlog(L_ERROR, "\t%s:%s (0x%x)", exp->m_export.e_hostname, + exp->m_export.e_path, exp->m_export.e_flags); + } + else { + xlog(L_ERROR, "dupilcated export entries:"); + xlog(L_ERROR, "\t%s:%s", eep->e_hostname, eep->e_path); + xlog(L_ERROR, "\t%s:%s", exp->m_export.e_hostname, + exp->m_export.e_path); + } + } } endexportent(); Index: support/export/hostname.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/support/export/hostname.c,v retrieving revision 1.2 diff -u -p -r1.2 hostname.c --- support/export/hostname.c 1998/09/23 01:45:58 1.2 +++ support/export/hostname.c 1998/10/28 05:35:55 @@ -99,21 +99,42 @@ hostent_dup (struct hostent *hp) int matchhostname (const char *h1, const char *h2) { - struct hostent *hp; - char *name; + struct hostent *hp1, *hp2; + int status; if (strcasecmp (h1, h2) == 0) return 1; - hp = gethostbyname (h1); - if (hp == NULL) + hp1 = gethostbyname (h1); + if (hp1 == NULL) return 0; - name = alloca (strlen (hp->h_name) + 1); - strcpy (name, hp->h_name); + hp1 = hostent_dup (hp1); - hp = gethostbyname (h2); - return hp && strcasecmp (name, hp->h_name) == 0; + hp2 = gethostbyname (h2); + if (hp2) + { + if (strcasecmp (hp1->h_name, hp2->h_name) == 0) + status = 1; + else + { + char **ap1, **ap2; + + status = 0; + for (ap1 = hp1->h_addr_list; *ap1 && status == 0; *ap1++) + for (ap2 = hp2->h_addr_list; *ap2; *ap2++) + if (memcmp (*ap1, *ap2, sizeof (struct in_addr)) == 0) + { + status = 1; + break; + } + } + } + else + status = 0; + + free (hp1); + return status; } #ifdef TEST @@ -150,6 +171,8 @@ main (int argc, char **argv) print_host (cp); free (cp); } + printf ("127.0.0.1 == %s: %d\n", argv [1], + matchhostname ("127.0.0.1", argv [1])); return 0; } #endif Index: support/nfs/rpcmisc.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/support/nfs/rpcmisc.c,v retrieving revision 1.2 diff -u -p -r1.2 rpcmisc.c --- support/nfs/rpcmisc.c 1998/09/09 15:27:55 1.2 +++ support/nfs/rpcmisc.c 1998/10/23 17:06:10 @@ -175,6 +175,8 @@ void rpc_logcall(struct svc_req *rqstp, char *xname, char *arg) { char buff[1024]; + int buflen=sizeof(buff); + int len; char *sp; int i; @@ -192,19 +194,29 @@ rpc_logcall(struct svc_req *rqstp, char unix_cred = (struct authunix_parms *) rqstp->rq_clntcred; tm = localtime(&unix_cred->aup_time); - sprintf(sp, "UNIX %d/%d/%d %02d:%02d:%02d %s %d.%d", + snprintf(sp, buflen, "UNIX %d/%d/%d %02d:%02d:%02d %s %d.%d", tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, unix_cred->aup_machname, unix_cred->aup_uid, unix_cred->aup_gid); - sp += strlen(sp); + sp[buflen-1] = 0; + len = strlen(sp); + sp += buflen; + buflen -= len; if ((int) unix_cred->aup_len > 0) { - sprintf(sp, "+%d", unix_cred->aup_gids[0]); - sp += strlen(sp); + snprintf(sp, buflen, "+%d", unix_cred->aup_gids[0]); + sp[buflen-1] = 0; + len = strlen(sp); + sp += buflen; + buflen -= len; for (i = 1; i < unix_cred->aup_len; i++) { - sprintf(sp, ",%d", unix_cred->aup_gids[i]); - sp += strlen(sp); + snprintf(sp, buflen, ",%d", + unix_cred->aup_gids[i]); + sp[buflen-1] = 0; + len = strlen(sp); + sp += buflen; + buflen -= len; } } } Index: support/nfs/xlog.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/support/nfs/xlog.c,v retrieving revision 1.2 diff -u -p -r1.2 xlog.c --- support/nfs/xlog.c 1998/10/01 00:31:36 1.2 +++ support/nfs/xlog.c 1998/10/31 19:24:29 @@ -140,8 +140,9 @@ xlog(int kind, const char *fmt, ...) return; va_start(args, fmt); - vsprintf(buff, fmt, args); + vsnprintf(buff, sizeof (buff), fmt, args); va_end(args); + buff[sizeof (buff) - 1] = 0; if ((n = strlen(buff)) > 0 && buff[n-1] != '\n') { buff[n++] = '\n'; buff[n++] = '\0'; Index: utils/rquotad/hasquota.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/rquotad/hasquota.c,v retrieving revision 1.4 diff -u -p -r1.4 hasquota.c --- utils/rquotad/hasquota.c 1998/10/01 00:31:36 1.4 +++ utils/rquotad/hasquota.c 1998/10/31 19:14:16 @@ -24,6 +24,7 @@ #include <limits.h> #include <string.h> #include "mntent.h" +#include "xmalloc.h" #undef min #define min(x,y) ((x) < (y)) ? (x) : (y) @@ -32,8 +33,6 @@ (!strcmp(type,MNTTYPE_EXT2)) char *qfextension[] = INITQFNAMES; -static char *qfname = QUOTAFILENAME; -static char qfullname[PATH_MAX]; /* * Check to see if a particular quota is to be enabled. @@ -41,6 +40,7 @@ static char qfullname[PATH_MAX]; int hasquota(struct mntent *mnt, int type, char **qfnamep) { + char *qfname = QUOTAFILENAME; char *buf, *option, *pathname; if (!CORRECT_FSTYPE(mnt->mnt_type)) @@ -49,21 +49,21 @@ hasquota(struct mntent *mnt, int type, c if (((type == USRQUOTA) && (option = hasmntopt(mnt, MNTOPT_USRQUOTA)) != (char *)0) || ((type == GRPQUOTA) && (option = hasmntopt(mnt, MNTOPT_GRPQUOTA)) != (char *)0)) { if ((pathname = strchr(option, '=')) == (char *)0) { - (void) sprintf(qfullname, "%s%s%s.%s", mnt->mnt_dir, - (mnt->mnt_dir[strlen(mnt->mnt_dir) - 1] == '/') ? "" : "/", - qfname, qfextension[type]); + *qfnamep=xmalloc(strlen(mnt->mnt_dir)+strlen(qfname)+strlen(qfextension[type])+2); + (void) sprintf(*qfnamep, "%s%s%s.%s", mnt->mnt_dir, + (mnt->mnt_dir[strlen(mnt->mnt_dir) - 1] == '/') ? "" : "/", + qfname, qfextension[type]); } else { if ((option = strchr(++pathname, ',')) != (char *)NULL) { - strncpy(qfullname, pathname, - min((option - pathname), sizeof(qfullname)) - 1); - qfullname [min((option - pathname), sizeof(qfullname)) - 1] = '\0'; + int len=option-pathname; + *qfnamep=xmalloc(len); + memcpy(*qfnamep, pathname, len-1); + (*qfnamep) [len-1] = '\0'; } else { - strncpy(qfullname, pathname, sizeof(qfullname) - 1); - qfullname [sizeof(qfullname) - 1] = '\0'; + *qfnamep=xstrdup(pathname); } } - *qfnamep = strdup(qfullname); return (1); } else return (0); Index: utils/rquotad/rquota_server.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/rquotad/rquota_server.c,v retrieving revision 1.4 diff -u -p -r1.4 rquota_server.c --- utils/rquotad/rquota_server.c 1998/10/01 00:31:36 1.4 +++ utils/rquotad/rquota_server.c 1998/10/23 17:06:10 @@ -176,7 +176,11 @@ getquota_rslt *getquotainfo(int flags, c if ((err = quotactl(QCMD(Q_GETQUOTA, type), devicename, id, (caddr_t)&dq_dqb)) == -1 && !(flags & ACTIVE)) { if ((fd = open(qfpathname, O_RDONLY)) < 0) + { + free(qfpathname); continue; + } + free(qfpathname); lseek(fd, (long) dqoff(id), L_SET); switch (read(fd, &dq_dqb, sizeof(struct dqblk))) { case 0:/* EOF */ Index: utils/showmount/showmount.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/showmount/showmount.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 showmount.c --- utils/showmount/showmount.c 1998/08/19 02:37:45 1.1.1.1 +++ utils/showmount/showmount.c 1998/10/23 17:06:10 @@ -263,18 +263,15 @@ char **argv; if (headers) printf("All mount points on %s:\n", hostname); while (dumplist) { - char s[1024]; char *t; - sprintf(s, "%s:%s", dumplist->ml_hostname, - dumplist->ml_directory); - t = malloc(strlen(s) + 1); - if (t) - strcpy(t, s); - else { - printf("%s: out of memory\n", program_name); + t=malloc(strlen(dumplist->ml_hostname)+strlen(dumplist->ml_directory)+2); + if (!t) + { + fprintf(stderr, "%s: out of memory\n", program_name); exit(1); } + sprintf(t, "%s:%s", dumplist->ml_hostname, dumplist->ml_directory); dumpv[i++] = t; dumplist = dumplist->ml_next; } Index: utils/statd/log.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/statd/log.c,v retrieving revision 1.2 diff -u -p -r1.2 log.c --- utils/statd/log.c 1998/10/01 00:31:36 1.2 +++ utils/statd/log.c 1998/10/23 17:06:10 @@ -60,8 +60,9 @@ die(char *fmt, ...) va_list ap; va_start(ap, fmt); - vsprintf (buffer, fmt, ap); + vsnprintf (buffer, 1024, fmt, ap); va_end(ap); + buffer[1023]=0; log(L_FATAL, "%s", buffer); @@ -79,8 +80,9 @@ log(int level, char *fmt, ...) va_list ap; va_start(ap, fmt); - vsprintf (buffer, fmt, ap); + vsnprintf (buffer, 1024, fmt, ap); va_end(ap); + buffer[1023]=0; if (level < L_DEBUG) { syslog(level, buffer); Index: utils/statd/misc.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/statd/misc.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 misc.c --- utils/statd/misc.c 1998/08/19 02:37:45 1.1.1.1 +++ utils/statd/misc.c 1998/10/31 19:19:46 @@ -28,7 +28,7 @@ xmalloc (size_t size) if (!(ptr = malloc (size))) /* SHIT! SHIT! SHIT! */ - die ("malloc: %s", strerror (errno)); + die ("malloc failed"); return (ptr); } @@ -44,7 +44,7 @@ xstrdup (const char *string) /* Will only fail if underlying malloc() fails (ENOMEM). */ if (!(result = strdup (string))) - die ("strdup: %s", strerror (errno)); + die ("strdup failed"); return (result); } @@ -57,9 +57,10 @@ xstrdup (const char *string) void xunlink (char *path, char *host, short int check) { - char tozap[PATH_MAX]; + char *tozap; - snprintf (tozap, PATH_MAX, "%s/%s", path, host); + tozap=alloca (strlen(path)+strlen(host)+2); + sprintf (tozap, "%s/%s", path, host); if (!check || !nlist_gethost(rtnl, host, 0)) if (unlink (tozap) == -1) Index: utils/statd/monitor.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/statd/monitor.c,v retrieving revision 1.4 diff -u -p -r1.4 monitor.c --- utils/statd/monitor.c 1998/10/10 23:57:28 1.4 +++ utils/statd/monitor.c 1998/10/23 17:06:10 @@ -33,7 +33,7 @@ sm_mon_1_svc(struct mon *argp, struct sv char *mon_name = argp->mon_id.mon_name, *my_name = argp->mon_id.my_id.my_name; struct my_id *id = &argp->mon_id.my_id; - char path[PATH_MAX]; + char *path; int fd; notify_list *clnt; @@ -114,14 +114,17 @@ sm_mon_1_svc(struct mon *argp, struct sv /* * Now, Create file on stable storage for host. */ - snprintf(path, PATH_MAX, SM_DIR "/%s", mon_name); + + path=xmalloc(strlen(SM_DIR)+strlen(mon_name)+2); + sprintf(path, SM_DIR "/%s", mon_name); if ((fd = open(path, O_WRONLY|O_SYNC|O_CREAT, S_IRUSR|S_IWUSR)) < 0) { /* Didn't fly. We won't monitor. */ log(L_ERROR, "creat(%s) failed: %m", path); nlist_free(NULL, clnt); + free(path); goto failure; } - + free(path); nlist_insert(&rtnl, clnt); close(fd); Index: utils/statd/notify.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/statd/notify.c,v retrieving revision 1.2 diff -u -p -r1.2 notify.c --- utils/statd/notify.c 1998/09/20 23:43:14 1.2 +++ utils/statd/notify.c 1998/10/23 17:06:10 @@ -54,11 +54,14 @@ notify_hosts(void) * (e.g. with cfsd) */ if (matchhostname(de->d_name, MY_NAME) || matchhostname(de->d_name, "localhost")) { - char fname[PATH_MAX]; - + char *fname; + fname=xmalloc(strlen(SM_BAK_DIR)+sizeof(de->d_name)+2); dprintf(L_DEBUG, "We're on our own notify list?!?"); sprintf(fname, SM_BAK_DIR "/%s", de->d_name); - unlink(fname); + if (unlink(fname)) + log(L_ERROR, "unlink(%s): %s", + fname, strerror(errno)); + free(fname); continue; } Index: utils/statd/statd.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/statd/statd.c,v retrieving revision 1.2 diff -u -p -r1.2 statd.c --- utils/statd/statd.c 1998/08/31 18:51:53 1.2 +++ utils/statd/statd.c 1998/10/31 17:55:07 @@ -7,6 +7,7 @@ #include <signal.h> #include <unistd.h> +#include <string.h> #include <rpc/rpc.h> #include <rpc/pmap_clnt.h> #include "statd.h" @@ -47,21 +48,31 @@ int main (int argc, char **argv) { int pid; + int foreground = 0; log_init (argv[0]); + if (argc == 2 && strcmp (argv [1], "-F") == 0) { + foreground = 1; + argc--; + argv++; + } + #ifdef SIMULATIONS if (argc > 1) simulator (--argc, ++argv); /* simulator() does exit() */ #endif - if ((pid = fork ()) < 0) { - perror ("Could not fork"); - exit (1); - } else if (pid != 0) { - /* Parent. */ - exit (0); + if (!foreground) { + if ((pid = fork ()) < 0) { + perror ("Could not fork"); + exit (1); + } else if (pid != 0) { + /* Parent. */ + exit (0); + } } + /* Child. */ signal (SIGHUP, killer); signal (SIGINT, killer); Index: utils/statd/state.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/statd/state.c,v retrieving revision 1.2 diff -u -p -r1.2 state.c --- utils/statd/state.c 1998/10/01 00:31:36 1.2 +++ utils/statd/state.c 1998/10/23 17:06:10 @@ -85,7 +85,8 @@ shuffle_dirs (void) DIR *nld; struct dirent *de; struct stat st; - char src[PATH_MAX], dst[PATH_MAX]; + char *src, *dst; + int len1, len2, len; if (stat (SM_DIR, &st) == -1 && errno != ENOENT) die ("stat (%s): %s", SM_DIR, strerror (errno)); @@ -106,13 +107,20 @@ shuffle_dirs (void) if (!(nld = opendir (SM_DIR))) die ("opendir (%s): %s", SM_DIR, strerror (errno)); + len1=strlen(SM_DIR); + len2=strlen(SM_BAK_DIR); while ((de = readdir (nld))) { if (de->d_name[0] == '.') continue; - snprintf (src, PATH_MAX, "%s/%s", SM_DIR, de->d_name); - snprintf (dst, PATH_MAX, "%s/%s", SM_BAK_DIR, de->d_name); + len=strlen(de->d_name); + src=xmalloc(len1+len+2); + dst=xmalloc(len2+len+2); + sprintf (src, "%s/%s", SM_DIR, de->d_name); + sprintf (dst, "%s/%s", SM_BAK_DIR, de->d_name); if (rename (src, dst) == -1) die ("rename (%s to %s): %s", SM_DIR, SM_BAK_DIR, strerror (errno)); + free(src); + free(dst); } if (closedir (nld) == -1) log (L_ERROR, "closedir (%s): %s", SM_DIR, strerror (errno));- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/