Git Product home page Git Product logo

Comments (4)

airween avatar airween commented on June 15, 2024

Hi @rkrishn7,

could you share your (minimal) config (at least to emulate this behavior)? And I assume you have your own application, so a minimal code example also would be fine.

from modsecurity.

rkrishn7 avatar rkrishn7 commented on June 15, 2024

Hey @airween,

Sure, I was able to create a minimal reproducible example in C (using libmodsecurity v3.0.12):

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <modsecurity/modsecurity.h>
#include <modsecurity/rules_set.h>

void *create_rules(void *arg)
{
    const char *plain_rules = arg;

    const char *err = NULL;

    RulesSet *rules;

    rules = msc_create_rules_set();
    if (rules == NULL)
    {
        return NULL;
    }

    int retval = msc_rules_add(rules, plain_rules, &err);

    if (retval < 0)
    {
        fprintf(stderr, "Error - msc_rules_add(): %s\n", err);
        exit(EXIT_FAILURE);
    }

    return NULL;
}

int main()
{
    pthread_t thread1, thread2;
    int iret1, iret2;

    const char *plain_rules_1 = "SecRuleEngine On\n";
    const char *plain_rules_2 = "SecRuleEngine On\n";

    iret1 = pthread_create(&thread1, NULL, create_rules, (void *)plain_rules_2);
    if (iret1)
    {
        fprintf(stderr, "Error - pthread_create() return code: %d\n", iret1);
        exit(EXIT_FAILURE);
    }

    iret2 = pthread_create(&thread2, NULL, create_rules, (void *)plain_rules_1);
    if (iret2)
    {
        fprintf(stderr, "Error - pthread_create() return code: %d\n", iret2);
        exit(EXIT_FAILURE);
    }

    // Wait till threads are complete before main continues.
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    return 0;
}

which yields the following output (of course the boundary errors are sporadic):

Error - msc_rules_add(): Rules error. File: <<reference missing or not informed>>. Line: 1. Column: 17. Invalid input:  
fish: Job 1, './test' terminated by signal SIGSEGV (Address boundary error)

from modsecurity.

airween avatar airween commented on June 15, 2024

Hi @rkrishn7,

thanks for the example.

Perhaps you already know that libmodsecurity3 uses Bison as configuration parser (lexer and parser are in the source tree).

Unfortunately Bison generates a non-reetrant parser, therefore you can't use that in multi-threading environment in this state. As you can see there is a (theoretical?) solution, but parser is one of the most sensitive part of the library, so I wouldn't touch it.

But you can try to use mutex locks - eg. this worked for me (based on your given example above):

pthread_mutex_t lock;

void *create_rules(void *arg)
{
    const char *plain_rules = arg;

    const char *err = NULL;

    RulesSet *rules;

    rules = msc_create_rules_set();
    if (rules == NULL)
    {
        return NULL;
    }

    pthread_mutex_lock(&lock);
    int retval = msc_rules_add(rules, plain_rules, &err);
    pthread_mutex_unlock(&lock);

    if (retval < 0)
    {
        fprintf(stderr, "Error - msc_rules_add(): %s\n", err);
        exit(EXIT_FAILURE);
    }
    else {
        fprintf(stdout, "Done - msc_rules_add(): %s\n", err);
    }

    return NULL;
}

from modsecurity.

rkrishn7 avatar rkrishn7 commented on June 15, 2024

Ah thank you @airween for the context. Yes, I thought it was related to parsing per the backtrace.

In regards to serializing parsing via a Mutex - definitely agreed. I landed on this approach for my rust crate that provides an interface to libmodsecurity. See: https://github.com/rkrishn7/rust-modsecurity/blob/55cb5e65df0c7771f74524f7e4144046cb0d323b/src/rules.rs#L20

However, it is probably worth mentioning the thread-safety of certain APIs (e.g. ModSecurity and RulesSet) in the documentation somewhere.

from modsecurity.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.