[Devel] [PATCH RHEL10 COMMIT] ve/fs/devmnt: free the right pointer in ve_devmnt_check()

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jul 31 17:42:53 MSK 2026


The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-211.39.1.16.1.vz10
------>
commit 0f75ea35fc85d70431c8fc8a5238a3932271b8e7
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date:   Fri Jul 17 14:17:22 2026 +0200

    ve/fs/devmnt: free the right pointer in ve_devmnt_check()
    
    ve_devmnt_check() duplicates the option string and tokenises the copy
    with strsep(), which advances the passed pointer. It then frees that
    advanced pointer instead of the start of the allocation: on success it
    is NULL (leaking the kstrdup() buffer), and on the -EPERM exit it points
    into the middle of the buffer (freeing an invalid pointer).
    
    Keep the allocation base in its own variable and free that.
    
    Fixes: 263467c864c5 ("ve/fs/devmnt: process mount options")
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    
    Feature: ve: ve generic structures
---
 fs/namespace.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index 0f4a3668e558d..43493f779c592 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3139,8 +3139,8 @@ static char *strstr_separated(char *haystack, char *needle, char sep)
 
 static int ve_devmnt_check(char *options, char *allowed)
 {
-	char *p;
-	char *tmp_options;
+	char *buff, *opts, *p;
+	int err = 0;
 
 	if (!options || !*options)
 		return 0;
@@ -3149,22 +3149,22 @@ static int ve_devmnt_check(char *options, char *allowed)
 		return -EPERM;
 
 	/* strsep() changes provided string: puts '\0' instead of separators */
-	tmp_options = kstrdup(options, GFP_KERNEL);
-	if (!tmp_options)
+	buff = opts = kstrdup(options, GFP_KERNEL);
+	if (!buff)
 		return -ENOMEM;
 
-	while ((p = strsep(&tmp_options, ",")) != NULL) {
+	while ((p = strsep(&opts, ",")) != NULL) {
 		if (!*p)
 			continue;
 
 		if (!strstr_separated(allowed, p, ',')) {
-			kfree(tmp_options);
-			return -EPERM;
+			err = -EPERM;
+			break;
 		}
 	}
 
-	kfree(tmp_options);
-	return 0;
+	kfree(buff);
+	return err;
 }
 
 static int ve_devmnt_insert(char *options, char *hidden)


More information about the Devel mailing list