From ada27b1a435802523f568fd94b81e393dcbabe71 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 1 May 2008 20:04:33 +0000 Subject: [PATCH] Prevent a Volume that is being swapped from being freed from the volume list. This will most likely fix, at least partially, bug #1083. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6871 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/patches/2.2.8-strippath.patch | 103 +++++++++++++++++++++++++++ bacula/src/stored/reserve.c | 27 ++++--- bacula/technotes-2.3 | 3 + 3 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 bacula/patches/2.2.8-strippath.patch diff --git a/bacula/patches/2.2.8-strippath.patch b/bacula/patches/2.2.8-strippath.patch new file mode 100644 index 0000000000..0aae25245b --- /dev/null +++ b/bacula/patches/2.2.8-strippath.patch @@ -0,0 +1,103 @@ + + This patch fixes the strippath bug that created a buffer overrun and thus + a crash in the FD. It fixes bug #1078. + + Apply it to version 2.2.8 or higher with: + + cd + patch -p0 <2.2.8-strippath.patch + ./configure + make + ... + make install + + +Index: src/filed/backup.c +=================================================================== +--- src/filed/backup.c (revision 6843) ++++ src/filed/backup.c (working copy) +@@ -1102,9 +1102,9 @@ + + /* Copy to first path separator -- Win32 might have c: ... */ + while (*in && !IsPathSeparator(*in)) { +- *out++ = *in++; ++ out++; in++; + } +- *out++ = *in++; ++ out++; in++; + numsep++; /* one separator seen */ + for (stripped=0; strippedlink_save = get_pool_memory(PM_FNAME); + } + pm_strcpy(ff_pkt->fname_save, ff_pkt->fname); ++ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) { ++ pm_strcpy(ff_pkt->link_save, ff_pkt->link); ++ Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save), ++ strlen(ff_pkt->link)); ++ sm_check(__FILE__, __LINE__, true); ++ } + + /* + * Strip path. If it doesn't succeed put it back. If + * it does, and there is a different link string, + * attempt to strip the link. If it fails, back them + * both back. +- * Don't strip symlinks. ++ * Do not strip symlinks. + * I.e. if either stripping fails don't strip anything. + */ +- if (do_strip(ff_pkt->strip_path, ff_pkt->fname)) { +- if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) { +- pm_strcpy(ff_pkt->link_save, ff_pkt->link); +- if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) { +- strcpy(ff_pkt->link, ff_pkt->link_save); +- strcpy(ff_pkt->fname, ff_pkt->fname_save); +- } ++ if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) { ++ unstrip_path(ff_pkt); ++ goto rtn; ++ } ++ /* Strip links but not symlinks */ ++ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) { ++ if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) { ++ unstrip_path(ff_pkt); + } +- } else { +- strcpy(ff_pkt->fname, ff_pkt->fname_save); +- } +- Dmsg2(200, "fname=%s stripped=%s\n", ff_pkt->fname_save, ff_pkt->fname); ++ } ++ ++rtn: ++ Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname, ++ ff_pkt->link); + } + + static void unstrip_path(FF_PKT *ff_pkt) +@@ -1172,6 +1184,11 @@ + } + strcpy(ff_pkt->fname, ff_pkt->fname_save); + if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) { ++ Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link, ++ ff_pkt->link_save); + strcpy(ff_pkt->link, ff_pkt->link_save); ++ Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link), ++ strlen(ff_pkt->link_save)); ++ sm_check(__FILE__, __LINE__, true); + } + } diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index 8d92efc534..fc580bc0e5 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -386,22 +386,24 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) nvol->dev = NULL; /* don't zap dev entry */ free_vol_item(nvol); - /* Check if we are trying to use the Volume on a different drive */ + /* + * Check if we are trying to use the Volume on a different drive + * dev is our device + * vol->dev is where the Volume we want is + */ if (dev != vol->dev) { /* Caller wants to switch Volume to another device */ if (!vol->dev->is_busy() && !vol->is_swapping()) { Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); free_volume(dev); /* free any volume attached to our drive */ - vol->dev->set_unload(); /* unload our drive */ + vol->dev->set_unload(); /* unload the other drive */ vol->set_swapping(); /* swap from other drive */ dev->swap_dev = vol->dev; /* remember to get this vol */ vol->dev->set_load(); /* then reload on our drive */ vol->dev->vol = NULL; /* remove volume from other drive */ - vol->dev = dev; /* point it at our drive */ - dev->vol = vol; /* point our drive at it */ - Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", - VolumeName, vol->dev->print_name(), dev->print_name()); + vol->dev = dev; /* point the Volume at our drive */ + dev->vol = vol; /* point our drive at the Volume */ } else { Dmsg3(dbglvl, "==== Swap not possible Vol busy vol=%s from dev=%s to %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); @@ -589,11 +591,14 @@ bool free_volume(DEVICE *dev) } lock_volumes(); vol = dev->vol; - dev->vol = NULL; - vol_list->remove(vol); - Dmsg2(dbglvl, "=== free_volume %s dev=%s\n", vol->vol_name, dev->print_name()); - free_vol_item(vol); - debug_list_volumes("free_volume"); + /* Don't free a volume while it is being swapped */ + if (!vol->is_swapping()) { + dev->vol = NULL; + vol_list->remove(vol); + Dmsg2(dbglvl, "=== free_volume %s dev=%s\n", vol->vol_name, dev->print_name()); + free_vol_item(vol); + debug_list_volumes("free_volume"); + } unlock_volumes(); return true; } diff --git a/bacula/technotes-2.3 b/bacula/technotes-2.3 index 658b1f5117..7d93b5e066 100644 --- a/bacula/technotes-2.3 +++ b/bacula/technotes-2.3 @@ -25,6 +25,9 @@ Add long term statistics job table General: 01May08 +kes Prevent a Volume that is being swapped from being freed from + the volume list. This will most likely fix, at least partially, + bug #1083. kes Fix strippath so that it does not get a buffer overrun and crash FD. This fixes bug #1078. kes Remove 50 millisec wait in SD that broke debugger. -- 2.39.5