Yesterday I applied a patch that fixed incorrect restriction checking on
CIDR data. Our old code didn't check the last byte for non-zero values
so '1.1.1.1/25'::cidr would be accepted but '1.1.1.1/24'::cidr would
not. Both should be rejected as cidr types, though they are OK for
inet.
The new problem Andrew Dunstan discovered is that because cidr and inet
are marked as implicitly casted in pg_cast, you can bypass the cidr
restriction by casting from inet to cidr then inserting into a cidr
column:test=# SELECT '1.1.1.1/3'::inet::cidr; cidr------------ 1.1.1.1/3
Basically the string comes in as inet, checks OK, then gets cast to cidr
with no additional checks. You can insert invalid values into a table
using this method:
test=> CREATE TABLE test (x cidr);CREATE TABLEtest=> INSERT INTO test VALUES ('1.1.1.1/3');ERROR: invalid cidr value:
"1.1.1.1/3"DETAIL: Value has bits set to right of mask.test=> INSERT INTO test VALUES ('1.1.1.1/3'::inet);INSERT 17239
1test=#SELECT * FROM test; x----------- 1.1.1.1/3(1 row)
So now we have a cidr value in a column that is invalid:test=# SELECT '1.1.1.1/3'::cidr;ERROR: invalid cidr value:
"1.1.1.1/3"DETAIL: Value has bits set to right of mask.
Not sure how we can fix this without modifying the system tables. Not
sure how serious this is since we have gotten few complaints about it
but clearly it should be fixed.
-- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610)
359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square,
Pennsylvania19073