Bug 179807 - devel/subversion: segfault when running up on a symlink
Summary: devel/subversion: segfault when running up on a symlink
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Lev A. Serebryakov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-06-21 11:40 UTC by vsjcfm
Modified: 2013-07-13 16:40 UTC (History)
0 users

See Also:


Attachments
patch.txt (5.75 KB, text/plain; charset=US-ASCII)
2013-06-25 08:18 UTC, vsjcfm
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description vsjcfm 2013-06-21 11:40:00 UTC
Subversion 1.8 will segfault when running "up" command on a symlink that points to repository. Previous versions (1.7, 1.6) worked fine.

How-To-Repeat: root@jw:/tmp# llh | grep svn
root@jw:/tmp# mkdir svn
root@jw:/tmp# svn co -q svn://svn.freebsd.org/base/releng/9.1/ svn/
root@jw:/tmp# svn up svn/
Updating 'svn':
At revision 252055.
root@jw:/tmp# ln -s svn svn2
root@jw:/tmp# llh | grep svn
drwxr-xr-x  23 root   wheel   1,2k 21 иÑн 13:16 svn
lrwxr-xr-x   1 root   wheel     3B 21 иÑн 13:18 svn2 -> svn
root@jw:/tmp# svn up svn2/
Updating 'svn2':
Segmentation fault (core dumped)
root@jw:/tmp# pkg_info | egrep "^subversion"
subversion-1.8.0_1  Version control system
root@jw:/tmp# pkg_info -r subversion-1.8.0_1
Information for subversion-1.8.0_1:

Depends on:
Dependency: expat-2.0.1_2
Dependency: icu-50.1.2
Dependency: sqlite3-3.7.17_1
Dependency: libiconv-1.14_1
Dependency: gettext-0.18.1.1_1
Dependency: apr-1.4.6.1.4.1_3
Dependency: serf-1.2.1

root@jw:/tmp# cat /var/db/ports/subversion/options 
# This file is auto-generated by 'make config'.
# Options for subversion-1.8.0_1
_OPTIONS_READ=subversion-1.8.0_1
_FILE_COMPLETE_OPTIONS_LIST=BDB BOOK FREEBSD_TEMPLATE GNOME_KEYRING KDE_KWALLET MAINTAINER_DEBUG MOD_DAV_SVN P4_STYLE_MARKERS SASL SERF STATIC SVNSERVE_WRAPPER TEST TOOLS
OPTIONS_FILE_UNSET+=BDB
OPTIONS_FILE_UNSET+=BOOK
OPTIONS_FILE_SET+=FREEBSD_TEMPLATE
OPTIONS_FILE_UNSET+=GNOME_KEYRING
OPTIONS_FILE_UNSET+=KDE_KWALLET
OPTIONS_FILE_UNSET+=MAINTAINER_DEBUG
OPTIONS_FILE_UNSET+=MOD_DAV_SVN
OPTIONS_FILE_SET+=P4_STYLE_MARKERS
OPTIONS_FILE_UNSET+=SASL
OPTIONS_FILE_SET+=SERF
OPTIONS_FILE_UNSET+=STATIC
OPTIONS_FILE_UNSET+=SVNSERVE_WRAPPER
OPTIONS_FILE_SET+=TEST
OPTIONS_FILE_UNSET+=TOOLS
Comment 1 Edwin Groothuis freebsd_committer 2013-06-21 11:40:09 UTC
Responsible Changed
From-To: freebsd-ports-bugs->lev

Over to maintainer (via the GNATS Auto Assign Tool)
Comment 2 Lev A. Serebryakov freebsd_committer 2013-06-21 17:33:04 UTC
Hello, Bug-followup.

  Do you have access to any Linux system with subversion 1.8.0 to
 check is it FreeBSD-specific bug or not? I think, it should be
 reported to upstream.

-- 
// Black Lion AKA Lev Serebryakov <lev@FreeBSD.org>
Comment 3 Lev A. Serebryakov freebsd_committer 2013-06-21 17:42:16 UTC
State Changed
From-To: open->feedback


Ask reporter, could he check this on other system.
Comment 4 vsjcfm 2013-06-21 17:55:57 UTC
Unfortunately, I didn't find any Linux distro with svn-1.8. Latest
version is 1.7.9 in Gentoo Portage.
I'll try to build svn from source, but it will take a day or two
because of time lack.
Comment 5 vsjcfm 2013-06-25 08:18:14 UTC
I've tested fix from
http://svn.apache.org/viewvc?view=revision&revision=r1496007
Now all works fine.
Comment 6 dfilter service freebsd_committer 2013-07-13 16:37:06 UTC
Author: lev
Date: Sat Jul 13 15:36:50 2013
New Revision: 322938
URL: http://svnweb.freebsd.org/changeset/ports/322938

