[PATCH v4] liveupdate: fix return value on session allocation failure

Pasha Tatashin posted 1 patch 2 months ago
kernel/liveupdate/luo_session.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
[PATCH v4] liveupdate: fix return value on session allocation failure
Posted by Pasha Tatashin 2 months ago
When session allocation fails during deserialization, the global 'err'
variable was not updated before returning. This caused subsequent calls
to luo_session_deserialize() to incorrectly report success.

Ensure 'err' is set to the error code from PTR_ERR(session). This
ensures that an error is correctly returned to userspace when it
attempts to open /dev/liveupdate in the new kernel if deserialization
failed.

Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org>
---
 kernel/liveupdate/luo_session.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
index a3327a28fc1f..7a42385dabe2 100644
--- a/kernel/liveupdate/luo_session.c
+++ b/kernel/liveupdate/luo_session.c
@@ -514,11 +514,12 @@ int luo_session_deserialize(void)
 {
 	struct luo_session_header *sh = &luo_session_global.incoming;
 	static bool is_deserialized;
-	static int err;
+	static int saved_err;
+	int err;
 
 	/* If has been deserialized, always return the same error code */
 	if (is_deserialized)
-		return err;
+		return saved_err;
 
 	is_deserialized = true;
 	if (!sh->active)
@@ -547,7 +548,8 @@ int luo_session_deserialize(void)
 			pr_warn("Failed to allocate session [%.*s] during deserialization %pe\n",
 				(int)sizeof(sh->ser[i].name),
 				sh->ser[i].name, session);
-			return PTR_ERR(session);
+			err = PTR_ERR(session);
+			goto save_err;
 		}
 
 		err = luo_session_insert(sh, session);
@@ -555,7 +557,7 @@ int luo_session_deserialize(void)
 			pr_warn("Failed to insert session [%s] %pe\n",
 				session->name, ERR_PTR(err));
 			luo_session_free(session);
-			return err;
+			goto save_err;
 		}
 
 		scoped_guard(mutex, &session->mutex) {
@@ -565,7 +567,7 @@ int luo_session_deserialize(void)
 		if (err) {
 			pr_warn("Failed to deserialize files for session [%s] %pe\n",
 				session->name, ERR_PTR(err));
-			return err;
+			goto save_err;
 		}
 	}
 
@@ -574,6 +576,9 @@ int luo_session_deserialize(void)
 	sh->ser = NULL;
 
 	return 0;
+save_err:
+	saved_err = err;
+	return err;
 }
 
 int luo_session_serialize(void)
-- 
2.43.0
Re: [PATCH v4] liveupdate: fix return value on session allocation failure
Posted by Mike Rapoport 2 months ago
On Wed, Apr 15, 2026 at 07:37:38PM +0000, Pasha Tatashin wrote:
> When session allocation fails during deserialization, the global 'err'
> variable was not updated before returning. This caused subsequent calls
> to luo_session_deserialize() to incorrectly report success.
> 
> Ensure 'err' is set to the error code from PTR_ERR(session). This
> ensures that an error is correctly returned to userspace when it
> attempts to open /dev/liveupdate in the new kernel if deserialization
> failed.
> 
> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org>

Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

> ---
>  kernel/liveupdate/luo_session.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
> index a3327a28fc1f..7a42385dabe2 100644
> --- a/kernel/liveupdate/luo_session.c
> +++ b/kernel/liveupdate/luo_session.c
> @@ -514,11 +514,12 @@ int luo_session_deserialize(void)
>  {
>  	struct luo_session_header *sh = &luo_session_global.incoming;
>  	static bool is_deserialized;
> -	static int err;
> +	static int saved_err;
> +	int err;
>  
>  	/* If has been deserialized, always return the same error code */
>  	if (is_deserialized)
> -		return err;
> +		return saved_err;
>  
>  	is_deserialized = true;
>  	if (!sh->active)
> @@ -547,7 +548,8 @@ int luo_session_deserialize(void)
>  			pr_warn("Failed to allocate session [%.*s] during deserialization %pe\n",
>  				(int)sizeof(sh->ser[i].name),
>  				sh->ser[i].name, session);
> -			return PTR_ERR(session);
> +			err = PTR_ERR(session);
> +			goto save_err;
>  		}
>  
>  		err = luo_session_insert(sh, session);
> @@ -555,7 +557,7 @@ int luo_session_deserialize(void)
>  			pr_warn("Failed to insert session [%s] %pe\n",
>  				session->name, ERR_PTR(err));
>  			luo_session_free(session);
> -			return err;
> +			goto save_err;
>  		}
>  
>  		scoped_guard(mutex, &session->mutex) {
> @@ -565,7 +567,7 @@ int luo_session_deserialize(void)
>  		if (err) {
>  			pr_warn("Failed to deserialize files for session [%s] %pe\n",
>  				session->name, ERR_PTR(err));
> -			return err;
> +			goto save_err;
>  		}
>  	}
>  
> @@ -574,6 +576,9 @@ int luo_session_deserialize(void)
>  	sh->ser = NULL;
>  
>  	return 0;
> +save_err:
> +	saved_err = err;
> +	return err;
>  }
>  
>  int luo_session_serialize(void)
> -- 
> 2.43.0
> 

-- 
Sincerely yours,
Mike.