DF-5683 / fix_combined.diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | --- a/sys/kern/vfs_quota.c +++ b/sys/kern/vfs_quota.c @@ -42,6 +42,7 @@ #include <sys/spinlock2.h> #include <sys/sysmsg.h> +#include <sys/caps.h> #include <libprop/proplib.h> #include <libprop/prop_dictionary.h> @@ -333,47 +334,61 @@ 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; if (!vfs_quota_enabled) return EOPNOTSUPP; + error = caps_priv_check_td(curthread, SYSCAP_NOQUOTA_WR); + if (error) + return (error); path = vqa->path; error = copyin(vqa->pref, &pref, sizeof(pref)); + if (error) + return (error); error = prop_dictionary_copyin(&pref, &dict); if (error) return(error); /* 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 +413,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; --- a/sys/kern/kern_udev.c +++ b/sys/kern/kern_udev.c @@ -1010,6 +1010,7 @@ error = prop_dictionary_copyout_ioctl(pref, cmd, odict); + prop_object_release(ctx.cdevs); prop_object_release(odict); return error; } |