Log:
   (1) Fix subversion-static port to use SERF.
   (2) Backport fix of issue #4383: problems with symbolic-link WC.
   (3) Backport change r1500762 (no isue # found): conflict between
       GPG Agent and other password stories.
   (4) Fix error message when Subversion is configured with BDB abd
       APR is not.
  
  PR:		ports/179807, ports/180121, ports/180121
  Submitted by:	[3] eugen@grosbein.pp.ru

Added:
  head/devel/subversion/files/patch-fix4383   (contents, props changed)
  head/devel/subversion/files/patch-subversion--libsvn_subr--gpg_agent.c   (contents, props changed)
Modified:
  head/devel/subversion-static/Makefile
  head/devel/subversion/Makefile
  head/devel/subversion/Makefile.common

Modified: head/devel/subversion-static/Makefile
==============================================================================
--- head/devel/subversion-static/Makefile	Sat Jul 13 15:33:23 2013	(r322937)
+++ head/devel/subversion-static/Makefile	Sat Jul 13 15:36:50 2013	(r322938)
@@ -3,10 +3,10 @@
 PKGNAMESUFFIX=	-static
 
 CONFLICTS_INSTALL=	${PORTNAME}-[0-9]*
-LATEST_LINK=	${PORTNAME}${PKGNAMESUFFIX}
+LATEST_LINK=		${PORTNAME}${PKGNAMESUFFIX}
 
 OPTIONS_EXCLUDE=	${OPTIONS_DEFINE}
-OPTIONS_SLAVE=	NEON STATIC FREEBSD_TEMPLATE ENHANCED_KEYWORD
+OPTIONS_SLAVE=		FREEBSD_TEMPLATE P4_STYLE_MARKERS SERF STATIC
 
 MASTERDIR=	${.CURDIR}/../subversion
 PKGMESSAGE=	${.CURDIR}/pkg-message

Modified: head/devel/subversion/Makefile
==============================================================================
--- head/devel/subversion/Makefile	Sat Jul 13 15:33:23 2013	(r322937)
+++ head/devel/subversion/Makefile	Sat Jul 13 15:36:50 2013	(r322938)
@@ -15,9 +15,10 @@ MAN8=		svnserve.8
 
 TXT_DOCS=	BUGS CHANGES COMMITTERS INSTALL README
 
-OPTIONS_DEFINE=	BDB BOOK GNOME_KEYRING KDE_KWALLET MAINTAINER_DEBUG \
-		MOD_DAV_SVN P4_STYLE_MARKERS FREEBSD_TEMPLATE SASL \
-		SERF STATIC SVNSERVE_WRAPPER TEST TOOLS \
+OPTIONS_DEFINE=	BDB BOOK DOCS GNOME_KEYRING KDE_KWALLET \
+		MAINTAINER_DEBUG MOD_DAV_SVN NLS P4_STYLE_MARKERS \
+		FREEBSD_TEMPLATE SASL SERF STATIC SVNSERVE_WRAPPER \
+		TEST TOOLS
 
 OPTIONS_DEFAULT=P4_STYLE_MARKERS FREEBSD_TEMPLATE SERF
 
@@ -212,8 +213,8 @@ pre-configure:
 	@BDB_VERSION=`${APR_APU_DIR}/${APU_CONFIG} --db-version`; \
 	if [ "$${BDB_VERSION}" != "4" -a "$${BDB_VERSION}" != "5" ] ; then \
 		${ECHO_MSG} "" ; \
-		${ECHO_MSG} 'You should build `'"${APR_PORT}' with Berkeley DB (4 or 5) support to use subversion with it." ; \
-		${ECHO_MSG} 'Please rebuild `'"${APR_PORT}' with option "'`'"${OPT_NAME}' and try again." ; \
+		${ECHO_MSG} 'You should build `'"devel/apr1' with Berkeley DB (4 or 5) support to use subversion with it." ; \
+		${ECHO_MSG} 'Please rebuild `'"devel/apr1' with option "'`'"${OPT_NAME}' and try again." ; \
 		${ECHO_MSG} "" ; \
 		${ECHO_MSG} "Or you can disable Berkeley DB support. Only 'fs' repository backend will be available." ; \
 		${ECHO_MSG} "" ; \

Modified: head/devel/subversion/Makefile.common
==============================================================================
--- head/devel/subversion/Makefile.common	Sat Jul 13 15:33:23 2013	(r322937)
+++ head/devel/subversion/Makefile.common	Sat Jul 13 15:36:50 2013	(r322938)
@@ -3,7 +3,7 @@
 
 PORTNAME=	subversion
 PORTVERSION=	1.8.0
-PORTREVISION?=	2
+PORTREVISION?=	3
 CATEGORIES+=	devel
 MASTER_SITES=	${MASTER_SITE_APACHE:S/$/:main/} \
 		${MASTER_SITE_LOCAL:S/$/:book/}

Added: head/devel/subversion/files/patch-fix4383
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/subversion/files/patch-fix4383	Sat Jul 13 15:36:50 2013	(r322938)
@@ -0,0 +1,77 @@
+Index: subversion/libsvn_wc/wc_db_wcroot.c
+===================================================================
+--- subversion/libsvn_wc/wc_db_wcroot.c	(revision 1496006)
++++ subversion/libsvn_wc/wc_db_wcroot.c	(revision 1496007)
+@@ -434,6 +434,8 @@
+   svn_boolean_t always_check = FALSE;
+   int wc_format = 0;
+   const char *adm_relpath;
++  /* Non-NULL if WCROOT is found through a symlink: */
++  const char *symlink_wcroot_abspath = NULL;
+ 
+   /* ### we need more logic for finding the database (if it is located
+      ### outside of the wcroot) and then managing all of that within DB.
+@@ -611,6 +613,7 @@
+                   if (found_wcroot)
+                     break;
+ 
++                  symlink_wcroot_abspath = local_abspath;
+                   SVN_ERR(read_link_target(&local_abspath, local_abspath,
+                                            scratch_pool));
+ try_symlink_as_dir:
+@@ -632,6 +635,7 @@
+       local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+ 
+       moved_upwards = TRUE;
++      symlink_wcroot_abspath = NULL;
+ 
+       /* Is the parent directory recorded in our hash?  */
+       found_wcroot = svn_hash_gets(db->dir_data, local_abspath);
+@@ -669,7 +673,10 @@
+          (ie. where we found it).  */
+ 
+       err = svn_wc__db_pdh_create_wcroot(wcroot,
+-                            apr_pstrdup(db->state_pool, local_abspath),
++                            apr_pstrdup(db->state_pool,
++                                        symlink_wcroot_abspath
++                                          ? symlink_wcroot_abspath
++                                          : local_abspath),
+                             sdb, wc_id, FORMAT_FROM_SDB,
+                             db->verify_format, db->enforce_empty_wq,
+                             db->state_pool, scratch_pool);
+@@ -737,7 +744,10 @@
+         }
+ 
+       SVN_ERR(svn_wc__db_pdh_create_wcroot(wcroot,
+-                            apr_pstrdup(db->state_pool, local_abspath),
++                            apr_pstrdup(db->state_pool,
++                                        symlink_wcroot_abspath
++                                          ? symlink_wcroot_abspath
++                                          : local_abspath),
+                             NULL, UNKNOWN_WC_ID, wc_format,
+                             db->verify_format, db->enforce_empty_wq,
+                             db->state_pool, scratch_pool));
+@@ -809,6 +819,7 @@
+                                              scratch_pool));
+           if (resolved_kind == svn_node_dir)
+             {
++              symlink_wcroot_abspath = original_abspath;
+               SVN_ERR(read_link_target(&local_abspath, original_abspath,
+                                        scratch_pool));
+               /* This handle was opened in this function but is not going
+@@ -826,6 +837,15 @@
+                 apr_pstrdup(db->state_pool, local_dir_abspath),
+                 *wcroot);
+ 
++  /* If the WCROOT was found through a symlink pointing at the root of
++   * the WC, its cache entry is now keyed on the link's target path.
++   * Cache the WCROOT under the symlink's path as well. Otherwise, future
++   * wcroot queries for the symlink path would construct a fresh wcroot. */
++  if (symlink_wcroot_abspath)
++    svn_hash_sets(db->dir_data,
++                  apr_pstrdup(db->state_pool, symlink_wcroot_abspath),
++                  *wcroot);
++
+   /* Did we traverse up to parent directories?  */
+   if (!moved_upwards)
+     {

Added: head/devel/subversion/files/patch-subversion--libsvn_subr--gpg_agent.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/subversion/files/patch-subversion--libsvn_subr--gpg_agent.c	Sat Jul 13 15:36:50 2013	(r322938)
@@ -0,0 +1,145 @@
+--- subversion/libsvn_subr/gpg_agent.c	2013/07/08 14:27:14	1500761
++++ subversion/libsvn_subr/gpg_agent.c	2013/07/08 14:29:04	1500762
+@@ -156,42 +156,28 @@
+   return (strncmp(buf, "OK", 2) == 0);
+ }
+ 
+-/* Implementation of svn_auth__password_get_t that retrieves the password
+-   from gpg-agent */
++
++/* Locate a running GPG Agent, and return an open file descriptor
++ * for communication with the agent in *NEW_SD. If no running agent
++ * can be found, set *NEW_SD to -1. */
+ static svn_error_t *
+-password_get_gpg_agent(svn_boolean_t *done,
+-                       const char **password,
+-                       apr_hash_t *creds,
+-                       const char *realmstring,
+-                       const char *username,
+-                       apr_hash_t *parameters,
+-                       svn_boolean_t non_interactive,
+-                       apr_pool_t *pool)
++find_running_gpg_agent(int *new_sd, apr_pool_t *pool)
+ {
+-  int sd;
++  char *buffer;
+   char *gpg_agent_info = NULL;
++  const char *socket_name = NULL;
++  const char *request = NULL;
+   const char *p = NULL;
+   char *ep = NULL;
+-  char *buffer;
+-
+-  apr_array_header_t *socket_details;
+-  const char *request = NULL;
+-  const char *cache_id = NULL;
+-  struct sockaddr_un addr;
+-  const char *tty_name;
+-  const char *tty_type;
+-  const char *lc_ctype;
+-  const char *display;
+-  const char *socket_name = NULL;
+-  svn_checksum_t *digest = NULL;
+-  char *password_prompt;
+-  char *realm_prompt;
++  int sd;
+ 
+-  *done = FALSE;
++  *new_sd = -1;
+ 
+   gpg_agent_info = getenv("GPG_AGENT_INFO");
+   if (gpg_agent_info != NULL)
+     {
++      apr_array_header_t *socket_details;
++
+       socket_details = svn_cstring_split(gpg_agent_info, ":", TRUE,
+                                          pool);
+       socket_name = APR_ARRAY_IDX(socket_details, 0, const char *);
+@@ -201,6 +187,8 @@
+ 
+   if (socket_name != NULL)
+     {
++      struct sockaddr_un addr;
++
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path) - 1);
+       addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
+@@ -273,6 +261,44 @@
+       return SVN_NO_ERROR;
+     }
+ 
++  *new_sd = sd;
++  return SVN_NO_ERROR;
++}
++
++/* Implementation of svn_auth__password_get_t that retrieves the password
++   from gpg-agent */
++static svn_error_t *
++password_get_gpg_agent(svn_boolean_t *done,
++                       const char **password,
++                       apr_hash_t *creds,
++                       const char *realmstring,
++                       const char *username,
++                       apr_hash_t *parameters,
++                       svn_boolean_t non_interactive,
++                       apr_pool_t *pool)
++{
++  int sd;
++  const char *p = NULL;
++  char *ep = NULL;
++  char *buffer;
++  const char *request = NULL;
++  const char *cache_id = NULL;
++  const char *tty_name;
++  const char *tty_type;
++  const char *lc_ctype;
++  const char *display;
++  svn_checksum_t *digest = NULL;
++  char *password_prompt;
++  char *realm_prompt;
++
++  *done = FALSE;
++
++  SVN_ERR(find_running_gpg_agent(&sd, pool));
++  if (sd == -1)
++    return SVN_NO_ERROR;
++
++  buffer = apr_palloc(pool, BUFFER_SIZE);
++
+   /* Send TTY_NAME to the gpg-agent daemon. */
+   tty_name = getenv("GPG_TTY");
+   if (tty_name != NULL)
+@@ -388,8 +414,8 @@
+    password in GPG Agent if that's how this particular integration
+    worked.  But it isn't.  GPG Agent stores the password provided by
+    the user via the pinentry program immediately upon its provision
+-   (and regardless of its accuracy as passwords go), so there's
+-   nothing really to do here.  */
++   (and regardless of its accuracy as passwords go), so we just need
++   to check if a usable GPG Agent exists. */
+ static svn_error_t *
+ password_set_gpg_agent(svn_boolean_t *done,
+                        apr_hash_t *creds,
+@@ -400,7 +426,21 @@
+                        svn_boolean_t non_interactive,
+                        apr_pool_t *pool)
+ {
+-  *done = TRUE;
++  int sd;
++  const char *tty_name;
++
++  *done = FALSE;
++
++  SVN_ERR(find_running_gpg_agent(&sd, pool));
++  if (sd == -1)
++    return SVN_NO_ERROR;
++
++  close(sd);
++
++  /* Also ensure that GPG_TTY is set in the evironment.
++   * If it isn't set the user won't be prompted by the agent. */
++  tty_name = getenv("GPG_TTY");
++  *done = (tty_name != NULL);
+ 
+   return SVN_NO_ERROR;
+ }
_______________________________________________
svn-ports-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-ports-all
To unsubscribe, send any mail to "svn-ports-all-unsubscribe@freebsd.org"
Comment 7 Lev A. Serebryakov freebsd_committer 2013-07-13 16:38:21 UTC
State Changed
From-To: feedback->closed


Fixed upstream, backported to ports. Thanks!