Download raw body.
snmpd: allow arbitrary string length in mib.y
Hello,
Right now mib.y operates on text buffers of 16384 bytes. This is more
than enough for the MIB files we have in base, and was based on "this
supports enough MIB files that I'm happy with it for now" and I vaguely
remember hitting some limits when doubling the value, but can't quite
seem to recall where.
However, this limit did mean we use quite large buffers inside the
yacc parser, and still meant we had to drop a few MIB files that can
be found inside librenms' database, because of extremely long
DESCRIPTION sections.
With this diff we can gain the following files from librenms' database
in direct parsing:
- /var/www/librenms/mibs/cisco/CISCO-TC
- /var/www/librenms/mibs/cisco/CISCO-CLASS-BASED-QOS-MIB
We lose the following file because I moved the length checking into
yylex, which means that that identifiers and typereferences are now
checked early, and some variables from before fell through the
cracks. This includes enum labels (see RFC2578 section 7.1.1):
- /var/www/librenms/mibs/fortinet/MERU-TC
Then there's a couple of files who changed motivation, in which I'm
not too interested right now:
- /var/www/librenms/mibs/huawei/HUAWEI-ENTITY-TRAP-MIB
- /var/www/librenms/mibs/huawei/HUAWEI-TC-MIB
- /var/www/librenms/mibs/hp/BLADETYPE2-SWITCH-MIB
(now can't be parsed instead of missing symbols)
- /var/www/librenms/mibs/cisco/CISCO-SWITCH-ENGINE-MIB
(incorrect symbol import)
- /var/www/librenms/mibs/adva/CM-FACILITY-MIB
(IPV6-TC still doesn't parse)
- /var/www/librenms/mibs/comware/HH3C-QOS-CAPABILITY-MIB
(HH3C-OID-MIB still doesn't parse)
- /var/www/librenms/mibs/nokia/TIMETRA-OAM-TEST-MIB
(IEEE8021-CFM-MIB still doesn't resolve)
- /var/www/librenms/mibs/nokia/1830/TN-OAM-TEST-MIB
(IEEE8021-CFM-MIB still doesn't resolve)
With this we gain the following MIBs because they can now resolve all
their symbols:
- CISCO-VTP-MIB
- CISCO-PRIVATE-VLAN-MIB
- CISCO-AUTH-FRAMEWORK-MIB
- CISCO-CONFIG-MAN-MIB
- CISCO-SLB-MIB
- CISCO-ENHANCED-SLB-MIB
- CISCO-ENTITY-DIAG-MIB
- CISCO-ENTITY-EXT-MIB
- CISCO-ENTITY-SENSOR-MIB
- CISCO-ERR-DISABLE-MIB
- CISCO-IF-EXTENSION-MIB
- CISCO-IGMP-SNOOPING-MIB
- CISCO-MEDIA-GATEWAY-MIB
- CISCO-IPSEC-FLOW-MONITOR-MIB
- CISCO-LWAPP-WLAN-MIB
- CISCO-LWAPP-AP-MIB
- CISCO-LWAPP-RF-MIB
- CISCO-MAC-NOTIFICATION-MIB
- CISCO-PAGP-MIB
- CISCO-POWER-ETHERNET-EXT-MIB
- CISCO-PROCESS-MIB
- CISCO-SLB-EXT-MIB
- CISCO-SLB-HEALTH-MON-MIB
- CISCO-SNAPSHOT-MIB
- CISCO-STACKWISE-MIB
- CISCO-STP-EXTENSIONS-MIB
- CISCO-VLAN-IFTABLE-RELATIONSHIP-MIB
- CISCO-VLAN-MEMBERSHIP-MIB
- CISCO-WAN-OPTIMIZATION-MIB
While here also satisfy the includes when building with bison.
OK?
martijn@
diff f5e5829750f6127f5a1dc9c2407b424587303b2a 5b410676d7b6ff40dae953e6a4c1abd8a0ac1c12
commit - f5e5829750f6127f5a1dc9c2407b424587303b2a
commit + 5b410676d7b6ff40dae953e6a4c1abd8a0ac1c12
blob - ae33b64280fbcd9766287f60f2908d08fcfbf7f0
blob + de66c9e27c9bd33f317d0dd75f049004be12ed38
--- usr.sbin/snmpd/mib.y
+++ usr.sbin/snmpd/mib.y
@@ -19,8 +19,10 @@
%{
#include <sys/tree.h>
+#include <sys/types.h>
#include <assert.h>
+#include <stddef.h>
#include <ber.h>
#include <ctype.h>
#include <dirent.h>
@@ -30,6 +32,8 @@
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <strings.h>
#include <time.h>
@@ -44,12 +48,18 @@
#define MODULENAME_MAX 64
#define SYMBOLS_MAX 256
#define IMPORTS_MAX 16
-#define TEXT_MAX 16384
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
+struct text {
+ char string[DESCRIPTOR_MAX + 1];
+ char file[PATH_MAX];
+ off_t start;
+ off_t end;
+};
+
struct objidcomponent {
enum {
OCT_DESCRIPTOR,
@@ -202,29 +212,38 @@ int mib_item_oid(struct item *,
int mib_macro(const char *);
int mib_applicationsyntax(const char *);
struct item *mib_oid(const char *, const struct oid_unresolved *);
-int mib_moduleidentity(const char *, time_t, const char *,
- const char *, const char *, const struct oid_unresolved *);
-int mib_objectidentity(const char *, enum status, const char *,
- const char *, const struct oid_unresolved *);
-int mib_objecttype(const char *, void *, const char *,
- enum access, enum status, const char *, const char *,
- void *, void *, const struct oid_unresolved *);
+int mib_moduleidentity(const char *, time_t, const struct text *,
+ const struct text *, const struct text *,
+ const struct oid_unresolved *);
+int mib_objectidentity(const char *, enum status,
+ const struct text *, const struct text *,
+ const struct oid_unresolved *);
+int mib_objecttype(const char *, void *, const struct text *,
+ enum access, enum status, const struct text *,
+ const struct text *, void *, void *,
+ const struct oid_unresolved *);
int mib_notificationtype(const char *, void *, enum status,
- const char *, const char *, const struct oid_unresolved *);
-int mib_textualconvetion(const char *, const char *, enum status,
- const char *, const char *, void *);
+ const struct text *, const struct text *,
+ const struct oid_unresolved *);
+int mib_textualconvetion(const char *, const struct text *,
+ enum status, const struct text *, const struct text *,
+ void *);
int mib_objectgroup(const char *, void *, enum status,
- const char *, const char *, const struct oid_unresolved *);
+ const struct text *, const struct text *,
+ const struct oid_unresolved *);
int mib_notificationgroup(const char *, void *, enum status,
- const char *, const char *, const struct oid_unresolved *);
-int mib_modulecompliance(const char *, enum status, const char *,
- const char *, void *, const struct oid_unresolved *);
+ const struct text *, const struct text *,
+ const struct oid_unresolved *);
+int mib_modulecompliance(const char *, enum status,
+ const struct text *, const struct text *, void *,
+ const struct oid_unresolved *);
struct item *mib_item_find(struct item *, const char *);
struct item *mib_item_parent(struct ber_oid *);
-int mib_resolve_oid(struct oid_resolved *,
+int mib_resolve_oid(struct oid_resolved *,
struct oid_unresolved *, struct item *);
int mib_resolve_item(struct item *);
int mib_resolve_module(struct module *);
+char *text_get(struct text *, int *);
int module_cmp_cs(struct module *, struct module *);
int module_cmp_ci(struct module *, struct module *);
int item_cmp_cs(struct item *, struct item *);
@@ -266,7 +285,7 @@ struct file {
} file;
typedef union {
- char string[TEXT_MAX];
+ struct text text;
unsigned long long number;
long long signednumber;
char symbollist[SYMBOLS_MAX][DESCRIPTOR_MAX + 1];
@@ -280,7 +299,6 @@ typedef union {
%}
%token ERROR
-%token HSTRING BSTRING
/* RFC2578 section 3.7 */
%token ABSENT ACCESS AGENTCAPABILITIES ANY APPLICATION AUGMENTS BEGIN
@@ -305,16 +323,16 @@ typedef union {
/* X.208 */
%token PRODUCTION RANGESEPARATOR
-%token <string> typereference identifier TEXT HSTRING BSTRING
+%token <text> typereference identifier TEXT HSTRING BSTRING
%token <number> NUMBER
%token <signednumber> SIGNEDNUMBER
-%type <string> moduleidentifier smiv2moduleidentifier
+%type <text> moduleidentifier smiv2moduleidentifier
%type <import> symbolsfrom
%type <symbollist> symbollist
-%type <string> descriptor symbol
+%type <text> descriptor symbol
%type <objidcomponent>objidcomponentfirst objidcomponent
%type <oid> objidcomponentlist objectidentifiervalue
-%type <string> displaypart referpart unitspart
+%type <text> displaypart referpart unitspart
%type <time> lastupdated
%type <status> status
%type <access> access
@@ -335,13 +353,8 @@ module : moduleidentifier DEFINITIONS PRODUCTION BEG
RB_INIT(&module->itemscs);
RB_INIT(&module->itemsci);
module->resolved = 0;
- if (strlcpy(module->name, $1,
- sizeof(module->name)) >=
- sizeof(module->name)) {
- yyerror("module name too long");
- free(module);
- YYERROR;
- }
+ (void)strlcpy(module->name, $1.string,
+ sizeof(module->name));
} imports moduleidentity modulebody END {
struct module *mprev;
@@ -367,12 +380,21 @@ module : moduleidentifier DEFINITIONS PRODUCTION BEG
}
;
-moduleidentifier : typereference { strlcpy($$, $1, sizeof($$)); }
+moduleidentifier : typereference { $$ = $1; }
;
-smiv2moduleidentifier : SNMPv2SMI { strlcpy($$, "SNMPv2-SMI", sizeof($$)); }
- | SNMPv2CONF { strlcpy($$, "SNMPv2-CONF", sizeof($$)); }
- | SNMPv2TC { strlcpy($$, "SNMPv2-TC", sizeof($$)); }
+smiv2moduleidentifier : SNMPv2SMI {
+ strlcpy($$.string,
+ "SNMPv2-SMI", sizeof($$.string));
+ }
+ | SNMPv2CONF {
+ strlcpy($$.string,
+ "SNMPv2-CONF", sizeof($$.string));
+ }
+ | SNMPv2TC {
+ strlcpy($$.string,
+ "SNMPv2-TC", sizeof($$.string));
+ }
;
modulebody : assignmentlist
@@ -393,7 +415,7 @@ symbolsfrom : symbollist FROM moduleidentifier {
symbols[i] = $1[i];
symbols[i] = NULL;
- if (mib_imports_add($3, symbols) == -1)
+ if (mib_imports_add($3.string, symbols) == -1)
YYERROR;
}
| symbollist FROM smiv2moduleidentifier {
@@ -404,7 +426,7 @@ symbolsfrom : symbollist FROM moduleidentifier {
symbols[i] = $1[i];
symbols[i] = NULL;
- if (mib_imports_add($3, symbols) == -1)
+ if (mib_imports_add($3.string, symbols) == -1)
YYERROR;
file.state = FILE_SMI2;
@@ -419,69 +441,92 @@ symbollist : symbollist ',' symbol {
yyerror("too many symbols from module");
YYERROR;
}
- if (strlcpy($$[i], $3, sizeof($$[i])) >=
- sizeof($$[i])) {
- yyerror("symbol too long");
- YYERROR;
- }
+ (void)strlcpy($$[i], $3.string, sizeof($$[i]));
$$[i + 1][0] = '\0';
}
| symbol {
- if (strlcpy($$[0], $1, sizeof($$[0])) >=
- sizeof($$[0])) {
- yyerror("symbol too long");
- YYERROR;
- }
+ (void)strlcpy($$[0], $1.string, sizeof($$[0]));
$$[1][0] = '\0';
}
;
-symbol : typereference { strlcpy($$, $1, sizeof($$)); }
- | descriptor { strlcpy($$, $1, sizeof($$)); }
+symbol : typereference { $$ = $1; }
+ | descriptor { $$ = $1; }
/* SNMPv2-SMI */
| MODULEIDENTITY {
- strlcpy($$, "MODULE-IDENTITY", sizeof($$));
+ (void)strlcpy($$.string,
+ "MODULE-IDENTITY", sizeof($$.string));
}
| OBJECTIDENTITY {
- strlcpy($$, "OBJECT-IDENTITY", sizeof($$));
+ (void)strlcpy($$.string,
+ "OBJECT-IDENTITY", sizeof($$.string));
}
- | Integer32 { strlcpy($$, "Integer32", sizeof($$)); }
- | IpAddress { strlcpy($$, "IpAddress", sizeof($$)); }
- | Counter32 { strlcpy($$, "Counter32", sizeof($$)); }
- | Gauge32 { strlcpy($$, "Gauge32", sizeof($$)); }
- | Unsigned32 { strlcpy($$, "Unsigned32", sizeof($$)); }
- | TimeTicks { strlcpy($$, "TimeTicks", sizeof($$)); }
- | Opaque { strlcpy($$, "Opaque", sizeof($$)); }
- | Counter64 { strlcpy($$, "Counter64", sizeof($$)); }
- | OBJECTTYPE { strlcpy($$, "OBJECT-TYPE", sizeof($$)); }
+ | Integer32 {
+ (void)strlcpy($$.string,
+ "Integer32", sizeof($$.string));
+ }
+ | IpAddress {
+ (void)strlcpy($$.string,
+ "IpAddress", sizeof($$.string));
+ }
+ | Counter32 {
+ (void)strlcpy($$.string,
+ "Counter32", sizeof($$.string));
+ }
+ | Gauge32 {
+ (void)strlcpy($$.string,
+ "Gauge32", sizeof($$.string));
+ }
+ | Unsigned32 {
+ (void)strlcpy($$.string,
+ "Unsigned32", sizeof($$.string));
+ }
+ | TimeTicks {
+ (void)strlcpy($$.string,
+ "TimeTicks", sizeof($$.string));
+ }
+ | Opaque {
+ (void)strlcpy($$.string,
+ "Opaque", sizeof($$.string));
+ }
+ | Counter64 {
+ (void)strlcpy($$.string,
+ "Counter64", sizeof($$.string));
+ }
+ | OBJECTTYPE {
+ (void)strlcpy($$.string,
+ "OBJECT-TYPE", sizeof($$.string));
+ }
| NOTIFICATIONTYPE {
- strlcpy($$, "NOTIFICATION-TYPE", sizeof($$));
+ (void)strlcpy($$.string,
+ "NOTIFICATION-TYPE", sizeof($$.string));
}
/* SNMPv2-TC */
| TEXTUALCONVENTION {
- strlcpy($$, "TEXTUAL-CONVENTION", sizeof($$));
+ (void)strlcpy($$.string,
+ "TEXTUAL-CONVENTION", sizeof($$.string));
}
/* SNMPv2-CONF */
| OBJECTGROUP {
- strlcpy($$, "OBJECT-GROUP", sizeof($$));
+ (void)strlcpy($$.string,
+ "OBJECT-GROUP", sizeof($$.string));
}
| NOTIFICATIONGROUP {
- strlcpy($$, "NOTIFICATION-GROUP", sizeof($$));
+ (void)strlcpy($$.string,
+ "NOTIFICATION-GROUP", sizeof($$.string));
}
| MODULECOMPLIANCE {
- strlcpy($$, "MODULE-COMPLIANCE", sizeof($$));
+ (void)strlcpy($$.string,
+ "MODULE-COMPLIANCE", sizeof($$.string));
}
| AGENTCAPABILITIES {
- strlcpy($$, "AGENT-CAPABILITIES", sizeof($$));
+ (void)strlcpy($$.string,
+ "AGENT-CAPABILITIES", sizeof($$.string));
}
;
descriptor : identifier {
- if (strlen($1) > DESCRIPTOR_MAX) {
- yyerror("descriptor too long");
- YYERROR;
- }
- strlcpy($$, $1, sizeof($$));
+ $$ = $1;
}
;
@@ -489,7 +534,7 @@ moduleidentity : descriptor MODULEIDENTITY lastupdate
ORGANIZATION TEXT CONTACTINFO TEXT DESCRIPTION TEXT
revisionpart PRODUCTION objectidentifiervalue {
if (mib_moduleidentity(
- $1, $3, $5, $7, $9, &$12) == -1)
+ $1.string, $3, &$5, &$7, &$9, &$12) == -1)
YYERROR;
}
;
@@ -499,23 +544,27 @@ lastupdated : LASTUPDATED TEXT {
struct tm tm = {};
size_t len;
- if ((len = strlen($2)) == 11)
+ if ((len = $2.end - $2.start) == 11)
snprintf(timebuf, sizeof(timebuf),
- "19%s", $2);
+ "19%s", $2.string);
else if (len == 13)
- strlcpy(timebuf, $2, sizeof(timebuf));
+ strlcpy(timebuf,
+ $2.string, sizeof(timebuf));
else {
- yyerror("Invalid LAST-UPDATED: %s", $2);
+ yyerror("Invalid LAST-UPDATED: %s",
+ $2.string);
YYERROR;
}
if (strptime(timebuf, "%Y%m%d%H%MZ", &tm) == NULL) {
- yyerror("Invalid LAST-UPDATED: %s", $2);
+ yyerror("Invalid LAST-UPDATED: %s",
+ $2.string);
YYERROR;
}
if (($$ = mktime(&tm)) == -1) {
- yyerror("Invalid LAST-UPDATED: %s", $2);
+ yyerror("Invalid LAST-UPDATED: %s",
+ $2.string);
YYERROR;
}
}
@@ -538,41 +587,43 @@ assignmentlist : assignment assignmentlist
assignment : descriptor OBJECT IDENTIFIER PRODUCTION
objectidentifiervalue {
- if (mib_oid($1, &$5) == NULL)
+ if (mib_oid($1.string, &$5) == NULL)
YYERROR;
}
| descriptor OBJECTIDENTITY STATUS status
DESCRIPTION TEXT referpart PRODUCTION
objectidentifiervalue {
- const char *reference;
+ const struct text *reference;
- reference = $7[0] == '\0' ? NULL : $7;
+ reference = $7.string[0] == '\0' ?
+ NULL : &$7;
- if (mib_objectidentity($1, $4, $6, reference,
- &$9) == -1)
+ if (mib_objectidentity($1.string, $4, &$6,
+ reference, &$9) == -1)
YYERROR;
}
| descriptor OBJECTTYPE SYNTAX syntax unitspart
MAXACCESS access STATUS status DESCRIPTION TEXT
referpart indexpart defvalpart PRODUCTION
objectidentifiervalue {
- const char *units, *reference;
+ const struct text *units, *reference;
- units = $5[0] == '\0' ? NULL : $5;
- reference = $12[0] == '\0' ? NULL : $12;
+ units = $5.string[0] == '\0' ? NULL : &$5;
+ reference = $12.string[0] == '\0' ? NULL : &$12;
- if (mib_objecttype($1, NULL, units, $7, $9, $11,
- reference, NULL, NULL, &$16) == -1)
+ if (mib_objecttype($1.string, NULL, units, $7,
+ $9, &$11, reference,
+ NULL, NULL, &$16) == -1)
YYERROR;
}
| descriptor NOTIFICATIONTYPE objectspart STATUS status
DESCRIPTION TEXT referpart PRODUCTION
objectidentifiervalue {
- const char *reference;
+ const struct text *reference;
- reference = $8[0] == '\0' ? NULL : $8;
+ reference = $8.string[0] == '\0' ? NULL : &$8;
- if (mib_notificationtype($1, NULL, $5, $7,
+ if (mib_notificationtype($1.string, NULL, $5, &$7,
reference, &$10) == -1)
YYERROR;
}
@@ -581,46 +632,46 @@ assignment : descriptor OBJECT IDENTIFIER PRODUCTION
}
| typereference PRODUCTION TEXTUALCONVENTION displaypart
STATUS status DESCRIPTION TEXT referpart SYNTAX syntax {
- const char *displayhint, *reference;
+ const struct text *displayhint, *reference;
- displayhint = $4[0] == '\0' ? NULL : $4;
- reference = $9[0] == '\0' ? NULL : $9;
+ displayhint = $4.string[0] == '\0' ? NULL : &$4;
+ reference = $9.string[0] == '\0' ? NULL : &$9;
- if (mib_textualconvetion($1, displayhint, $6,
- $8, reference, NULL) == -1)
+ if (mib_textualconvetion($1.string, displayhint,
+ $6, &$8, reference, NULL) == -1)
YYERROR;
}
| descriptor MODULECOMPLIANCE STATUS status
DESCRIPTION TEXT referpart compliancemodulepart
PRODUCTION objectidentifiervalue {
- const char *reference;
+ const struct text *reference;
- reference = $7[0] == '\0' ? NULL : $7;
+ reference = $7.string[0] == '\0' ? NULL : &$7;
- if (mib_modulecompliance($1, $4, $6, reference,
- NULL, &$10) == -1)
+ if (mib_modulecompliance($1.string, $4, &$6,
+ reference, NULL, &$10) == -1)
YYERROR;
}
| descriptor OBJECTGROUP objectspart STATUS status
DESCRIPTION TEXT referpart PRODUCTION
objectidentifiervalue {
- const char *reference;
+ const struct text *reference;
- reference = $8[0] == '\0' ? NULL : $8;
+ reference = $8.string[0] == '\0' ? NULL : &$8;
- if (mib_objectgroup($1, NULL, $5, $7, reference,
- &$10) == -1)
+ if (mib_objectgroup($1.string, NULL, $5, &$7,
+ reference, &$10) == -1)
YYERROR;
}
| descriptor NOTIFICATIONGROUP notificationspart
STATUS status DESCRIPTION TEXT referpart PRODUCTION
objectidentifiervalue {
- const char *reference;
+ const struct text *reference;
- reference = $8[0] == '\0' ? NULL : $8;
+ reference = $8.string[0] == '\0' ? NULL : &$8;
- if (mib_notificationgroup($1, NULL, $5, $7, reference,
- &$10) == -1)
+ if (mib_notificationgroup($1.string, NULL, $5,
+ &$7, reference, &$10) == -1)
YYERROR;
}
| typereference PRODUCTION syntax
@@ -656,18 +707,18 @@ syntax : type
;
unitspart : UNITS TEXT {
- strlcpy($$, $2, sizeof($$));
+ $$ = $2;
}
| /* empty */ {
- $$[0] = '\0';
+ $$ = (struct text){};
}
;
referpart : REFERENCE TEXT {
- strlcpy($$, $2, sizeof($$));
+ $$ = $2;
}
| /* empty */ {
- $$[0] = '\0';
+ $$ = (struct text){};
}
;
@@ -713,10 +764,10 @@ bitscomponent : identifier
;
displaypart : DISPLAYHINT TEXT {
- strlcpy($$, $2, sizeof($$));
+ $$ = $2;
}
| /* empty */ {
- $$[0] = '\0';
+ $$ = (struct text){};
}
;
@@ -838,7 +889,7 @@ objidcomponentlist : objidcomponent objidcomponentlist
objidcomponentfirst : descriptor {
$$.type = OCT_DESCRIPTOR;
- strlcpy($$.name, $1, sizeof($$.name));
+ strlcpy($$.name, $1.string, sizeof($$.name));
}
| objidcomponent {
$$.type = $1.type;
@@ -865,7 +916,7 @@ objidcomponent : NUMBER {
YYERROR;
}
$$.number = $3;
- strlcpy($$.name, $1, sizeof($$.name));
+ strlcpy($$.name, $1.string, sizeof($$.name));
}
;
@@ -933,16 +984,16 @@ value : SIGNEDNUMBER
;
access : descriptor {
- if (strcmp($1, "not-accessible") == 0)
+ if (strcmp($1.string, "not-accessible") == 0)
$$ = NOTACCESSIBLE;
- else if (
- strcmp($1, "accessible-for-notify") == 0)
+ else if (strcmp($1.string,
+ "accessible-for-notify") == 0)
$$ = ACCESSIBLEFORNOTIFY;
- else if (strcmp($1, "read-only") == 0)
+ else if (strcmp($1.string, "read-only") == 0)
$$ = READONLY;
- else if (strcmp($1, "read-write") == 0)
+ else if (strcmp($1.string, "read-write") == 0)
$$ = READWRITE;
- else if (strcmp($1, "read-create") == 0)
+ else if (strcmp($1.string, "read-create") == 0)
$$ = READCREATE;
else {
yyerror("invalid access");
@@ -952,11 +1003,11 @@ access : descriptor {
;
status : descriptor {
- if (strcmp($1, "current") == 0)
+ if (strcmp($1.string, "current") == 0)
$$ = CURRENT;
- else if (strcmp($1, "deprecated") == 0)
+ else if (strcmp($1.string, "deprecated") == 0)
$$ = DEPRECATED;
- else if (strcmp($1, "obsolete") == 0)
+ else if (strcmp($1.string, "obsolete") == 0)
$$ = OBSOLETE;
else {
yyerror("invalid status");
@@ -1106,48 +1157,60 @@ yylex(void)
{}
};
- char buf[TEXT_MAX];
+ struct text text;
+ char lookback[2] = {};
size_t i = 0, j;
- int c, comment = 0;
+ int c, comment = 0, quote = 0;
const char *errstr;
- char *endptr;
+ char *endptr, *buf;
+ int dofree;
+ (void)strlcpy(text.file, file.name, sizeof(text.file));
while ((c = fgetc(file.stream)) != EOF) {
- if (i == sizeof(buf)) {
- yyerror("token too large");
- return ERROR;
+ if (i == 0) {
+ text.start = ftello(file.stream) - 1;
+ if (c == '"' && !quote) {
+ quote = 1;
+ continue;
+ }
}
- if (i > 0 && buf[0] == '"') {
+ if (quote) {
if (c == '"') {
- buf[i] = '\0';
- (void)strlcpy(yylval.string, buf + 1,
- sizeof(yylval.string));
+ text.end = ftello(file.stream) - 1;
+ yylval.text = text;
return TEXT;
}
if (c == '\n')
file.lineno++;
- buf[i++] = c;
+ if (i < sizeof(text.string) - 1) {
+ text.string[i++] = c;
+ text.string[i] = '\0';
+ }
continue;
}
if (comment) {
if (c == '-') {
- if (++comment == 3)
+ if (++comment == 3) {
comment = 0;
+ i = 0;
+ }
} else if (c == '\n') {
file.lineno++;
comment = 0;
+ i = 0;
} else
comment = 1;
continue;
}
if (c == '\n') {
if (i != 0) {
- if (buf[i - 1] == '\r') {
+ if (text.string[i - 1] == '\r') {
i--;
if (i == 0) {
file.lineno++;
continue;
}
+ text.string[i] = '\0';
}
ungetc(c, file.stream);
goto token;
@@ -1158,15 +1221,17 @@ yylex(void)
if (c == ' ' || c == '\t') {
if (i == 0)
continue;
+ ungetc(c, file.stream);
goto token;
}
if (c == '.' || c == ':') {
- if (i > 0 && buf[0] != '.' && buf[0] != ':') {
+ if (i > 0 &&
+ text.string[0] != '.' && text.string[0] != ':') {
ungetc(c, file.stream);
goto token;
}
}
- if (i > 0 && (buf[0] == '.' || buf[0] == ':')) {
+ if (i > 0 && (text.string[0] == '.' || text.string[0] == ':')) {
if (c != '.' && c != ':' && c != '=') {
ungetc(c, file.stream);
goto token;
@@ -1179,9 +1244,18 @@ yylex(void)
ungetc(c, file.stream);
goto token;
}
- buf[i++] = c;
+ if (i < sizeof(text.string) - 1) {
+ text.string[i++] = c;
+ text.string[i] = '\0';
+ }
+ if (i < 2)
+ lookback[i] = c;
+ else {
+ lookback[0] = lookback[1];
+ lookback[1] = c;
+ }
if (i >= 2) {
- if (buf[i - 2] == '-' && buf[i - 1] == '-') {
+ if (lookback[0] == '-' && lookback[1] == '-') {
if (i > 2) {
ungetc('-', file.stream);
ungetc('-', file.stream);
@@ -1189,7 +1263,6 @@ yylex(void)
goto token;
}
comment = 1;
- i = 0;
continue;
}
}
@@ -1199,95 +1272,122 @@ yylex(void)
yyerror(NULL);
return ERROR;
}
- if (i == 0)
+ if (i == 0 || comment)
return 0;
token:
- buf[i] = '\0';
-
+ text.end = ftello(file.stream);
for (i = 0; keywords[i].name != NULL; i++) {
- if (strcmp(keywords[i].name, buf) == 0)
+ if (strcmp(keywords[i].name, text.string) == 0)
return keywords[i].token;
}
- if (isupper(buf[0])) {
- for (i = 1; buf[i] != '\0'; i++) {
- if (!isalnum(buf[i]) && buf[i] != '-')
+ if (isupper(text.string[0])) {
+ if ((size_t)(text.end - text.start) >= sizeof(text.string)) {
+ yyerror("typereference too long");
+ return ERROR;
+ }
+ for (i = 1; text.string[i] != '\0'; i++) {
+ if (!isalnum(text.string[i]) && text.string[i] != '-')
break;
}
- if (buf[i] == '\0' && buf[i - 1] != '-') {
- strlcpy(yylval.string, buf, sizeof(yylval.string));
+ if (text.string[i] == '\0' && text.string[i - 1] != '-') {
+ yylval.text = text;
return typereference;
}
}
- if (islower(buf[0])) {
- for (i = 1; buf[i] != '\0'; i++) {
- if (!isalnum(buf[i]) && buf[i] != '-')
+ if (islower(text.string[0])) {
+ if ((size_t)(text.end - text.start) >= sizeof(text.string)) {
+ yyerror("identifier too long");
+ return ERROR;
+ }
+ for (i = 1; text.string[i] != '\0'; i++) {
+ if (!isalnum(text.string[i]) && text.string[i] != '-')
break;
}
- if (buf[i] == '\0'&& buf[i - 1] != '-') {
- strlcpy(yylval.string, buf, sizeof(yylval.string));
+ if (text.string[i] == '\0' && text.string[i - 1] != '-') {
+ yylval.text = text;
return identifier;
}
}
- if (buf[0] == '\'') {
- for (i = 1; buf[i] != '\0'; i++)
- continue;
+ if (text.string[0] == '\'') {
+ i = text.end - text.start;
+ if ((buf = text_get(&text, &dofree)) == NULL) {
+ yyerror("failed to get full text: %s", strerror(errno));
+ return ERROR;
+ }
if (i < 3 || buf[i - 2] != '\'') {
yyerror("incomplete binary or hexadecimal string");
return ERROR;
}
+ buf[i - 2] = '\0';
+ strlcpy(yylval.text.file, text.file, sizeof(yylval.text.file));
+ yylval.text.start = text.start + 1;
+ yylval.text.end = text.end - 2;
+
if (tolower(buf[i - 1]) == 'b') {
for (j = 1; j < i - 2; j++) {
if (buf[j] != '0' && buf[j] != '1') {
yyerror("invalid character in bstring");
+ if (dofree)
+ free(buf);
return ERROR;
}
}
- strlcpy(yylval.string, buf + 1, sizeof(yylval.string));
- yylval.string[i - 2] = '\0';
+ strlcpy(yylval.text.string, buf + 1,
+ sizeof(yylval.text.string));
+ if (dofree)
+ free(buf);
return BSTRING;
} else if (tolower(buf[i - 1]) == 'h') {
for (j = 1; j < i - 2; j++) {
if (!isxdigit(buf[j])) {
yyerror("invalid character in hstring");
+ if (dofree)
+ free(buf);
return ERROR;
}
}
- strlcpy(yylval.string, buf + 1, sizeof(yylval.string));
- yylval.string[i - 2] = '\0';
+ strlcpy(yylval.text.string, buf + 1,
+ sizeof(yylval.text.string));
+ if (dofree)
+ free(buf);
return HSTRING;
}
yyerror("no valid binary or hexadecimal string");
+ if (dofree)
+ free(buf);
return ERROR;
}
- for (i = 0; buf[i] != '\0'; i++) {
- if (i == 0 && buf[i] == '-')
+ for (i = 0; text.string[i] != '\0'; i++) {
+ if (i == 0 && text.string[i] == '-')
continue;
- if (!isdigit(buf[i]))
+ if (!isdigit(text.string[i]))
break;
}
- if ((i == 1 && isdigit(buf[0])) || i > 1) {
+ if ((i == 1 && isdigit(text.string[0])) || i > 1) {
+ /* string length check is implicit here */
yylval.signednumber =
- strtonum(buf, LLONG_MIN, LLONG_MAX, &errstr);
+ strtonum(text.string, LLONG_MIN, LLONG_MAX, &errstr);
if (errstr != NULL) {
- if (errno == ERANGE && isdigit(buf[0])) {
+ if (errno == ERANGE && isdigit(text.string[0])) {
errno = 0;
- yylval.number = strtoull(buf, &endptr, 10);
+ yylval.number =
+ strtoull(text.string, &endptr, 10);
if (errno == 0)
return NUMBER;
}
- yyerror("invalid number: %s: %s", buf, errstr);
+ yyerror("invalid number: %s: %s", text.string, errstr);
return ERROR;
}
- if (buf[0] == '-')
+ if (text.string[0] == '-')
return SIGNEDNUMBER;
yylval.number = yylval.signednumber;
return NUMBER;
}
- yyerror("unknown token: %s", buf);
+ yyerror("unknown token: %s", text.string);
return ERROR;
}
@@ -1495,8 +1595,8 @@ mib_applicationsyntax(const char *name)
int
mib_moduleidentity(const char *name, time_t lastupdated,
- const char *organization, const char *contactinfo, const char *description,
- const struct oid_unresolved *oid)
+ const struct text *organization, const struct text *contactinfo,
+ const struct text *description, const struct oid_unresolved *oid)
{
struct item *item;
@@ -1512,7 +1612,7 @@ mib_moduleidentity(const char *name, time_t lastupdate
int
mib_objectidentity(const char *name, enum status status,
- const char *description, const char *reference,
+ const struct text *description, const struct text *reference,
const struct oid_unresolved *oid)
{
struct item *item;
@@ -1528,9 +1628,9 @@ mib_objectidentity(const char *name, enum status statu
}
int
-mib_objecttype(const char *name, void *syntax, const char *units,
- enum access maxaccess, enum status status, const char *description,
- const char *reference, void *index, void *defval,
+mib_objecttype(const char *name, void *syntax, const struct text *units,
+ enum access maxaccess, enum status status, const struct text *description,
+ const struct text *reference, void *index, void *defval,
const struct oid_unresolved *oid)
{
struct item *item;
@@ -1547,7 +1647,7 @@ mib_objecttype(const char *name, void *syntax, const c
int
mib_notificationtype(const char *name, void *objects, enum status status,
- const char *description, const char *reference,
+ const struct text *description, const struct text *reference,
const struct oid_unresolved *oid)
{
struct item *item;
@@ -1562,9 +1662,9 @@ mib_notificationtype(const char *name, void *objects,
}
int
-mib_textualconvetion(const char *name, const char *displayhint,
- enum status status, const char *description, const char *reference,
- void *syntax)
+mib_textualconvetion(const char *name, const struct text *displayhint,
+ enum status status, const struct text *description,
+ const struct text *reference, void *syntax)
{
struct item *item;
@@ -1576,7 +1676,7 @@ mib_textualconvetion(const char *name, const char *dis
int
mib_objectgroup(const char *name, void *objects, enum status status,
- const char *description, const char *reference,
+ const struct text *description, const struct text *reference,
const struct oid_unresolved *oid)
{
struct item *item;
@@ -1591,7 +1691,7 @@ mib_objectgroup(const char *name, void *objects, enum
int
mib_notificationgroup(const char *name, void *notifications, enum status status,
- const char *description, const char *reference,
+ const struct text *description, const struct text *reference,
const struct oid_unresolved *oid)
{
struct item *item;
@@ -1606,7 +1706,7 @@ mib_notificationgroup(const char *name, void *notifica
int
mib_modulecompliance(const char *name, enum status status,
- const char *description, const char *reference, void *mods,
+ const struct text *description, const struct text *reference, void *mods,
const struct oid_unresolved *oid)
{
struct item *item;
@@ -1639,6 +1739,8 @@ mib_parsefile(const char *path)
}
fclose(file.stream);
+ file.name = NULL;
+ file.stream = NULL;
}
void
@@ -1786,6 +1888,11 @@ mib_defaults(void)
{
struct oid_unresolved oid;
struct item *iso;
+ const struct text ds = {
+ .string = "255a"
+ }, x = {
+ .string = "1x:"
+ }, empty = {};
if (!RB_EMPTY(&modulesci))
return;
@@ -1924,37 +2031,37 @@ mib_defaults(void)
exit(1);
if (mib_textualconvetion(
- "DisplayString", "255a", CURRENT, "", NULL, NULL) == -1 ||
+ "DisplayString", &ds, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "PhysAddress", "1x:", CURRENT, "", NULL, NULL) == -1 ||
+ "PhysAddress", &x, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "MacAddress", "1x:", CURRENT, "", NULL, NULL) == -1 ||
+ "MacAddress", &x, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "TruthValue", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "TruthValue", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "TestAndIncr", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "TestAndIncr", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "AutonomousType", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "AutonomousType", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "InstancePointer", NULL, OBSOLETE, "", NULL, NULL) == -1 ||
+ "InstancePointer", NULL, OBSOLETE, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "VariablePointer", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "VariablePointer", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "RowPointer", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "RowPointer", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "RowStatus", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "RowStatus", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "TimeStamp", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "TimeStamp", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "TimeInterval", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "TimeInterval", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "DateAndTime", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "DateAndTime", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "StorageType", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "StorageType", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "TDomain", NULL, CURRENT, "", NULL, NULL) == -1 ||
+ "TDomain", NULL, CURRENT, &empty, NULL, NULL) == -1 ||
mib_textualconvetion(
- "TAddress", NULL, CURRENT, "", NULL, NULL) == -1)
+ "TAddress", NULL, CURRENT, &empty, NULL, NULL) == -1)
exit(1);
RB_INSERT(modulesci, &modulesci, module);
@@ -2207,6 +2314,50 @@ mib_resolve(void)
}
}
+char *
+text_get(struct text *text, int *dofree)
+{
+ off_t curoff;
+ FILE *f;
+ char *buf;
+
+ if ((size_t)(text->end - text->start) < sizeof(text->string)) {
+ *dofree = 0;
+ return text->string;
+ }
+
+ if (file.name != NULL && strcmp(file.name, text->file) == 0) {
+ curoff = ftello(file.stream);
+ f = file.stream;
+ } else {
+ curoff = -1;
+ if ((f = fopen(text->file, "r")) == NULL)
+ return NULL;
+ }
+ fseek(f, text->start, SEEK_SET);
+ if ((buf = malloc((text->end - text->start) + 1)) == NULL) {
+ if (curoff == -1)
+ fclose(f);
+ return NULL;
+ }
+ if (fread(buf, 1, (size_t)(text->end - text->start), f) !=
+ (size_t)(text->end - text->start)) {
+ if (curoff == -1)
+ fclose(f);
+ free(buf);
+ return NULL;
+ }
+ if (curoff == -1)
+ fclose(f);
+ else
+ fseeko(file.stream, curoff, SEEK_SET);
+ buf[text->end - text->start] = '\0';
+
+ *dofree = 1;
+
+ return buf;
+}
+
int
module_cmp_cs(struct module *m1, struct module *m2)
{
blob - 3882b915ebd85bcac9b41fff40c89a9a2633c88b
blob + 6ec2d878be69600647b4bcc152c63e3798408cd5
--- usr.sbin/snmpd/parse.y
+++ usr.sbin/snmpd/parse.y
@@ -37,6 +37,7 @@
#include <openssl/sha.h>
+#include <stddef.h>
#include <ber.h>
#include <ctype.h>
#include <err.h>
@@ -48,7 +49,9 @@
#include <pwd.h>
#include <stdarg.h>
#include <stdint.h>
+#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <strings.h>
#include <syslog.h>
#include <unistd.h>
snmpd: allow arbitrary string length in mib.y