Index: appfsd.c ================================================================== --- appfsd.c +++ appfsd.c @@ -660,19 +660,23 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(-EIO); } + + Tcl_Preserve(interp); tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getattr", path); if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::getattr(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); pathinfo->type = APPFS_PATHTYPE_DOES_NOT_EXIST; appfs_get_path_info_cache_add(path, appfs_get_fsuid(), pathinfo); + + Tcl_Release(interp); return(-ENOENT); } if (attr_key_type == NULL) { @@ -689,14 +693,18 @@ tcl_ret = Tcl_DictObjGet(interp, attrs_dict, attr_key_type, &attr_value); if (tcl_ret != TCL_OK) { APPFS_DEBUG("[dict get \"type\"] failed"); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + Tcl_Release(interp); + return(-EIO); } if (attr_value == NULL) { + Tcl_Release(interp); + return(-EIO); } pathinfo->packaged = 0; pathinfo->inode = appfs_get_path_inode(path); @@ -759,10 +767,12 @@ break; case 'S': /* UNIX domain socket */ pathinfo->type = APPFS_PATHTYPE_SOCKET; break; default: + Tcl_Release(interp); + return(-EIO); } Tcl_DictObjGet(interp, attrs_dict, attr_key_packaged, &attr_value); if (attr_value != NULL) { @@ -776,10 +786,12 @@ pathinfo->time = attr_value_wide; } } else { pathinfo->time = 0; } + + Tcl_Release(interp); appfs_get_path_info_cache_add(path, appfs_get_fsuid(), pathinfo); return(0); } @@ -793,20 +805,27 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(NULL); } + + Tcl_Preserve(interp); tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::prepare_to_create", path); if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::prepare_to_create(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + Tcl_Release(interp); + return(NULL); } real_path = Tcl_GetStringResult(interp); + + Tcl_Release(interp); + if (real_path == NULL) { return(NULL); } return(strdup(real_path)); @@ -819,10 +838,12 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(NULL); } + + Tcl_Preserve(interp); tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::localpath", path); if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::localpath(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); @@ -829,10 +850,13 @@ return(NULL); } real_path = Tcl_GetStringResult(interp); + + Tcl_Release(interp); + if (real_path == NULL) { return(NULL); } return(strdup(real_path)); @@ -946,33 +970,41 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(0); } + + Tcl_Preserve(interp); filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getchildren", path); if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::getchildren(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + + Tcl_Release(interp); return(0); } tcl_ret = Tcl_ListObjGetElements(interp, Tcl_GetObjResult(interp), &children_count, &children); if (tcl_ret != TCL_OK) { APPFS_DEBUG("Parsing list of children on path %s failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + Tcl_Release(interp); + return(0); } for (idx = 0; idx < children_count; idx++) { filler(buf, Tcl_GetString(children[idx]), NULL, 0); } + + Tcl_Release(interp); return(0); } static int appfs_fuse_open(const char *path, struct fuse_file_info *fi) { @@ -1018,20 +1050,27 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(-EIO); } + + Tcl_Preserve(interp); tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::openpath", path, mode); if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::openpath(%s, %s) failed.", path, mode); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + Tcl_Release(interp); + return(-EIO); } real_path = Tcl_GetStringResult(interp); + + Tcl_Release(interp); + if (real_path == NULL) { return(-EIO); } APPFS_DEBUG("Translated request to open %s to opening %s (mode = \"%s\")", path, real_path, mode); @@ -1208,12 +1247,16 @@ tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::unlinkpath", path); if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::unlinkpath(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + Tcl_Release(interp); + return(-EIO); } + + Tcl_Release(interp); return(0); } static int appfs_fuse_mkdir(const char *path, mode_t mode) { @@ -1255,20 +1298,27 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(-EIO); } + + Tcl_Preserve(interp); tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::openpath", path, "write"); if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::openpath(%s, %s) failed.", path, "write"); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + Tcl_Release(interp); + return(-EIO); } real_path = Tcl_GetStringResult(interp); + + Tcl_Release(interp); + if (real_path == NULL) { return(-EIO); } appfs_simulate_user_fs_enter();