You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Joe Orton <jo...@redhat.com> on 2020/02/14 09:08:14 UTC
[PATCH] event idle_spawn_rate initialization?
I've been playing with UBSan[1] which catches undefined behaviour, found a
couple of interesting things so far.
One is with event, I messed with the line numbers but the error is:
event.c:3620:13: runtime error: null pointer passed as argument 2, which is declared to never be null
from the memcpy() in this code:
https://github.com/apache/httpd/blob/trunk/server/mpm/event/event.c#L3619
new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
memcpy(new_ptr, retained->idle_spawn_rate,
retained->mpm->num_buckets * sizeof(int));
retained->idle_spawn_rate = new_ptr;
retained->mpm->max_buckets = new_max;
At startup it seems retained->idle_spawn_rate is NULL, and you can't
(shouldn't?!) memcpy() from NULL. I am not sure what the right fix is
here, is that array supposed to be initialized to something other than
zero here, or somewhere else? Not obvious if the loop below will
initialize it properly:
https://github.com/apache/httpd/blob/trunk/server/mpm/event/event.c#L3624
Is something like this correct? (also this could use apr_pmemdup rather
than palloc+memcpy now I think about it)
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -3615,9 +3615,15 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
if (new_max < num_buckets) {
new_max = num_buckets;
}
- new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
- memcpy(new_ptr, retained->idle_spawn_rate,
- retained->mpm->num_buckets * sizeof(int));
+ if (retained->idle_spawn_rate) {
+ new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
+ memcpy(new_ptr, retained->idle_spawn_rate,
+ retained->mpm->num_buckets * sizeof(int));
+ }
+ else {
+ /* ### should initialize array to something other than 0?? */
+ new_ptr = apr_pcalloc(ap_pglobal, new_max * sizeof(int));
+ }
retained->idle_spawn_rate = new_ptr;
retained->mpm->max_buckets = new_max;
}
[1] https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
Re: [PATCH] event idle_spawn_rate initialization?
Posted by Joe Orton <jo...@redhat.com>.
On Fri, Feb 14, 2020 at 11:33:50AM +0100, Ruediger Pluem wrote:
> On 02/14/2020 10:08 AM, Joe Orton wrote:
> > I've been playing with UBSan[1] which catches undefined behaviour, found a
> > couple of interesting things so far.
> >
> > One is with event, I messed with the line numbers but the error is:
> >
> > event.c:3620:13: runtime error: null pointer passed as argument 2, which is declared to never be null
> >
> > from the memcpy() in this code:
> > https://github.com/apache/httpd/blob/trunk/server/mpm/event/event.c#L3619
> >
> > new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
> > memcpy(new_ptr, retained->idle_spawn_rate,
> > retained->mpm->num_buckets * sizeof(int));
>
> I guess the above only does not crash because retained->mpm->num_buckets is 0 at the same time.
> But this is probably something we should not rely on with all memcpy implementations.
Ahhhh, yes, that makes more sense now. Thanks a lot.
...
> I guess there is no need for two cases here. We should only avoid the call to memcpy
> if retained->idle_spawn_rate is NULL. The initialization happens then in the block starting
> at line 3624.
Gotcha. Done in r1874011.
Regards, Joe
Re: [PATCH] event idle_spawn_rate initialization?
Posted by Ruediger Pluem <rp...@apache.org>.
On 02/14/2020 10:08 AM, Joe Orton wrote:
> I've been playing with UBSan[1] which catches undefined behaviour, found a
> couple of interesting things so far.
>
> One is with event, I messed with the line numbers but the error is:
>
> event.c:3620:13: runtime error: null pointer passed as argument 2, which is declared to never be null
>
> from the memcpy() in this code:
> https://github.com/apache/httpd/blob/trunk/server/mpm/event/event.c#L3619
>
> new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
> memcpy(new_ptr, retained->idle_spawn_rate,
> retained->mpm->num_buckets * sizeof(int));
I guess the above only does not crash because retained->mpm->num_buckets is 0 at the same time.
But this is probably something we should not rely on with all memcpy implementations.
> retained->idle_spawn_rate = new_ptr;
> retained->mpm->max_buckets = new_max;
>
> At startup it seems retained->idle_spawn_rate is NULL, and you can't
> (shouldn't?!) memcpy() from NULL. I am not sure what the right fix is
> here, is that array supposed to be initialized to something other than
> zero here, or somewhere else? Not obvious if the loop below will
> initialize it properly:
I think stuff is correctly initialized in the block starting at line 3624.
>
> https://github.com/apache/httpd/blob/trunk/server/mpm/event/event.c#L3624
>
> Is something like this correct? (also this could use apr_pmemdup rather
> than palloc+memcpy now I think about it)
>
> --- a/server/mpm/event/event.c
> +++ b/server/mpm/event/event.c
> @@ -3615,9 +3615,15 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
> if (new_max < num_buckets) {
> new_max = num_buckets;
> }
> - new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
> - memcpy(new_ptr, retained->idle_spawn_rate,
> - retained->mpm->num_buckets * sizeof(int));
> + if (retained->idle_spawn_rate) {
> + new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
> + memcpy(new_ptr, retained->idle_spawn_rate,
> + retained->mpm->num_buckets * sizeof(int));
> + }
> + else {
> + /* ### should initialize array to something other than 0?? */
> + new_ptr = apr_pcalloc(ap_pglobal, new_max * sizeof(int));
> + }
I guess there is no need for two cases here. We should only avoid the call to memcpy
if retained->idle_spawn_rate is NULL. The initialization happens then in the block starting
at line 3624.
Regards
RĂ¼diger