*/
CK_DLL_EXP void CK_EXPORT check_waitpid_and_exit(pid_t pid) CK_ATTRIBUTE_NORETURN;
+/**
+ * Set the maximal assertion message size.
+ *
+ * This protects the code against unintentional extremely large assertion messages
+ * (values of up to 4GB were seen in the wild).
+ * The usual size for a message is less than 80 bytes.
+ *
+ * By default, an assertion message is restricted to 4K bytes.
+ * It is possible to override this by setting the CK_MAX_MSG_SIZE environment variable,
+ * or by invoking this function.
+ * Specifying a non-positive argument resets the value,
+ * to the value specified by the environment variable,
+ * or to the default 4K bytes if the environment variable is not specified.
+ *
+ * @param max_msg_size the maximal assertion message size.
+ *
+ * @since 0.12.0
+ */
+CK_DLL_EXP void CK_EXPORT check_set_max_msg_size(int max_msg_size);
+
#ifdef __cplusplus
CK_CPPEND
#endif
#endif
/* Maximum size for one message in the message stream. */
-#define CK_MAX_MSG_SIZE 8192
+static int ck_max_msg_size = 0;
/* This is used to implement a sliding window on the receiving
* side. When sending messages, we assure that no single message
- * is bigger than this (actually we check against CK_MAX_MSG_SIZE/2).
+ * is bigger than this.
* The usual size for a message is less than 80 bytes.
* All this is done instead of the previous approach to allocate (actually
* continuously reallocate) one big chunk for the whole message stream.
* Problems were seen in the wild with up to 4 GB reallocations.
*/
+void check_set_max_msg_size(int max_msg_size) {
+ ck_max_msg_size = max_msg_size;
+}
+
+static int get_max_msg_size(void) {
+ if (ck_max_msg_size <= 0) {
+ char *env = getenv("CK_MAX_MSG_SIZE");
+ if (env)
+ ck_max_msg_size = atoi(env);
+
+ if (ck_max_msg_size <= 0)
+ ck_max_msg_size = 4096;
+ }
+ return ck_max_msg_size;
+}
+
+
/* typedef an unsigned int that has at least 4 bytes */
typedef uint32_t ck_uint32;
n = pack(type, &buf, msg);
/* Keep it on the safe side to not send too much data. */
- if(n > (CK_MAX_MSG_SIZE / 2))
+ if(n > get_max_msg_size())
eprintf("Message string too long", __FILE__, __LINE__ - 2);
pthread_cleanup_push(ppack_cleanup, &ck_mutex_lock);
rmsg = rcvmsg_create();
/* Allcate a buffer */
- buf = (char *)emalloc(CK_MAX_MSG_SIZE);
+ buf = (char *)emalloc(get_max_msg_size() * 2);
/* Fill the buffer from the file */
- nread = read_buf(fdes, CK_MAX_MSG_SIZE, buf);
+ nread = read_buf(fdes, get_max_msg_size() * 2, buf);
nparse = nread;
/* While not all parsed */
while(nparse > 0)