Re: svn commit: r1850651 - /subversion/trunk/subversion/mod_dav_svn/repos.c

2019-08-15 Thread Stefan Sperling
On Thu, Aug 15, 2019 at 09:36:48PM +0300, Sergey Raevskiy wrote:
> Hi!
> 
> I've attached a patch with fix. Log message:
> [[[
> * subversion/mod_dav_svn/repos.c
>   (get_resource): Following up on r1850651: Set cleanup handler for
>FS warning logging regardless of presence of R->USER.
> 
> Patch by: sergey.raevskiy{_AT_}visualsvn.com
> ]]]

Thank you Sergey!

I can confirm FSFS/serf tests still pass with this patch on an OpenBSD
System. Which means the original use-after-free issue remains fixed.

Committed in r1865266.

Regards,
Stefan


Re: svn commit: r1850651 - /subversion/trunk/subversion/mod_dav_svn/repos.c

2019-08-15 Thread Sergey Raevskiy
Hi!

I've attached a patch with fix. Log message:
[[[
* subversion/mod_dav_svn/repos.c
  (get_resource): Following up on r1850651: Set cleanup handler for
   FS warning logging regardless of presence of R->USER.

Patch by: sergey.raevskiy{_AT_}visualsvn.com
]]]

On Thu, Aug 15, 2019 at 8:25 PM Stefan Sperling  wrote:
>
> On Thu, Aug 15, 2019 at 08:14:43PM +0300, Sergey Raevskiy wrote:
> > >   /* if an authenticated username is present, attach it to the FS */
> > >if (r->user)
> > > @@ -2503,6 +2529,14 @@ get_resource(request_rec *r,
> > >apr_pool_cleanup_register(r->pool, cleanup_baton, 
> > > cleanup_fs_access,
> > >  apr_pool_cleanup_null);
> > >
> > > +  /* We must degrade the logging context when the request is freed. 
> > > */
> > > +  cleanup_req_logging_baton =
> > > +apr_pcalloc(r->pool, sizeof(*cleanup_req_logging_baton));
> > > +  cleanup_req_logging_baton->fs = repos->fs;
> > > +  cleanup_req_logging_baton->connection = r->connection;
> > > +  apr_pool_pre_cleanup_register(r->pool, cleanup_req_logging_baton,
> > > +cleanup_req_logging);
> >
> > Is it intended to set-up this cleanup handler only if R->USER is specified?
>
> Thanks Sergey!
>
> Good question. Looking back at this patch, this looks like an accident.
>
> Were you planning on writing a fix?
* subversion/mod_dav_svn/repos.c
  (get_resource): Following up on r1850651: Set cleanup handler for
   FS warning logging regardless of presence of R->USER.

Patch by: sergey.raevskiy{_AT_}visualsvn.com

Index: subversion/mod_dav_svn/repos.c
===
--- subversion/mod_dav_svn/repos.c  (revision 1865250)
+++ subversion/mod_dav_svn/repos.c  (working copy)
@@ -2514,6 +2514,14 @@ get_resource(request_rec *r,
   /* capture warnings during cleanup of the FS */
   svn_fs_set_warning_func(repos->fs, log_warning_req, r);
 
+  /* We must degrade the logging context when the request is freed. */
+  cleanup_req_logging_baton =
+apr_pcalloc(r->pool, sizeof(*cleanup_req_logging_baton));
+  cleanup_req_logging_baton->fs = repos->fs;
+  cleanup_req_logging_baton->connection = r->connection;
+  apr_pool_pre_cleanup_register(r->pool, cleanup_req_logging_baton,
+cleanup_req_logging);
+
   /* if an authenticated username is present, attach it to the FS */
   if (r->user)
 {
@@ -2529,14 +2537,6 @@ get_resource(request_rec *r,
   apr_pool_cleanup_register(r->pool, cleanup_baton, cleanup_fs_access,
 apr_pool_cleanup_null);
 
-  /* We must degrade the logging context when the request is freed. */
-  cleanup_req_logging_baton =
-apr_pcalloc(r->pool, sizeof(*cleanup_req_logging_baton));
-  cleanup_req_logging_baton->fs = repos->fs;
-  cleanup_req_logging_baton->connection = r->connection;
-  apr_pool_pre_cleanup_register(r->pool, cleanup_req_logging_baton,
-cleanup_req_logging);
-
   /* Create an access context based on the authenticated username. */
   serr = svn_fs_create_access(&access_ctx, r->user, r->pool);
   if (serr)


Re: svn commit: r1850651 - /subversion/trunk/subversion/mod_dav_svn/repos.c

2019-08-15 Thread Stefan Sperling
On Thu, Aug 15, 2019 at 08:14:43PM +0300, Sergey Raevskiy wrote:
> >   /* if an authenticated username is present, attach it to the FS */
> >if (r->user)
> > @@ -2503,6 +2529,14 @@ get_resource(request_rec *r,
> >apr_pool_cleanup_register(r->pool, cleanup_baton, cleanup_fs_access,
> >  apr_pool_cleanup_null);
> >
> > +  /* We must degrade the logging context when the request is freed. */
> > +  cleanup_req_logging_baton =
> > +apr_pcalloc(r->pool, sizeof(*cleanup_req_logging_baton));
> > +  cleanup_req_logging_baton->fs = repos->fs;
> > +  cleanup_req_logging_baton->connection = r->connection;
> > +  apr_pool_pre_cleanup_register(r->pool, cleanup_req_logging_baton,
> > +cleanup_req_logging);
> 
> Is it intended to set-up this cleanup handler only if R->USER is specified?

Thanks Sergey!

Good question. Looking back at this patch, this looks like an accident.

Were you planning on writing a fix?


Re: svn commit: r1850651 - /subversion/trunk/subversion/mod_dav_svn/repos.c

2019-08-15 Thread Sergey Raevskiy
>   /* if an authenticated username is present, attach it to the FS */
>if (r->user)
> @@ -2503,6 +2529,14 @@ get_resource(request_rec *r,
>apr_pool_cleanup_register(r->pool, cleanup_baton, cleanup_fs_access,
>  apr_pool_cleanup_null);
>
> +  /* We must degrade the logging context when the request is freed. */
> +  cleanup_req_logging_baton =
> +apr_pcalloc(r->pool, sizeof(*cleanup_req_logging_baton));
> +  cleanup_req_logging_baton->fs = repos->fs;
> +  cleanup_req_logging_baton->connection = r->connection;
> +  apr_pool_pre_cleanup_register(r->pool, cleanup_req_logging_baton,
> +cleanup_req_logging);

Is it intended to set-up this cleanup handler only if R->USER is specified?

On Mon, Jan 7, 2019 at 6:04 PM  wrote:
>
> Author: stsp
> Date: Mon Jan  7 15:04:15 2019
> New Revision: 1850651
>
> URL: http://svn.apache.org/viewvc?rev=1850651&view=rev
> Log:
> Fix a use-after-free in mod_dav_svn's logging of FS warnings.
>
> The FS warning callback could be called with a request context that had
> already been deallocated. This resulted in a crash during 'make check'
> with ra_serf on OpenBSD. The problem was even documented in a comment:
>
>   /* ### hmm. the FS is cleaned up at request cleanup time. "r" might
>  ### not really be valid. we should probably put the FS into a
>  ### subpool to ensure it gets cleaned before the request.
>  ### is there a good way to create and use a subpool for all
>  ### of our functions ... ??
>   */
>
> Rather than putting the FS into a subpool, the solution implemented with this
> commit installs a pre-cleanup handler on the request pool, which switches the
> logging context from the request to its associated connection. This avoids the
> use-after-free at the cost of a less precise logging context.
>
> Suggested by: stefan2
> https://svn.haxx.se/dev/archive-2018-12/0145.shtml
>
> * subversion/mod_dav_svn/repos.c
>   (log_warning): Rename to ...
>   (log_warning_req): ... this.
>   (log_warning_conn): New logging helper which uses a connection context.
>   (cleanup_req_logging_baton, cleanup_req_logging): New APR pool cleanup
>handler which switches FS logging context from a request to a connection.
>   (get_resource): Install aforementioned pool cleanup handler.
>
> Modified:
> subversion/trunk/subversion/mod_dav_svn/repos.c
>
> Modified: subversion/trunk/subversion/mod_dav_svn/repos.c
> URL: 
> http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/repos.c?rev=1850651&r1=1850650&r2=1850651&view=diff
> ==
> --- subversion/trunk/subversion/mod_dav_svn/repos.c (original)
> +++ subversion/trunk/subversion/mod_dav_svn/repos.c Mon Jan  7 15:04:15 2019
> @@ -1225,25 +1225,32 @@ create_private_resource(const dav_resour
>return &comb->res;
>  }
>
> -
> -static void log_warning(void *baton, svn_error_t *err)
> +static void log_warning_req(void *baton, svn_error_t *err)
>  {
>request_rec *r = baton;
>const char *continuation = "";
>
> -  /* ### hmm. the FS is cleaned up at request cleanup time. "r" might
> - ### not really be valid. we should probably put the FS into a
> - ### subpool to ensure it gets cleaned before the request.
> +  /* Not showing file/line so no point in tracing */
> +  err = svn_error_purge_tracing(err);
> +  while (err)
> +{
> +  ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, "%s%s",
> +continuation, err->message);
> +  continuation = "-";
> +  err = err->child;
> +}
> +}
>
> - ### is there a good way to create and use a subpool for all
> - ### of our functions ... ??
> -  */
> +static void log_warning_conn(void *baton, svn_error_t *err)
> +{
> +  conn_rec *c = baton;
> +  const char *continuation = "";
>
>/* Not showing file/line so no point in tracing */
>err = svn_error_purge_tracing(err);
>while (err)
>  {
> -  ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, "%s%s",
> +  ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c, "%s%s",
>  continuation, err->message);
>continuation = "-";
>err = err->child;
> @@ -1547,6 +1554,24 @@ cleanup_fs_access(void *data)
>return APR_SUCCESS;
>  }
>
> +/* Context for cleanup handler. */
> +struct cleanup_req_logging_baton
> +{
> +  svn_fs_t *fs;
> +  conn_rec *connection;
> +};
> +
> +static apr_status_t
> +cleanup_req_logging(void *data)
> +{
> +  struct cleanup_req_logging_baton *baton = data;
> +
> +  /* The request about to be freed. Log future warnings with a connection
> +   * context instead of a request context. */
> +  svn_fs_set_warning_func(baton->fs, log_warning_conn, baton->connection);
> +
> +  return APR_SUCCESS;
> +}
>
>  /* Helper func to construct a special 'parentpath' private resource. */
>  static dav_error *
> @@ -2180,6 +2205,7 @@ get_resour