src/share/classes/com/sun/jndi/dns/ResourceRecord.java
Print this page
rev 9296 : Detect compression loops in the JNDI DNS client
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -82,10 +82,15 @@
*/
static final String rrClassNames[] = {
null, "IN", null, null, "HS"
};
+ /*
+ * Maximum number of compression references in labels.
+ * Used to detect compression loops.
+ */
+ private static final int MAXIMUM_COMPRESSION_REFERENCES = 16;
byte[] msg; // DNS message
int msgLen; // msg size (in octets)
boolean qSection; // true if this RR is part of question section
// and therefore has no ttl or rdata
@@ -237,11 +242,11 @@
*/
private void decode(boolean decodeRdata) throws InvalidNameException {
int pos = offset; // index of next unread octet
name = new DnsName(); // NAME
- pos = decodeName(pos, name);
+ pos = decodeName(pos, name, 0);
rrtype = getUShort(pos); // TYPE
rrtypeName = (rrtype < rrTypeNames.length)
? rrTypeNames[rrtype]
: null;
@@ -316,33 +321,37 @@
/*
* Returns the name encoded at msg[pos], including the root label.
*/
private DnsName decodeName(int pos) throws InvalidNameException {
DnsName n = new DnsName();
- decodeName(pos, n);
+ decodeName(pos, n, 0);
return n;
}
/*
* Prepends to "n" the domain name encoded at msg[pos], including the root
* label. Returns the index into "msg" following the name.
*/
- private int decodeName(int pos, DnsName n) throws InvalidNameException {
+ private int decodeName(int pos, DnsName n, int level)
+ throws InvalidNameException {
+ if (level > MAXIMUM_COMPRESSION_REFERENCES) {
+ throw new InvalidNameException("Too many compression references");
+ }
if (msg[pos] == 0) { // end of name
n.add(0, "");
return (pos + 1);
} else if ((msg[pos] & 0xC0) != 0) { // name compression
- decodeName(getUShort(pos) & 0x3FFF, n);
+ decodeName(getUShort(pos) & 0x3FFF, n, level + 1);
return (pos + 2);
} else { // append a label
int len = msg[pos++];
try {
n.add(0, new String(msg, pos, len, "ISO-8859-1"));
} catch (java.io.UnsupportedEncodingException e) {
// assert false : "ISO-Latin-1 charset unavailable";
}
- return decodeName(pos + len, n);
+ return decodeName(pos + len, n, level);
}
}
/*
* Returns the rdata encoded at msg[pos]. The format is dependent
@@ -396,13 +405,13 @@
/*
* Returns the rdata of an SOA record that is encoded at msg[pos].
*/
private String decodeSoa(int pos) throws InvalidNameException {
DnsName mname = new DnsName();
- pos = decodeName(pos, mname);
+ pos = decodeName(pos, mname, 0);
DnsName rname = new DnsName();
- pos = decodeName(pos, rname);
+ pos = decodeName(pos, rname, 0);
long serial = getUInt(pos);
pos += 4;
long refresh = getUInt(pos);
pos += 4;