diff mbox series

[1/1] lua: prevent copy2file from corrupting input file

Message ID 20230913034523.177625-1-james.hilliard1@gmail.com
State Accepted
Delegated to: Stefano Babic
Headers show
Series [1/1] lua: prevent copy2file from corrupting input file | expand

Commit Message

James Hilliard Sept. 13, 2023, 3:45 a.m. UTC
If we call copy2file with the temporary filepath of our input file
it will result in hash mismatch errors that can be tricky to identify
properly. It can also result in a corrupt output file.

To prevent this ensure that fdin and fdout point to different files.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
 core/util.c             | 7 +++++++
 corelib/lua_interface.c | 6 ++++++
 include/util.h          | 1 +
 3 files changed, 14 insertions(+)

Comments

Stefano Babic Sept. 13, 2023, 7:58 a.m. UTC | #1
Hi James,

On 13.09.23 05:45, James Hilliard wrote:
> If we call copy2file with the temporary filepath of our input file
> it will result in hash mismatch errors that can be tricky to identify
> properly. It can also result in a corrupt output file.
> 
> To prevent this ensure that fdin and fdout point to different files.
> 

Yes, I think it is a good idea to have this check, else it is not easy 
to find the reason. Thanks for this.


> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> ---
>   core/util.c             | 7 +++++++
>   corelib/lua_interface.c | 6 ++++++
>   include/util.h          | 1 +
>   3 files changed, 14 insertions(+)
> 
> diff --git a/core/util.c b/core/util.c
> index a6ddf82..9ab0a17 100644
> --- a/core/util.c
> +++ b/core/util.c
> @@ -1211,3 +1211,10 @@ bool img_check_free_space(struct img_type *img, int fd)
>   
>   	return check_free_space(fd, size, img->fname);
>   }
> +
> +bool check_same_file(int fd1, int fd2) {
> +    struct stat stat1, stat2;
> +    if(fstat(fd1, &stat1) < 0) return false;
> +    if(fstat(fd2, &stat2) < 0) return false;
> +    return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
> +}
> diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
> index dd925b7..b68cf32 100644
> --- a/corelib/lua_interface.c
> +++ b/corelib/lua_interface.c
> @@ -393,6 +393,12 @@ static int l_copy2file(lua_State *L)
>   	uint32_t checksum = 0;
>   
>   	table2image(L, &img);
> +	if (check_same_file(img.fdin, fdout)) {
> +		lua_pop(L, 1);
> +		lua_pushinteger(L, -1);
> +		lua_pushstring(L, "Output file path is same as input file temporary path");
> +		goto copyfile_exit;
> +	}
>   	int ret = copyfile(img.fdin,
>   				 &fdout,
>   				 img.size,
> diff --git a/include/util.h b/include/util.h
> index 3c2a42f..2f5c7ad 100644
> --- a/include/util.h
> +++ b/include/util.h
> @@ -230,6 +230,7 @@ int read_lines_notify(int fd, char *buf, int buf_size, int *buf_offset,
>   		      LOGLEVEL level);
>   long long get_output_size(struct img_type *img, bool strict);
>   bool img_check_free_space(struct img_type *img, int fd);
> +bool check_same_file(int fd1, int fd2);
>   
>   /* Decryption key functions */
>   int load_decryption_key(char *fname);

Reviewed-by: Stefano Babic <stefano.babic@swupdate.org>

Best regards,
Stefano
diff mbox series

Patch

diff --git a/core/util.c b/core/util.c
index a6ddf82..9ab0a17 100644
--- a/core/util.c
+++ b/core/util.c
@@ -1211,3 +1211,10 @@  bool img_check_free_space(struct img_type *img, int fd)
 
 	return check_free_space(fd, size, img->fname);
 }
+
+bool check_same_file(int fd1, int fd2) {
+    struct stat stat1, stat2;
+    if(fstat(fd1, &stat1) < 0) return false;
+    if(fstat(fd2, &stat2) < 0) return false;
+    return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
+}
diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
index dd925b7..b68cf32 100644
--- a/corelib/lua_interface.c
+++ b/corelib/lua_interface.c
@@ -393,6 +393,12 @@  static int l_copy2file(lua_State *L)
 	uint32_t checksum = 0;
 
 	table2image(L, &img);
+	if (check_same_file(img.fdin, fdout)) {
+		lua_pop(L, 1);
+		lua_pushinteger(L, -1);
+		lua_pushstring(L, "Output file path is same as input file temporary path");
+		goto copyfile_exit;
+	}
 	int ret = copyfile(img.fdin,
 				 &fdout,
 				 img.size,
diff --git a/include/util.h b/include/util.h
index 3c2a42f..2f5c7ad 100644
--- a/include/util.h
+++ b/include/util.h
@@ -230,6 +230,7 @@  int read_lines_notify(int fd, char *buf, int buf_size, int *buf_offset,
 		      LOGLEVEL level);
 long long get_output_size(struct img_type *img, bool strict);
 bool img_check_free_space(struct img_type *img, int fd);
+bool check_same_file(int fd1, int fd2);
 
 /* Decryption key functions */
 int load_decryption_key(char *fname);