⬢ DragonFlyBSD Kernel Audit
DF-5683 / fix_combined.diff
← back to finding ↓ download raw
--- 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;
 }