DF-5683 / fix.diff
--- a/sys/kern/vfs_quota.c +++ b/sys/kern/vfs_quota.c @@ -333,8 +333,9 @@ const char *path; struct plistref pref; prop_dictionary_t dict; + prop_dictionary_t odict; prop_object_t args; - char *cmd; + const char *cmd; prop_array_t pa_out; struct nlookupdata nd; int error; @@ -349,31 +350,39 @@ /* we have a path, get its mount point */ error = nlookup_init(&nd, path, UIO_USERSPACE, 0); - if (error) + if (error) { + prop_object_release(dict); return (error); + } error = nlookup(&nd); - if (error) + if (error) { + prop_object_release(dict); + nlookup_done(&nd); return (error); + } nch = nd.nl_nch; cache_zero(&nd.nl_nch); nlookup_done(&nd); /* get the command */ - if (prop_dictionary_get_cstring(dict, "command", &cmd) == 0) { + if (prop_dictionary_get_cstring_nocopy(dict, "command", &cmd) == 0) { kprintf("sys_vquotactl(): couldn't get command\n"); cache_put(&nch); + prop_object_release(dict); return EINVAL; } args = prop_dictionary_get(dict, "arguments"); if (args == NULL) { kprintf("couldn't get arguments\n"); cache_put(&nch); + prop_object_release(dict); return EINVAL; } pa_out = prop_array_create(); if (pa_out == NULL) { cache_put(&nch); + prop_object_release(dict); return ENOMEM; } @@ -398,15 +407,26 @@ goto done; } cache_put(&nch); + prop_object_release(pa_out); + prop_object_release(dict); return EINVAL; done: /* kernel to userland */ - dict = prop_dictionary_create(); - error = prop_dictionary_set(dict, "returned data", pa_out); + odict = prop_dictionary_create(); + if (odict == NULL) { + cache_put(&nch); + prop_object_release(pa_out); + prop_object_release(dict); + return ENOMEM; + } + error = prop_dictionary_set(odict, "returned data", pa_out); - error = prop_dictionary_copyout(&pref, dict); + error = prop_dictionary_copyout(&pref, odict); error = copyout(&pref, vqa->pref, sizeof(pref)); + prop_object_release(odict); + prop_object_release(pa_out); + prop_object_release(dict); cache_put(&nch); return error; |