perl_access hash value length limit?

Julien ÉLIE julien at trigofacile.com
Sat Jan 22 20:00:49 UTC 2011


Hi David,

> I think I've found a bug in INN 2.5.2 with the readers.conf perl_access
> access() returned hash value length.  I added a bunch of newsgroups
> today that pushed the character count in the 'read' key's value from
> 6456 characters to 8238 characters.  With a 'read' string that long, INN
> didn't work anymore for incoming connections.  Syslog reported the error
> "syntax error in (null)(2), Expected value." and terminated the
> connection.

Here is a patch to improve the logging.
It will now log:

Jan 22 20:30:32 news nnrpd[2856]: stdin syntax error in perl_access-block(2), Expected value.

--- nnrpd/perm.c	(révision 9112)
+++ nnrpd/perm.c	(copie de travail)
@@ -1066,6 +1066,7 @@
     SetDefaultAccess(acc);
     str = xstrdup(name);
     acc->name = str;
+    file->filename = str;
 
     for (i = 0; i <= access_vec->count; i++) {
       tok = CONFgettoken(PERMtoks, file);
@@ -1074,6 +1075,9 @@
         accessdecl_parse(acc, file, tok);
       }
     }
+
+    /* No need to free str here; it is used by acc, and will be
+     * free'd when the access block is free'd. */
     free(file);
     return;
 }
@@ -1605,7 +1609,7 @@
 
         access_realms[0] = xcalloc(1, sizeof(ACCESSGROUP));
 
-        PERMvectortoaccess(access_realms[0], "perl-dynamic", access_vec);
+        PERMvectortoaccess(access_realms[0], "perl_access-block", access_vec);
 
         vector_free(access_vec);
       } else {
@@ -1640,7 +1644,7 @@
             access_realms[0] = xcalloc(1, sizeof(ACCESSGROUP));
             memset(access_realms[0], 0, sizeof(ACCESSGROUP));
 
-            PERMvectortoaccess(access_realms[0], "python-dynamic", access_vec);
+            PERMvectortoaccess(access_realms[0], "python_access-block", access_vec);
 
             vector_free(access_vec);
         } else {






> I don't think perl cares, or that we've hit a limit in perl, since a
> small test perl script that calls the same perl_access library and
> simply prints out the resulting hash showed the thing in entirity
> (that's how I was able to see the character counts).  I'm hoping it's
> something simple like a buffer limit being hit in INN.

Yes, exactly.  See Florian's answer about it.




> Backstory: We've been using INN for years to support internal newsgroups
> for CS course discussions.  18 months ago we started naming the groups
> per-semester (for more granular access control and versioning), but that
> means each term we add 100 or so newsgroups.  Either wildmats didn't
> work in the perl_access hash at one time, or we decided not to use them
> but each newsgroup is enumerated individually in the read and post hash
> values.  FWIW, I was able to squeeze all of this semester's groups in by
> just putting a comma inbetween groups (I had comma-space before) and my
> current length is 7803.  That'll get me through the start of the
> semester, but I'll need a solution by summer.

As Florian and Russ suggested, the right fix is to change the parser.
I do not think it will be done before this summer!

So the best thing to do right now for you would be to increase the length
of the buffer *only* for the config parser.
Here is a quick-and-dirty hack to do that.
BIG_BUFFER*10 = 81920 bytes
Adjust according to your needs.

This patch works.  I have tested it.


--- lib/conffile.c	(révision 9112)
+++ lib/conffile.c	(copie de travail)
@@ -47,7 +47,7 @@
   if (!F->buf || !F->buf[0]) {
     if (cfeof (F)) return (NULL);
     if (!F->buf) {
-      F->sbuf = BIG_BUFFER;
+      F->sbuf = BIG_BUFFER*10;
       F->buf = xmalloc(F->sbuf);
     }
     if (getconfline(F, F->buf, F->sbuf) != 0)





--- nnrpd/perl.c	(r?vision 9112)
+++ nnrpd/perl.c	(copie de travail)
@@ -264,7 +264,7 @@
 
     vector_resize(access_vec, (rc / 2));
 
-    buffer = xmalloc(BIG_BUFFER);
+    buffer = xmalloc(BIG_BUFFER*10);
 
     for (i = (rc / 2); i >= 1; i--) {
         sv = POPs;
@@ -272,10 +272,10 @@
         sv = POPs;
         key = SvPV(sv, PL_na);
 
-        strlcpy(buffer, key, BIG_BUFFER);
-        strlcat(buffer, ": \"", BIG_BUFFER);
-        strlcat(buffer, val, BIG_BUFFER);
-        strlcat(buffer, "\"\n", BIG_BUFFER);
+        strlcpy(buffer, key, BIG_BUFFER*10);
+        strlcat(buffer, ": \"", BIG_BUFFER*10);
+        strlcat(buffer, val, BIG_BUFFER*10);
+        strlcat(buffer, "\"\n", BIG_BUFFER*10);
  
         vector_add(access_vec, buffer);
     }




--- nnrpd/python.c	(r?vision 9147)
+++ nnrpd/python.c	(copie de travail)
@@ -327,7 +327,7 @@
 
     /* Store dict values in proper format in access vector. */
     pos = 0;
-    buffer = xmalloc(BIG_BUFFER);
+    buffer = xmalloc(BIG_BUFFER*10);
 
     while(PyDict_Next(result, &pos, &key, &value)) {
         if (!PyString_Check(key)) {
@@ -341,10 +341,10 @@
             ExitWithStats(1, false);
         }
         
-        strlcpy(buffer, PyString_AsString(key), BIG_BUFFER);
-        strlcat(buffer, ": \"", BIG_BUFFER);
-        strlcat(buffer, PyString_AsString(value), BIG_BUFFER);
-        strlcat(buffer, "\"\n", BIG_BUFFER);
+        strlcpy(buffer, PyString_AsString(key), BIG_BUFFER*10);
+        strlcat(buffer, ": \"", BIG_BUFFER*10);
+        strlcat(buffer, PyString_AsString(value), BIG_BUFFER*10);
+        strlcat(buffer, "\"\n", BIG_BUFFER*10);
 
         vector_add(access_vec, buffer);
     }




Would this fix be OK for you?  No problem to patch these relevant
files on your news server?

Do not hesitate to ask in case you encounter any problem to patch.

Have a nice week-end,

-- 
Julien ÉLIE

« – Avez-vous été attaqués par une force supérieure en nombre ?
  – Supérieure en nombre…
  – …On ne peut pas dire !
  – …Ils étaient un…
  – …Et pas bien gros avec ça ! » (Astérix)



More information about the inn-workers mailing list