--- a/src/modules/client/imageplan.py Wed May 20 13:11:42 2015 -0700
+++ b/src/modules/client/imageplan.py Fri May 22 11:23:28 2015 -0700
@@ -3777,21 +3777,52 @@
self.pd._new_mediators = prop_mediators
# Link mediation is complete.
+ def __check_reserved(self, action):
+ """Check whether files are delivered to var/pkg or
+ .org.opensolaris.pkg"""
+
+ if not "path" in action.attrs:
+ return True
+
+ dirs = ["cache", "gui_cache", "history", "license",
+ "linked", "lost+found", "publisher", "ssl", "state"
+ ]
+ files = ["pkg5.image", "lock"]
+ path = action.get_installed_path(self.image.root)
+
+ for d in dirs:
+ dir_p = os.path.join(self.image.imgdir, d) + "/"
+ dir_path = path + "/"
+ if dir_path.startswith(dir_p):
+ return False
+
+ for f in files:
+ fname = os.path.join(self.image.imgdir, f)
+ if path == fname:
+ return False
+ return True
+
def __check_be_boundary(self, action, excluded_list, cur_dirs):
"""Check whether the package is installed within its
own boot environment"""
-
- # If there is no excluded list or action is not
- # dir action.
- if not excluded_list or action.name != "dir":
+
+ # We only consider dir action.
+ if not action.name == "dir":
return True
path = action.get_installed_path(self.image.root)
+ # Check whether the dir is already installed.
if path in cur_dirs:
return True
# Extend the path in format /path1/path2/
path = path + "/"
+
+ # If the path is already outside current boot
+ # environment.
+ if not path.startswith(self.image.root):
+ return False
+
for excluded_path in excluded_list:
if path.startswith(excluded_path):
return False
@@ -3839,7 +3870,14 @@
# /path1/path2/
dataset_path = os.path.normpath(special) + "/"
path += "/"
- excluded_list.append((dataset_path, path))
+ # Only paths from a dataset inside the
+ # image root need to be excluded as all
+ # actions are installed as an absolute
+ # path. we turn all relative paths into an
+ # absolute path, and we explicitly check that
+ # paths are inside the image.
+ if path.startswith(self.image.root):
+ excluded_list.append((dataset_path, path))
except:
pass
@@ -3995,7 +4033,10 @@
excluded_list = self.__parse_mnttab()
cur_dirs = self.__get_cur_directories()
for p in self.pd.pkg_plans:
- err_actions = None
+ pfmri = None
+ if p.destination_fmri:
+ pfmri = p.destination_fmri.get_fmri()
+ err_actions = api_errors.ImageBoundaryError(pfmri)
pt.plan_add_progress(pt.PLAN_ACTION_MERGE)
for src, dest in p.gen_install_actions():
if dest.name == "user":
@@ -4008,17 +4049,18 @@
# boot environment.
if not self.__check_be_boundary(dest,
excluded_list, cur_dirs):
- if not err_actions:
- err_actions = \
- api_errors.ImageBoundaryError(
- p.destination_fmri.get_fmri())
err_actions.append_error(
action=dest,
err_type=api_errors.ImageBoundaryError.\
OUTSIDE_BE)
+ elif not self.__check_reserved(dest):
+ err_actions.append_error(
+ action=dest,
+ err_type=api_errors.ImageBoundaryError.\
+ RESERVED)
self.pd.install_actions.append(
_ActionPlan(p, src, dest))
- if err_actions:
+ if not err_actions.isEmpty():
errs.append(err_actions)
if errs:
--- a/src/tests/cli/t_pkg_install.py Wed May 20 13:11:42 2015 -0700
+++ b/src/tests/cli/t_pkg_install.py Fri May 22 11:23:28 2015 -0700
@@ -1105,6 +1105,7 @@
mnttab_path = os.path.join(etc_path, "mnttab")
mnttab = open(os.path.join(mnttab_path), "w")
content = """rpool/dataset {root} zfs dev=0 0
+rpool/outside /tmp zfs 0 0
rpool/fail {root}/fail zfs dev=0 0
rpool/dataset/succ {root}/success dev dev=0 0
rpool/fail/fail2 {root}/fail2 zfs dev=0 0
@@ -1113,7 +1114,7 @@
mnttab.write(content)
mnttab.flush()
- # This path is installed under dev not in zfs
+ # This path is installed under dev not in zfs
# should be successful
success1 = """
open success1@1
@@ -1138,27 +1139,27 @@
add dir mode=0755 owner=root group=bin path=fail2
close """
- # Install a file under fail
- fail3 = """
- open fail3@1
- add file mode=0755 owner=root group=bin path=fail/foo
+ nfs_fail = """
+ open nfs_fail@1
+ add dir mode=0755 owner=root group=bin path=success/bla
close """
- nfs_fail = """
- open fail4@1
- add file mode=0755 owner=root group=bin path=success/bla/foo
- close """
-
+ user_image = """
+ open user_image_fail@1
+ add dir mode=0755 owner=root group=bin path=../../test
+ close
+ """
# Create dirs for testing
os.mkdir(os.path.join(self.get_img_path(), "test"))
os.mkdir(os.path.join(self.get_img_path(), "success"))
os.mkdir(os.path.join(self.get_img_path(), "fail"))
os.mkdir(os.path.join(self.get_img_path(), "fail2"))
os.mkdir(os.path.join(self.get_img_path(), "success/bla"))
- misc_files = [ "fail/foo", "success/bla/foo"]
- self.make_misc_files(misc_files)
+
+ path = "/".join(self.get_img_path().split("/")[:3])
+ os.mkdir(os.path.join(path, "test"))
plist = self.pkgsend_bulk(self.rurl, [success1,
- success2, fail1, fail2])
+ success2, fail1, fail2, nfs_fail, user_image])
self.pkg("--debug simulate_mnttab={0} install success1".format(
mnttab_path), exit=0)
self.pkg("--debug simulate_mnttab={0} install success2".format(
@@ -1167,10 +1168,11 @@
mnttab_path), exit=1)
self.pkg("--debug simulate_mnttab={0} install fail2".format(
mnttab_path), exit=1)
- self.pkg("--debug simulate_mnttab={0} install fail3".format(
- mnttab_path), exit=1)
self.pkg("--debug simulate_mnttab={0} install nfs_fail".format(
mnttab_path), exit=1)
+ self.pkg("--debug simulate_mnttab={0} install user_image_fail".format(
+ mnttab_path), exit=1)
+ shutil.rmtree(os.path.join(path, "test"))
def test_update_outside_boot_environment(self):
"""Test that we can not install packages outside our current
@@ -1185,6 +1187,7 @@
mnttab_path = os.path.join(etc_path, "mnttab")
mnttab = open(os.path.join(mnttab_path), "w")
content = """rpool/dataset {root} zfs dev=0 0
+rpool/outside /tmp zfs 0 0
rpool/fail {root}/fail zfs dev=0 0
rpool/dataset/succ {root}/success dev dev=0 0
rpool/fail/fail2 {root}/fail2 zfs dev=0 0
@@ -1218,16 +1221,16 @@
add dir mode=0755 owner=root group=bin path=fail2
close """
- # Install a file under fail
- fail3 = """
+ nfs_fail = """
open success2@3
- add file mode=0755 owner=root group=bin path=fail/foo
+ add dir mode=0755 owner=root group=bin path=success/bla
close """
- nfs_fail = """
- open success@4
- add file mode=0755 owner=root group=bin path=success/bla/foo
- close """
+ user_image = """
+ open success2@4
+ add dir mode=0755 owner=root group=bin path=../../test
+ close
+ """
# Create and dirs for testing
os.mkdir(os.path.join(self.get_img_path(), "test"))
@@ -1235,10 +1238,10 @@
os.mkdir(os.path.join(self.get_img_path(), "fail"))
os.mkdir(os.path.join(self.get_img_path(), "fail2"))
os.mkdir(os.path.join(self.get_img_path(), "success/bla"))
- misc_files = [ "fail/foo", "success/bla/foo"]
- self.make_misc_files(misc_files)
+ path = "/".join(self.get_img_path().split("/")[:3])
+ os.mkdir(os.path.join(path, "test"))
plist = self.pkgsend_bulk(self.rurl, [success1,
- success2, fail1, fail2])
+ success2, fail1, fail2, nfs_fail, user_image])
self.pkg("--debug simulate_mnttab={0} install success1@1".format(
mnttab_path), exit=0)
self.pkg("--debug simulate_mnttab={0} update success1".format(
@@ -1251,7 +1254,63 @@
mnttab_path), exit=1)
self.pkg("--debug simulate_mnttab={0} update success2@4".format(
mnttab_path), exit=1)
-
+ shutil.rmtree(os.path.join(path, "test"))
+
+ def test_install_to_reserved_directories(self):
+ """Ensure installation of new actions will fail when the delivered
+ files target reserved filesystem locations."""
+
+ b1 = """
+ open [email protected]
+ add dir mode=0755 owner=root group=bin path=var/pkg/cache
+ close
+ """
+ b2 = """
+ open [email protected]
+ add link path=var/pkg/pkg5.image target=tmp/cat
+ close
+ """
+ b3 = """
+ open [email protected]
+ add dir mode=0755 owner=root group=bin path=var/pkg/config
+ close
+ """
+
+ self.image_create(self.rurl)
+ self.pkgsend_bulk(self.rurl, [b1, b2, b3])
+
+ self.pkg("install b1", exit=1)
+ self.pkg("install b2", exit=1)
+ # this should pass because var/pkg/config is not reserved
+ self.pkg("install b3", exit=0)
+
+ def test_update_to_reserved_directories(self):
+ """Ensure installation of new actions will fail when the delivered
+ files target reserved filesystem locations."""
+
+ b1 = """
+ open [email protected]
+ add file tmp/cat mode=0755 owner=root group=bin path=var/pkg/foo
+ close
+ """
+ b2 = """
+ open [email protected]
+ add dir mode=0755 owner=root group=bin path=var/pkg/cache
+ close
+ """
+ b3 = """
+ open [email protected]
+ add dir mode=0755 owner=root group=bin path=var/pkg/config
+ close
+ """
+
+ self.image_create(self.rurl)
+ self.pkgsend_bulk(self.rurl, [b1, b2, b3])
+
+ self.pkg("install [email protected]", exit=0)
+ self.pkg("update [email protected]", exit=1)
+ # this should pass because var/pkg/config is not reserved
+ self.pkg("update [email protected]", exit=0)
class TestPkgInstallApache(pkg5unittest.ApacheDepotTestCase):