From owner-freebsd-audit Sun Feb 24 10:38:59 2002 Delivered-To: freebsd-audit@freebsd.org Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by hub.freebsd.org (Postfix) with SMTP id C885137B400 for ; Sun, 24 Feb 2002 10:38:43 -0800 (PST) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 24 Feb 2002 18:38:42 +0000 (GMT) To: freebsd-audit@freebsd.org Subject: cleanup of last(1) Date: Sun, 24 Feb 2002 18:38:42 +0000 From: Ian Dowse Message-ID: <200202241838.aa93591@salmon.maths.tcd.ie> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG The code in last(1) has suffered a bit from having features added without reorganisation to avoid deep nesting and code duplication. The patch below attempts to clean it up by splitting out bits of the huge wtmp() function. I have tested that it produces the same output as the original code for a few wtmp files. This should make it much neater to add a "-y" option as proposed by PR bin/12982. Any comments? (BTW, the final chunk fixes a brace misplacement in the current source although the diff makes it look like a typo). Ian Index: last.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.bin/last/last.c,v retrieving revision 1.22 diff -u -r1.22 last.c --- last.c 19 Jan 2002 23:20:00 -0000 1.22 +++ last.c 24 Feb 2002 17:55:19 -0000 @@ -84,6 +84,7 @@ LIST_ENTRY(ttytab) list; }; +static const char *crmsg; /* cause of last reboot */ static long currentout, /* current logout value */ maxrec; /* records to display */ static const char *file = _PATH_WTMP; /* wtmp file */ @@ -97,8 +98,10 @@ void addarg __P((int, char *)); time_t dateconv __P((char *)); +void doentry __P((struct utmp *)); void hostconv __P((char *)); void onintr __P((int)); +void printentry __P((struct utmp *, struct ttytab *)); char *ttyconv __P((char *)); int want __P((struct utmp *)); void usage __P((void)); @@ -193,15 +196,11 @@ wtmp() { struct utmp *bp; /* current structure */ - struct ttytab *tt, *ttx; /* ttylist entry */ struct stat stb; /* stat of file for size */ long bl; - time_t delta; /* time difference */ int bytes, wfd; - const char *crmsg; char ct[80]; struct tm *tm; - int snapfound = 0; /* found snapshot entry? */ time_t t; LIST_INIT(&ttylist); @@ -219,152 +218,8 @@ if (lseek(wfd, (off_t)(bl * sizeof(buf)), L_SET) == -1 || (bytes = read(wfd, buf, sizeof(buf))) == -1) err(1, "%s", file); - for (bp = &buf[bytes / sizeof(buf[0]) - 1]; bp >= buf; --bp) { - /* - * if the terminal line is '~', the machine stopped. - * see utmp(5) for more info. - */ - if (bp->ut_line[0] == '~' && !bp->ut_line[1]) { - /* everybody just logged out */ - for (tt = LIST_FIRST(&ttylist); tt;) { - LIST_REMOVE(tt, list); - ttx = tt; - tt = LIST_NEXT(tt, list); - free(ttx); - } - currentout = -bp->ut_time; - crmsg = strncmp(bp->ut_name, "shutdown", - UT_NAMESIZE) ? "crash" : "shutdown"; - /* - * if we're in snapshot mode, we want to - * exit if this shutdown/reboot appears - * while we we are tracking the active - * range - */ - if (snaptime && snapfound) - return; - /* - * don't print shutdown/reboot entries - * unless flagged for - */ - if (!snaptime && want(bp)) { - t = _int_to_time(bp->ut_time); - tm = localtime(&t); - (void) strftime(ct, sizeof(ct), - d_first ? "%a %e %b %R" : - "%a %b %e %R", - tm); - printf("%-*.*s %-*.*s %-*.*s %s\n", - UT_NAMESIZE, UT_NAMESIZE, - bp->ut_name, UT_LINESIZE, - UT_LINESIZE, bp->ut_line, - UT_HOSTSIZE, UT_HOSTSIZE, - bp->ut_host, ct); - if (maxrec != -1 && !--maxrec) - return; - } - continue; - } - /* - * if the line is '{' or '|', date got set; see - * utmp(5) for more info. - */ - if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|') - && !bp->ut_line[1]) { - if (want(bp) && !snaptime) { - t = _int_to_time(bp->ut_time); - tm = localtime(&t); - (void) strftime(ct, sizeof(ct), - d_first ? "%a %e %b %R" : - "%a %b %e %R", - tm); - printf("%-*.*s %-*.*s %-*.*s %s\n", - UT_NAMESIZE, UT_NAMESIZE, bp->ut_name, - UT_LINESIZE, UT_LINESIZE, bp->ut_line, - UT_HOSTSIZE, UT_HOSTSIZE, bp->ut_host, - ct); - if (maxrec && !--maxrec) - return; - } - continue; - } - /* find associated tty */ - LIST_FOREACH(tt, &ttylist, list) - if (!strncmp(tt->tty, bp->ut_line, UT_LINESIZE)) - break; - - if (tt == NULL) { - /* add new one */ - tt = malloc(sizeof(struct ttytab)); - if (tt == NULL) - err(1, "malloc failure"); - tt->logout = currentout; - strncpy(tt->tty, bp->ut_line, UT_LINESIZE); - LIST_INSERT_HEAD(&ttylist, tt, list); - } - - /* - * print record if not in snapshot mode and wanted - * or in snapshot mode and in snapshot range - */ - if (bp->ut_name[0] && (want(bp) || - (bp->ut_time < snaptime && - (tt->logout > snaptime || tt->logout < 1)))) { - snapfound = 1; - /* - * when uucp and ftp log in over a network, the entry in - * the utmp file is the name plus their process id. See - * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information. - */ - if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1)) - bp->ut_line[3] = '\0'; - else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1)) - bp->ut_line[4] = '\0'; - t = _int_to_time(bp->ut_time); - tm = localtime(&t); - (void) strftime(ct, sizeof(ct), - d_first ? "%a %e %b %R" : - "%a %b %e %R", - tm); - printf("%-*.*s %-*.*s %-*.*s %s ", - UT_NAMESIZE, UT_NAMESIZE, bp->ut_name, - UT_LINESIZE, UT_LINESIZE, bp->ut_line, - UT_HOSTSIZE, UT_HOSTSIZE, bp->ut_host, - ct); - if (!tt->logout) - puts(" still logged in"); - else { - if (tt->logout < 0) { - tt->logout = -tt->logout; - printf("- %s", crmsg); - } - else { - tm = localtime(&tt->logout); - (void) strftime(ct, sizeof(ct), "%R", tm); - printf("- %s", ct); - } - delta = tt->logout - bp->ut_time; - if ( sflag ) { - printf(" (%8ld)\n", - (long)delta); - } else { - tm = gmtime(&delta); - (void) strftime(ct, sizeof(ct), - width >= 8 ? "%T" : "%R", - tm); - if (delta < 86400) - printf(" (%s)\n", ct); - else - printf(" (%ld+%s)\n", - (long)delta / - 86400, ct); - } - } - if (maxrec != -1 && !--maxrec) - return; - } - tt->logout = bp->ut_time; - } + for (bp = &buf[bytes / sizeof(buf[0]) - 1]; bp >= buf; --bp) + doentry(bp); } t = _int_to_time(buf[0].ut_time); tm = localtime(&t); @@ -373,6 +228,153 @@ } /* + * doentry -- + * process a single wtmp entry + */ +void +doentry(bp) + struct utmp *bp; +{ + struct ttytab *tt, *ttx; /* ttylist entry */ + int snapfound = 0; /* found snapshot entry? */ + + /* + * if the terminal line is '~', the machine stopped. + * see utmp(5) for more info. + */ + if (bp->ut_line[0] == '~' && !bp->ut_line[1]) { + /* everybody just logged out */ + for (tt = LIST_FIRST(&ttylist); tt;) { + LIST_REMOVE(tt, list); + ttx = tt; + tt = LIST_NEXT(tt, list); + free(ttx); + } + currentout = -bp->ut_time; + crmsg = strncmp(bp->ut_name, "shutdown", UT_NAMESIZE) ? + "crash" : "shutdown"; + /* + * if we're in snapshot mode, we want to exit if this + * shutdown/reboot appears while we we are tracking the + * active range + */ + if (snaptime && snapfound) + exit(0); + /* + * don't print shutdown/reboot entries unless flagged for + */ + if (!snaptime && want(bp)) { + printentry(bp, NULL); + if (maxrec != -1 && !--maxrec) + exit(0); + } + return; + } + /* + * if the line is '{' or '|', date got set; see + * utmp(5) for more info. + */ + if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|') && + !bp->ut_line[1]) { + if (want(bp) && !snaptime) { + printentry(bp, NULL); + if (maxrec && !--maxrec) + exit(0); + } + return; + } + /* find associated tty */ + LIST_FOREACH(tt, &ttylist, list) + if (!strncmp(tt->tty, bp->ut_line, UT_LINESIZE)) + break; + + if (tt == NULL) { + /* add new one */ + tt = malloc(sizeof(struct ttytab)); + if (tt == NULL) + err(1, "malloc failure"); + tt->logout = currentout; + strncpy(tt->tty, bp->ut_line, UT_LINESIZE); + LIST_INSERT_HEAD(&ttylist, tt, list); + } + + /* + * print record if not in snapshot mode and wanted + * or in snapshot mode and in snapshot range + */ + if (bp->ut_name[0] && (want(bp) || (bp->ut_time < snaptime && + (tt->logout > snaptime || tt->logout < 1)))) { + snapfound = 1; + /* + * when uucp and ftp log in over a network, the entry in + * the utmp file is the name plus their process id. See + * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information. + */ + if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1)) + bp->ut_line[3] = '\0'; + else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1)) + bp->ut_line[4] = '\0'; + printentry(bp, tt); + if (maxrec != -1 && !--maxrec) + return; + } + tt->logout = bp->ut_time; +} + +/* + * printentry -- + * output an entry + * + * If `tt' is non-NULL, use it and `crmsg' to print the logout time or + * logout type (crash/shutdown) as appropriate. + */ +void +printentry(bp, tt) + struct utmp *bp; + struct ttytab *tt; +{ + char ct[80]; + struct tm *tm; + time_t delta; /* time difference */ + time_t t; + + t = _int_to_time(bp->ut_time); + tm = localtime(&t); + (void) strftime(ct, sizeof(ct), d_first ? "%a %e %b %R" : + "%a %b %e %R", tm); + printf("%-*.*s %-*.*s %-*.*s %s%c", + UT_NAMESIZE, UT_NAMESIZE, bp->ut_name, + UT_LINESIZE, UT_LINESIZE, bp->ut_line, + UT_HOSTSIZE, UT_HOSTSIZE, bp->ut_host, + ct, tt == NULL ? '\n' : ' '); + if (tt == NULL) + return; + if (!tt->logout) { + puts(" still logged in"); + return; + } + if (tt->logout < 0) { + tt->logout = -tt->logout; + printf("- %s", crmsg); + } else { + tm = localtime(&tt->logout); + (void) strftime(ct, sizeof(ct), "%R", tm); + printf("- %s", ct); + } + delta = tt->logout - bp->ut_time; + if (sflag) { + printf(" (%8ld)\n", (long)delta); + } else { + tm = gmtime(&delta); + (void) strftime(ct, sizeof(ct), width >= 8 ? "%T" : "%R", tm); + if (delta < 86400) + printf(" (%s)\n", ct); + else + printf(" (%ld+%s)\n", (long)delta / 86400, ct); + } +} + +/* * want -- * see if want this entry */ @@ -402,7 +404,7 @@ if (!strncmp(step->name, bp->ut_name, UT_NAMESIZE)) return (YES); break; - } + } return (NO); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Feb 25 9:18:27 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mailsrv.otenet.gr (mailsrv.otenet.gr [195.170.0.5]) by hub.freebsd.org (Postfix) with ESMTP id AF92637B405 for ; Mon, 25 Feb 2002 09:18:20 -0800 (PST) Received: from hades.hell.gr (patr530-a051.otenet.gr [212.205.215.51]) by mailsrv.otenet.gr (8.12.2/8.12.2) with ESMTP id g1PHICki001054 for ; Mon, 25 Feb 2002 19:18:15 +0200 (EET) Received: (from charon@localhost) by hades.hell.gr (8.11.6/8.11.6) id g1PG16U32686 for freebsd-audit@freebsd.org; Mon, 25 Feb 2002 18:01:06 +0200 (EET) (envelope-from keramida@freebsd.org) Date: Mon, 25 Feb 2002 18:01:05 +0200 From: Giorgos Keramidas To: freebsd-audit@freebsd.org Subject: Comment update in src/Makefile Message-ID: <20020225160105.GA31651@hades.hell.gr> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.25i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG src/Makefile references Makefile.inc0 although that file was removed a couple of years back: $ cvs -q log Makefile.inc0 ---------------------------- revision 1.19 date: 2000/01/09 20:22:35; author: marcel; state: dead; lines: +1 -1 Remove; we don't use this file anymore. What do you all think of the following change to src/Makefile? - Giorgos Index: Makefile =================================================================== RCS file: /home/ncvs/src/Makefile,v retrieving revision 1.247 diff -2 -u -r1.247 Makefile --- Makefile 8 Feb 2002 09:48:34 -0000 1.247 +++ Makefile 25 Feb 2002 15:54:16 -0000 @@ -31,7 +31,5 @@ # the mk files from the source tree which are supposed to DTRT. # -# The user-driven targets (as listed above) are implemented in Makefile.inc0 -# and the private targets are in Makefile.inc1. These are kept separate -# to help the bootstrap build from aout to elf format. +# The user-driven targets (as listed above) are implemented in Makefile.inc1. # # For novices wanting to build from current sources, the simple instructions To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed Feb 27 13:50:33 2002 Delivered-To: freebsd-audit@freebsd.org Received: from dragon.nuxi.com (trang.nuxi.com [66.92.13.169]) by hub.freebsd.org (Postfix) with ESMTP id 7CEAB37B41B for ; Wed, 27 Feb 2002 13:50:17 -0800 (PST) Received: (from obrien@localhost) by dragon.nuxi.com (8.11.6/8.11.1) id g1RLo1D85629; Wed, 27 Feb 2002 13:50:01 -0800 (PST) (envelope-from obrien) Date: Wed, 27 Feb 2002 13:50:00 -0800 From: "David O'Brien" To: Mark Murray Cc: audit@freebsd.org Subject: Re: lib/csu cleanup Message-ID: <20020227135000.A85486@dragon.nuxi.com> Reply-To: obrien@freebsd.org References: <200201172146.g0HLkft13995@grimreaper.grondar.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <200201172146.g0HLkft13995@grimreaper.grondar.org>; from mark@grondar.za on Thu, Jan 17, 2002 at 09:46:41PM +0000 X-Operating-System: FreeBSD 5.0-CURRENT Organization: The NUXI BSD group X-Pgp-Rsa-Fingerprint: B7 4D 3E E9 11 39 5F A3 90 76 5D 69 58 D9 98 7A X-Pgp-Rsa-Keyid: 1024/34F9F9D5 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Thu, Jan 17, 2002 at 09:46:41PM +0000, Mark Murray wrote: > Index: alpha/crt1.c > =================================================================== > RCS file: /home/ncvs/src/lib/csu/alpha/crt1.c,v > retrieving revision 1.10 > diff -u -d -r1.10 crt1.c > --- alpha/crt1.c 26 Oct 2001 06:45:10 -0000 1.10 > +++ alpha/crt1.c 17 Jan 2002 21:11:52 -0000 ... > /* > * NOTE: Leave the RCS ID _after_ __start(), in case it gets placed in .text. > */ > -#ifndef lint > -static const char rcsid[] = > - "$FreeBSD: src/lib/csu/alpha/crt1.c,v 1.10 2001/10/26 06:45:10 obrien Exp $"; > -#endif > + > +__FBSDID("$FreeBSD: src/lib/csu/alpha/crt1.c,v 1.10 2001/10/26 06:45:10 obrien Exp $"); I am not comfortable with this change. __FBSDID has several ways of implimenting its functionality. In crt*.0 we must be careful what goes into the files, how, and where. -- -- David (obrien@FreeBSD.org) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed Feb 27 15: 0:29 2002 Delivered-To: freebsd-audit@freebsd.org Received: from storm.FreeBSD.org.uk (storm.FreeBSD.org.uk [194.242.139.170]) by hub.freebsd.org (Postfix) with ESMTP id A69C737B402; Wed, 27 Feb 2002 15:00:21 -0800 (PST) Received: (from uucp@localhost) by storm.FreeBSD.org.uk (8.11.6/8.11.6) with UUCP id g1RN0Kv23526; Wed, 27 Feb 2002 23:00:20 GMT (envelope-from mark@grimreaper.grondar.za) Received: from grimreaper (localhost [127.0.0.1]) by grimreaper.grondar.org (8.12.2/8.12.2) with ESMTP id g1RMv6g4038944; Wed, 27 Feb 2002 22:57:06 GMT (envelope-from mark@grimreaper.grondar.za) Message-Id: <200202272257.g1RMv6g4038944@grimreaper.grondar.org> To: obrien@freebsd.org Cc: Mark Murray , audit@freebsd.org Subject: Re: lib/csu cleanup References: <20020227135000.A85486@dragon.nuxi.com> In-Reply-To: <20020227135000.A85486@dragon.nuxi.com> ; from "David O'Brien" "Wed, 27 Feb 2002 13:50:00 PST." Date: Wed, 27 Feb 2002 22:57:05 +0000 From: Mark Murray Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG > I am not comfortable with this change. __FBSDID has several ways of > implimenting its functionality. In crt*.0 we must be careful what goes > into the files, how, and where. Understood; I put it there under BDE's direction. How about I put a a __FBSDID() there (for orthogonality), but #ifdef 0 it out? M -- o Mark Murray \_ FreeBSD Services Limited O.\_ Warning: this .sig is umop ap!sdn To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat Mar 2 10:13:23 2002 Delivered-To: freebsd-audit@freebsd.org Received: from gate.sim.ionidea.com (ion.so-com.net [212.110.132.83]) by hub.freebsd.org (Postfix) with ESMTP id C412F37B402; Sat, 2 Mar 2002 10:12:53 -0800 (PST) Received: (from phantom@localhost) by gate.sim.ionidea.com (8.11.6/8.11.1) id g22IOc901091; Sat, 2 Mar 2002 20:24:38 +0200 (EET) (envelope-from phantom) Date: Sat, 2 Mar 2002 20:24:37 +0200 From: Alexey Zelkin To: audit@FreeBSD.org Cc: ache@FreeBSD.org Subject: safety checking for catgets (NLS catalogs) Message-ID: <20020302202437.A1078@gate.sim.ionidea.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.20i X-Operating-System: FreeBSD 4.2-RELEASE i386 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Folks, In order to prepare of some internationalization work for base tree tools I have reviewed some security cases applied to NLS catalogs handling system. Actually the only thing which make cause problems is possibly stale catalogs or intentionaly broken ones. I have wrote patch which is responsible for runtime checking of strings retrived by NLS system from message catalog and default (not translated) version of this string provided by application. In case if formating specifiers in these strings are different, misplaced or not balanced catgets() will return default version of the message instead of retrived. It guarantees that no unexpected effects will appear while processing of pre-loaded NLS messages with printf()'like functions. Also this patch is adding some kind of runtime verbosity information. It's not related to security, but actually useful for developers. Index: catgets.3 =================================================================== RCS file: /home/cvs/freebsd/src/lib/libc/nls/catgets.3,v retrieving revision 1.11 diff -u -r1.11 catgets.3 --- catgets.3 1 Oct 2001 16:08:56 -0000 1.11 +++ catgets.3 2 Mar 2002 18:09:41 -0000 @@ -52,12 +52,47 @@ .Fa s points to a default message which is returned if the function is unable to retrieve the specified message. +.Sh SECURITY CONSIDERATIONS +Before returning of message retrived from the message catalog +.Fn catgets +will perform internal sanity check of retrived message and default +message provided by application. Aim of this check is to make +sure that formating specifiers provided by both messages are +same and balanced. If check is failed (messages have different +format specifiers) default message is returned. +.Sh ENVIRONMENT +The following environment variables affect the execution of the +.Fn catgets +function: +.Bl -tag -width ".Ev NLS_VERBOSE" +.It Ev NLS_VERBOSE +If the environment variable +.Ev NLS_VERBOSE +is set, catgets will report runtime inconsistences of opened +message catalog to stdandard error output. See +.Sx DIAGNOSTIC MESSAGES +for more information. +.El .Sh RETURN VALUES If the specified message was retrieved successfully, .Fn catgets returns a pointer to an internal buffer containing the message string; otherwise it returns .Fa s . +.Sh DIAGNOSTIC MESSAGES +If the environment variable +.Ev NLS_VERBOSE +is set, following diagnostics messages may appear in standard error +output: +.Pp +.Bl -diag +.It "(NLS verbose): unsafe message: setId = XX, msgId = YY" +Internal sanity check for formatting specifiers of retrived from the +message catalog string against default message provided by application +is failed. +.It "(NLS verbose): missing message: setId = XX, msgId = YY" +Requested message is not available in the specified message catalog. +.El .Sh SEE ALSO .Xr gencat 1 , .Xr catclose 3 , Index: msgcat.c =================================================================== RCS file: /home/cvs/freebsd/src/lib/libc/nls/msgcat.c,v retrieving revision 1.38 diff -u -r1.38 msgcat.c --- msgcat.c 13 Aug 2001 14:06:26 -0000 1.38 +++ msgcat.c 2 Mar 2002 18:13:25 -0000 @@ -58,15 +58,24 @@ #define _DEFAULT_NLS_PATH "/usr/share/nls/%L/%N.cat:/usr/share/nls/%N/%L:/usr/local/share/nls/%L/%N.cat:/usr/local/share/nls/%N/%L" +/* + * List of valid conversion specifiers for *printf() and strfmon(). These + * are used to determine safety of the message catalog's version of string. + */ +#define VALID_CONV_SPECIFIERS "cDdiAaEefFgGnOopsUuXx" + #define TRUE 1 #define FALSE 0 #define NLERR ((nl_catd) -1) #define NLRETERR(errc) errno = errc; return(NLERR); +static int nls_verbose = FALSE; + static nl_catd loadCat(); static int loadSet(); static void __nls_free_resources(); +static int msg_unsafe(); nl_catd catopen( name, type) @@ -83,6 +92,8 @@ NLRETERR(ENOENT); } + nls_verbose = (getenv("NLS_VERBOSE") == NULL) ? FALSE : TRUE; + /* is it absolute path ? if yes, load immidiately */ if (strchr(name, '/')) return loadCat(name); @@ -271,12 +282,24 @@ if (catd == NULL || catd == NLERR) return((char *)dflt); msg = MCGetMsg(MCGetSet(cat, setId), msgId); - if (msg != NULL) cptr = msg->msg.str; - else cptr = dflt; + if (msg != NULL) { + cptr = msg->msg.str; + if (msg_unsafe(cptr, dflt)) { + if (nls_verbose == TRUE) + printf ("(NLS verbose): unsafe message: setId = %d, msgId = %d\n" + "(NLS verbose): original = \"%s\",\n" + "(NLS verbose): default = \"%s\"\n", setId, msgId, cptr, dflt); + cptr = dflt; + } + } else { + if (nls_verbose == TRUE) + printf ("(NLS verbose): missing message: setId = %d, msgId = %d\n" + "(NLS verbose): default = \"%s\"\n", setId, msgId, dflt); + cptr = dflt; + } return((char *)cptr); } - int catclose( catd) nl_catd catd; @@ -457,4 +480,58 @@ } set->invalid = FALSE; return(1); +} + +/* + * Return pointer to first valid '%'. + * '%%' case handled as usual character. + */ +static char * +msg_skip(ptr) + char *ptr; +{ + while (ptr) { + while (*ptr != '%' && *ptr != '\0') ptr++; + if (*ptr == '\0') + break; + ptr++; + if (*ptr != '%') { + ptr--; + break; + } + ptr++; + } + return (ptr); +} + +/* + * Validate message retrived from the message catalog against default + * message provided by the application. Main aim of this check is to make + * sure that format specifiers are same and balanced in both cases. + */ +static int +msg_unsafe(src, dflt) + char *src; + char *dflt; +{ + if (src == NULL || dflt == NULL) + return (1); + + src = msg_skip(src); + dflt = msg_skip(dflt); + while (*src != '\0' && *dflt != '\0') { + while (1) { + if (*dflt != *src) + return (1); + if (strchr(VALID_CONV_SPECIFIERS, *dflt)) + break; + src++; + dflt++; + } + src = msg_skip(src); + dflt = msg_skip(dflt); + } + if (*src != *dflt) + return (1); + return (0); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat Mar 2 10:47:29 2002 Delivered-To: freebsd-audit@freebsd.org Received: from nagual.pp.ru (pobrecita.freebsd.ru [194.87.13.42]) by hub.freebsd.org (Postfix) with ESMTP id E6FC037B400; Sat, 2 Mar 2002 10:47:26 -0800 (PST) Received: from pobrecita.freebsd.ru (ache@localhost [127.0.0.1]) by nagual.pp.ru (8.12.2/8.12.2) with ESMTP id g22Il2Yl032322; Sat, 2 Mar 2002 21:47:19 +0300 (MSK) (envelope-from ache@pobrecita.freebsd.ru) Received: (from ache@localhost) by pobrecita.freebsd.ru (8.12.2/8.12.2/Submit) id g22Ikxmq032321; Sat, 2 Mar 2002 21:47:00 +0300 (MSK) Date: Sat, 2 Mar 2002 21:46:57 +0300 From: "Andrey A. Chernov" To: Alexey Zelkin Cc: audit@FreeBSD.org Subject: Re: safety checking for catgets (NLS catalogs) Message-ID: <20020302184656.GA32218@nagual.pp.ru> References: <20020302202437.A1078@gate.sim.ionidea.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20020302202437.A1078@gate.sim.ionidea.com> User-Agent: Mutt/1.3.27i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG I dislike whole idea, it just add yet one runtime slowness. Suser programs authors should just check their translations more accurately. Better way to solve it is to add external check tool to run through all existen catalogs for given program, do it once and not each run time. Translation strings are per program version constants and not changed each run time, so there is absolutely no needs to check them each run time. On Sat, Mar 02, 2002 at 20:24:37 +0200, Alexey Zelkin wrote: > + while (*src != '\0' && *dflt != '\0') { > + while (1) { > + if (*dflt != *src) > + return (1); > + if (strchr(VALID_CONV_SPECIFIERS, *dflt)) *dflt can be '\0' here and strchr() will succeed. > + break; > + src++; > + dflt++; > + } -- Andrey A. Chernov http://ache.pp.ru/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message