From owner-svn-src-all@freebsd.org Fri Dec 16 02:06:36 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0122DC771FF; Fri, 16 Dec 2016 02:06:36 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CFFFA1784; Fri, 16 Dec 2016 02:06:35 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBG26ZqB024962; Fri, 16 Dec 2016 02:06:35 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBG26Z74024961; Fri, 16 Dec 2016 02:06:35 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201612160206.uBG26Z74024961@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: "Conrad E. Meyer" Date: Fri, 16 Dec 2016 02:06:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r310144 - head/usr.bin/iconv X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Dec 2016 02:06:36 -0000 Author: cem Date: Fri Dec 16 02:06:34 2016 New Revision: 310144 URL: https://svnweb.freebsd.org/changeset/base/310144 Log: iconv(1): Capsicumify This takes the usual shortcut of only sandboxing the last input file. It's a first cut and this program will be easy to adapt to sandbox all files in the future. iconv(1) has been changed to only open the conversion descriptor once, since the input and output encodings are fixed over all inputs. Instead, the descriptor is simply reset after each use (documented in iconv(3) API). Reviewed by: no one, unfortunately Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D7917 Modified: head/usr.bin/iconv/iconv.c Modified: head/usr.bin/iconv/iconv.c ============================================================================== --- head/usr.bin/iconv/iconv.c Fri Dec 16 02:03:40 2016 (r310143) +++ head/usr.bin/iconv/iconv.c Fri Dec 16 02:06:34 2016 (r310144) @@ -28,7 +28,9 @@ */ #include +#include +#include #include #include #include @@ -41,7 +43,7 @@ #include #include -static int do_conv(FILE *, const char *, const char *, bool, bool); +static int do_conv(FILE *, iconv_t, bool, bool); static int do_list(unsigned int, const char * const *, void *); static void usage(void) __dead2; @@ -67,23 +69,16 @@ usage(void) #define INBUFSIZE 1024 #define OUTBUFSIZE (INBUFSIZE * 2) static int -do_conv(FILE *fp, const char *from, const char *to, bool silent, - bool hide_invalid) +do_conv(FILE *fp, iconv_t cd, bool silent, bool hide_invalid) { - iconv_t cd; char inbuf[INBUFSIZE], outbuf[OUTBUFSIZE], *in, *out; unsigned long long invalids; size_t inbytes, outbytes, ret; - if ((cd = iconv_open(to, from)) == (iconv_t)-1) - err(EXIT_FAILURE, "iconv_open(%s, %s)", to, from); - - if (hide_invalid) { - int arg = 1; + int arg = (int)hide_invalid; + if (iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, (void *)&arg) == -1) + err(EXIT_FAILURE, "iconvctl(DISCARD_ILSEQ, %d)", arg); - if (iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, (void *)&arg) == -1) - err(EXIT_FAILURE, NULL); - } invalids = 0; while ((inbytes = fread(inbuf, 1, INBUFSIZE, fp)) > 0) { in = inbuf; @@ -133,7 +128,6 @@ do_conv(FILE *fp, const char *from, cons if (invalids > 0 && !silent) warnx("warning: invalid characters: %llu", invalids); - iconv_close(cd); return (invalids > 0); } @@ -155,6 +149,7 @@ do_list(unsigned int n, const char * con int main(int argc, char **argv) { + iconv_t cd; FILE *fp; const char *opt_f, *opt_t; int ch, i, res; @@ -201,9 +196,28 @@ main(int argc, char **argv) argv += optind; if ((strcmp(opt_f, "") == 0) && (strcmp(opt_t, "") == 0)) usage(); - if (argc == 0) - res = do_conv(stdin, opt_f, opt_t, opt_s, opt_c); - else { + + if (caph_limit_stdio() < 0) + err(EXIT_FAILURE, "capsicum"); + + /* + * Cache NLS data, for strerror, for err(3), before entering capability + * mode. + */ + caph_cache_catpages(); + + /* + * Cache iconv conversion handle before entering sandbox. + */ + cd = iconv_open(opt_t, opt_f); + if (cd == (iconv_t)-1) + err(EXIT_FAILURE, "iconv_open(%s, %s)", opt_t, opt_f); + + if (argc == 0) { + if (cap_enter() < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to enter capability mode"); + res = do_conv(stdin, cd, opt_s, opt_c); + } else { res = 0; for (i = 0; i < argc; i++) { fp = (strcmp(argv[i], "-") != 0) ? @@ -211,9 +225,17 @@ main(int argc, char **argv) if (fp == NULL) err(EXIT_FAILURE, "Cannot open `%s'", argv[i]); - res |= do_conv(fp, opt_f, opt_t, opt_s, opt_c); + /* Enter Capsicum sandbox for final input file. */ + if (i + 1 == argc && cap_enter() < 0 && errno != ENOSYS) + err(EXIT_FAILURE, + "unable to enter capability mode"); + res |= do_conv(fp, cd, opt_s, opt_c); (void)fclose(fp); + + /* Reset iconv descriptor state. */ + (void)iconv(cd, NULL, NULL, NULL, NULL); } } + iconv_close(cd); return (res == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }