Sun Jul 31 23:30:28 2016 UTC ()
Apply patch from PR 43587, mostly from martin and kre. When writing a
sysctl variable using ?= fails with EPERM, don't print an error
message.

Ideally setting a sysctl to the same value it already has should also
not fail regardless of permissions, but this would need to be done in
the kernel.


(dholland)
diff -r1.157 -r1.158 src/sbin/sysctl/sysctl.c

cvs diff -r1.157 -r1.158 src/sbin/sysctl/sysctl.c (expand / switch to unified diff)

--- src/sbin/sysctl/sysctl.c 2015/12/13 14:24:47 1.157
+++ src/sbin/sysctl/sysctl.c 2016/07/31 23:30:28 1.158
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sysctl.c,v 1.157 2015/12/13 14:24:47 christos Exp $ */ 1/* $NetBSD: sysctl.c,v 1.158 2016/07/31 23:30:28 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Brown. 8 * by Andrew Brown.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -58,27 +58,27 @@ @@ -58,27 +58,27 @@
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 */ 59 */
60 60
61#include <sys/cdefs.h> 61#include <sys/cdefs.h>
62#ifndef lint 62#ifndef lint
63__COPYRIGHT("@(#) Copyright (c) 1993\ 63__COPYRIGHT("@(#) Copyright (c) 1993\
64 The Regents of the University of California. All rights reserved."); 64 The Regents of the University of California. All rights reserved.");
65#endif /* not lint */ 65#endif /* not lint */
66 66
67#ifndef lint 67#ifndef lint
68#if 0 68#if 0
69static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93"; 69static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93";
70#else 70#else
71__RCSID("$NetBSD: sysctl.c,v 1.157 2015/12/13 14:24:47 christos Exp $"); 71__RCSID("$NetBSD: sysctl.c,v 1.158 2016/07/31 23:30:28 dholland Exp $");
72#endif 72#endif
73#endif /* not lint */ 73#endif /* not lint */
74 74
75#include <sys/types.h> 75#include <sys/types.h>
76#include <sys/param.h> 76#include <sys/param.h>
77#include <sys/sysctl.h> 77#include <sys/sysctl.h>
78#include <sys/mount.h> 78#include <sys/mount.h>
79#include <sys/resource.h> 79#include <sys/resource.h>
80#include <sys/stat.h> 80#include <sys/stat.h>
81#include <sys/sched.h> 81#include <sys/sched.h>
82#include <sys/socket.h> 82#include <sys/socket.h>
83#include <sys/bitops.h> 83#include <sys/bitops.h>
84#include <netinet/in.h> 84#include <netinet/in.h>
@@ -118,28 +118,28 @@ __RCSID("$NetBSD: sysctl.c,v 1.157 2015/ @@ -118,28 +118,28 @@ __RCSID("$NetBSD: sysctl.c,v 1.157 2015/
118 u_int type, void *v 118 u_int type, void *v
119#define DISPLAY_VALUE 0 119#define DISPLAY_VALUE 0
120#define DISPLAY_OLD 1 120#define DISPLAY_OLD 1
121#define DISPLAY_NEW 2 121#define DISPLAY_NEW 2
122 122
123/* 123/*
124 * generic routines 124 * generic routines
125 */ 125 */
126static const struct handlespec *findhandler(const char *, regex_t *, size_t *); 126static const struct handlespec *findhandler(const char *, regex_t *, size_t *);
127static void canonicalize(const char *, char *); 127static void canonicalize(const char *, char *);
128static void purge_tree(struct sysctlnode *); 128static void purge_tree(struct sysctlnode *);
129static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *, 129static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *,
130 size_t *); 130 size_t *);
131static void write_number(int *, u_int, struct sysctlnode *, char *); 131static void write_number(int *, u_int, struct sysctlnode *, char *, bool);
132static void write_string(int *, u_int, struct sysctlnode *, char *); 132static void write_string(int *, u_int, struct sysctlnode *, char *, bool);
133static void display_number(const struct sysctlnode *, const char *, 133static void display_number(const struct sysctlnode *, const char *,
134 const void *, size_t, int); 134 const void *, size_t, int);
135static void display_string(const struct sysctlnode *, const char *, 135static void display_string(const struct sysctlnode *, const char *,
136 const void *, size_t, int); 136 const void *, size_t, int);
137static void display_struct(const struct sysctlnode *, const char *, 137static void display_struct(const struct sysctlnode *, const char *,
138 const void *, size_t, int); 138 const void *, size_t, int);
139static void hex_dump(const unsigned char *, size_t); 139static void hex_dump(const unsigned char *, size_t);
140__dead static void usage(void); 140__dead static void usage(void);
141static void parse(char *, regex_t *, size_t *); 141static void parse(char *, regex_t *, size_t *);
142static void parse_create(char *); 142static void parse_create(char *);
143static void parse_destroy(char *); 143static void parse_destroy(char *);
144static void parse_describe(char *); 144static void parse_describe(char *);
145static void getdesc1(int *, u_int, struct sysctlnode *); 145static void getdesc1(int *, u_int, struct sysctlnode *);
@@ -936,30 +936,30 @@ parse(char *l, regex_t *re, size_t *last @@ -936,30 +936,30 @@ parse(char *l, regex_t *re, size_t *last
936 } 936 }
937 937
938 switch (type) { 938 switch (type) {
939 case CTLTYPE_NODE: 939 case CTLTYPE_NODE:
940 /* 940 /*
941 * XXX old behavior is to print. should we error instead? 941 * XXX old behavior is to print. should we error instead?
942 */ 942 */
943 print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re, 943 print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re,
944 lastcompiled); 944 lastcompiled);
945 break; 945 break;
946 case CTLTYPE_INT: 946 case CTLTYPE_INT:
947 case CTLTYPE_BOOL: 947 case CTLTYPE_BOOL:
948 case CTLTYPE_QUAD: 948 case CTLTYPE_QUAD:
949 write_number(&name[0], namelen, node, value); 949 write_number(&name[0], namelen, node, value, optional);
950 break; 950 break;
951 case CTLTYPE_STRING: 951 case CTLTYPE_STRING:
952 write_string(&name[0], namelen, node, value); 952 write_string(&name[0], namelen, node, value, optional);
953 break; 953 break;
954 case CTLTYPE_STRUCT: 954 case CTLTYPE_STRUCT:
955 /* 955 /*
956 * XXX old behavior is to print. should we error instead? 956 * XXX old behavior is to print. should we error instead?
957 */ 957 */
958 /* fprintf(warnfp, "you can't write to %s\n", gsname); */ 958 /* fprintf(warnfp, "you can't write to %s\n", gsname); */
959 print_tree(&name[0], namelen, node, type, 0, re, lastcompiled); 959 print_tree(&name[0], namelen, node, type, 0, re, lastcompiled);
960 break; 960 break;
961 } 961 }
962} 962}
963 963
964/* 964/*
965 965
@@ -1744,27 +1744,28 @@ sysctlperror(const char *fmt, ...) @@ -1744,27 +1744,28 @@ sysctlperror(const char *fmt, ...)
1744 va_start(ap, fmt); 1744 va_start(ap, fmt);
1745 (void)vfprintf(warnfp, fmt, ap); 1745 (void)vfprintf(warnfp, fmt, ap);
1746 va_end(ap); 1746 va_end(ap);
1747 errs++; 1747 errs++;
1748} 1748}
1749 1749
1750 1750
1751/* 1751/*
1752 * ******************************************************************** 1752 * ********************************************************************
1753 * how to write to a "simple" node 1753 * how to write to a "simple" node
1754 * ******************************************************************** 1754 * ********************************************************************
1755 */ 1755 */
1756static void 1756static void
1757write_number(int *name, u_int namelen, struct sysctlnode *node, char *value) 1757write_number(int *name, u_int namelen, struct sysctlnode *node, char *value,
 1758 bool optional)
1758{ 1759{
1759 u_int ii, io; 1760 u_int ii, io;
1760 u_quad_t qi, qo; 1761 u_quad_t qi, qo;
1761 size_t si, so; 1762 size_t si, so;
1762 bool bi, bo; 1763 bool bi, bo;
1763 int rc; 1764 int rc;
1764 void *i, *o; 1765 void *i, *o;
1765 char *t; 1766 char *t;
1766 1767
1767 if (fn) 1768 if (fn)
1768 trim_whitespace(value, 3); 1769 trim_whitespace(value, 3);
1769 1770
1770 si = so = 0; 1771 si = so = 0;
@@ -1801,69 +1802,75 @@ write_number(int *name, u_int namelen, s @@ -1801,69 +1802,75 @@ write_number(int *name, u_int namelen, s
1801 i = &bi; 1802 i = &bi;
1802 si = sizeof(bi); 1803 si = sizeof(bi);
1803 break; 1804 break;
1804 case CTLTYPE_QUAD: 1805 case CTLTYPE_QUAD:
1805 o = &qo; 1806 o = &qo;
1806 so = sizeof(qo); 1807 so = sizeof(qo);
1807 i = &qi; 1808 i = &qi;
1808 si = sizeof(qi); 1809 si = sizeof(qi);
1809 break; 1810 break;
1810 } 1811 }
1811 1812
1812 rc = prog_sysctl(name, namelen, o, &so, i, si); 1813 rc = prog_sysctl(name, namelen, o, &so, i, si);
1813 if (rc == -1) { 1814 if (rc == -1) {
1814 sysctlerror(0); 1815 if (!optional || errno != EPERM) {
 1816 sysctlerror(0);
 1817 }
1815 return; 1818 return;
1816 } 1819 }
1817 1820
1818 switch (SYSCTL_TYPE(node->sysctl_flags)) { 1821 switch (SYSCTL_TYPE(node->sysctl_flags)) {
1819 case CTLTYPE_INT: 1822 case CTLTYPE_INT:
1820 display_number(node, gsname, &io, sizeof(io), DISPLAY_OLD); 1823 display_number(node, gsname, &io, sizeof(io), DISPLAY_OLD);
1821 display_number(node, gsname, &ii, sizeof(ii), DISPLAY_NEW); 1824 display_number(node, gsname, &ii, sizeof(ii), DISPLAY_NEW);
1822 break; 1825 break;
1823 case CTLTYPE_BOOL: 1826 case CTLTYPE_BOOL:
1824 display_number(node, gsname, &bo, sizeof(bo), DISPLAY_OLD); 1827 display_number(node, gsname, &bo, sizeof(bo), DISPLAY_OLD);
1825 display_number(node, gsname, &bi, sizeof(bi), DISPLAY_NEW); 1828 display_number(node, gsname, &bi, sizeof(bi), DISPLAY_NEW);
1826 break; 1829 break;
1827 case CTLTYPE_QUAD: 1830 case CTLTYPE_QUAD:
1828 display_number(node, gsname, &qo, sizeof(qo), DISPLAY_OLD); 1831 display_number(node, gsname, &qo, sizeof(qo), DISPLAY_OLD);
1829 display_number(node, gsname, &qi, sizeof(qi), DISPLAY_NEW); 1832 display_number(node, gsname, &qi, sizeof(qi), DISPLAY_NEW);
1830 break; 1833 break;
1831 } 1834 }
1832} 1835}
1833 1836
1834static void 1837static void
1835write_string(int *name, u_int namelen, struct sysctlnode *node, char *value) 1838write_string(int *name, u_int namelen, struct sysctlnode *node, char *value,
 1839 bool optional)
1836{ 1840{
1837 char *i, *o; 1841 char *i, *o;
1838 size_t si, so; 1842 size_t si, so;
1839 int rc; 1843 int rc;
1840 1844
1841 i = value; 1845 i = value;
1842 si = strlen(i) + 1; 1846 si = strlen(i) + 1;
1843 so = node->sysctl_size; 1847 so = node->sysctl_size;
1844 if (si > so && so != 0) { 1848 if (si > so && so != 0) {
1845 sysctlperror("%s: string too long\n", value); 1849 sysctlperror("%s: string too long\n", value);
1846 EXIT(EXIT_FAILURE); 1850 EXIT(EXIT_FAILURE);
1847 } 1851 }
1848 o = malloc(so); 1852 o = malloc(so);
1849 if (o == NULL) { 1853 if (o == NULL) {
1850 sysctlperror("%s: !malloc failed!\n", gsname); 1854 sysctlperror("%s: !malloc failed!\n", gsname);
1851 exit(EXIT_FAILURE); 1855 exit(EXIT_FAILURE);
1852 } 1856 }
1853 1857
1854 rc = prog_sysctl(name, namelen, o, &so, i, si); 1858 rc = prog_sysctl(name, namelen, o, &so, i, si);
1855 if (rc == -1) { 1859 if (rc == -1) {
1856 sysctlerror(0); 1860 if (!optional || errno != EPERM) {
 1861 sysctlerror(0);
 1862 }
 1863 free(o);
1857 return; 1864 return;
1858 } 1865 }
1859 1866
1860 display_string(node, gsname, o, so, DISPLAY_OLD); 1867 display_string(node, gsname, o, so, DISPLAY_OLD);
1861 display_string(node, gsname, i, si, DISPLAY_NEW); 1868 display_string(node, gsname, i, si, DISPLAY_NEW);
1862 free(o); 1869 free(o);
1863} 1870}
1864 1871
1865/* 1872/*
1866 * ******************************************************************** 1873 * ********************************************************************
1867 * simple ways to print stuff consistently 1874 * simple ways to print stuff consistently
1868 * ******************************************************************** 1875 * ********************************************************************
1869 */ 1876 */