summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Bao2018-04-23 17:15:40 -0500
committerTao Bao2018-04-25 12:29:22 -0500
commite18c03165b3ea86f563e104f44696d5c53f5b6a5 (patch)
tree967bd9f4d4d7fa2c57a8f194e05f47523f32c589 /libsparse
parent9249f4bc4148caef423a9cd0139d9e917fb36341 (diff)
downloadplatform-system-core-e18c03165b3ea86f563e104f44696d5c53f5b6a5.tar.gz
platform-system-core-e18c03165b3ea86f563e104f44696d5c53f5b6a5.tar.xz
platform-system-core-e18c03165b3ea86f563e104f44696d5c53f5b6a5.zip
libsparse: Use 'size_t' for the 'len' parameter in callbacks.
This CL updates the callback function signature in sparse_file_callback() and sparse_file_foreach_chunk(). Before: int sparse_file_callback( struct sparse_file *s, bool sparse, bool crc, int (*write)(void *priv, const void *data, int len), void *priv); int sparse_file_foreach_chunk( struct sparse_file *s, bool sparse, bool crc, int (*write)( void *priv, const void *data, int len, unsigned int block, unsigned int nr_blocks), void *priv); After: int sparse_file_callback( struct sparse_file *s, bool sparse, bool crc, int (*write)(void *priv, const void *data, size_t len), void *priv); int sparse_file_foreach_chunk( struct sparse_file *s, bool sparse, bool crc, int (*write)( void *priv, const void *data, size_t len, unsigned int block, unsigned int nr_blocks), void *priv); The length (i.e. 'len') comes from the size of a chunk, which could be legitimately larger than INT_MAX. Prior to this CL, callers (e.g. write_sparse_data_chunk()) were already passing unsigned int to the callbacks. When a chunk size exceeds INT_MAX, the callback would see a negative value, which could lead to undesired behavior. For example, out_counter_write(), as one of the internal callbacks in libsparse, gives a wrong sum of chunk sizes, which in turn fails the fastboot flashing when given a huge sparse image. It also defines SPARSE_CALLBACK_USES_SIZE_T that allows clients to keep their codes compatibile with both versions. Bug: 78432315 Test: `m dist` (with matching changes to all the clients) Test: Build fastboot and successfully flash a previously failing (huge) sparse image. Change-Id: Iac4bcf7b57039d08af3c57f4be00d75f6b693d93
Diffstat (limited to 'libsparse')
-rw-r--r--libsparse/include/sparse/sparse.h10
-rw-r--r--libsparse/output_file.c5
-rw-r--r--libsparse/output_file.h3
-rw-r--r--libsparse/sparse.c12
4 files changed, 19 insertions, 11 deletions
diff --git a/libsparse/include/sparse/sparse.h b/libsparse/include/sparse/sparse.h
index 356f65fd0..1b91ead5c 100644
--- a/libsparse/include/sparse/sparse.h
+++ b/libsparse/include/sparse/sparse.h
@@ -18,6 +18,7 @@
18#define _LIBSPARSE_SPARSE_H_ 18#define _LIBSPARSE_SPARSE_H_
19 19
20#include <stdbool.h> 20#include <stdbool.h>
21#include <stddef.h>
21#include <stdint.h> 22#include <stdint.h>
22 23
23#ifdef __cplusplus 24#ifdef __cplusplus
@@ -26,6 +27,11 @@ extern "C" {
26 27
27struct sparse_file; 28struct sparse_file;
28 29
30// The callbacks in sparse_file_callback() and sparse_file_foreach_chunk() take
31// size_t as the length type (was `int` in past). This allows clients to keep
32// their codes compatibile with both versions as needed.
33#define SPARSE_CALLBACK_USES_SIZE_T
34
29/** 35/**
30 * sparse_file_new - create a new sparse file cookie 36 * sparse_file_new - create a new sparse file cookie
31 * 37 *
@@ -201,7 +207,7 @@ unsigned int sparse_file_block_size(struct sparse_file *s);
201 * Returns 0 on success, negative errno on error. 207 * Returns 0 on success, negative errno on error.
202 */ 208 */
203int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc, 209int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
204 int (*write)(void *priv, const void *data, int len), void *priv); 210 int (*write)(void *priv, const void *data, size_t len), void *priv);
205 211
206/** 212/**
207 * sparse_file_foreach_chunk - call a callback for data blocks in sparse file 213 * sparse_file_foreach_chunk - call a callback for data blocks in sparse file
@@ -218,7 +224,7 @@ int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
218 * Returns 0 on success, negative errno on error. 224 * Returns 0 on success, negative errno on error.
219 */ 225 */
220int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc, 226int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
221 int (*write)(void *priv, const void *data, int len, unsigned int block, 227 int (*write)(void *priv, const void *data, size_t len, unsigned int block,
222 unsigned int nr_blocks), 228 unsigned int nr_blocks),
223 void *priv); 229 void *priv);
224/** 230/**
diff --git a/libsparse/output_file.c b/libsparse/output_file.c
index 51e60ef79..002ad2746 100644
--- a/libsparse/output_file.c
+++ b/libsparse/output_file.c
@@ -109,7 +109,7 @@ struct output_file_normal {
109struct output_file_callback { 109struct output_file_callback {
110 struct output_file out; 110 struct output_file out;
111 void *priv; 111 void *priv;
112 int (*write)(void *priv, const void *buf, int len); 112 int (*write)(void *priv, const void *buf, size_t len);
113}; 113};
114 114
115#define to_output_file_callback(_o) \ 115#define to_output_file_callback(_o) \
@@ -634,7 +634,8 @@ static struct output_file *output_file_new_normal(void)
634 return &outn->out; 634 return &outn->out;
635} 635}
636 636
637struct output_file *output_file_open_callback(int (*write)(void *, const void *, int), 637struct output_file *output_file_open_callback(
638 int (*write)(void *, const void *, size_t),
638 void *priv, unsigned int block_size, int64_t len, 639 void *priv, unsigned int block_size, int64_t len,
639 int gz __unused, int sparse, int chunks, int crc) 640 int gz __unused, int sparse, int chunks, int crc)
640{ 641{
diff --git a/libsparse/output_file.h b/libsparse/output_file.h
index b67e94ecb..690f61057 100644
--- a/libsparse/output_file.h
+++ b/libsparse/output_file.h
@@ -27,7 +27,8 @@ struct output_file;
27 27
28struct output_file *output_file_open_fd(int fd, unsigned int block_size, int64_t len, 28struct output_file *output_file_open_fd(int fd, unsigned int block_size, int64_t len,
29 int gz, int sparse, int chunks, int crc); 29 int gz, int sparse, int chunks, int crc);
30struct output_file *output_file_open_callback(int (*write)(void *, const void *, int), 30struct output_file *output_file_open_callback(
31 int (*write)(void *, const void *, size_t),
31 void *priv, unsigned int block_size, int64_t len, int gz, int sparse, 32 void *priv, unsigned int block_size, int64_t len, int gz, int sparse,
32 int chunks, int crc); 33 int chunks, int crc);
33int write_data_chunk(struct output_file *out, unsigned int len, void *data); 34int write_data_chunk(struct output_file *out, unsigned int len, void *data);
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index b17586066..466435f7b 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -179,7 +179,7 @@ int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse,
179} 179}
180 180
181int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc, 181int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
182 int (*write)(void *priv, const void *data, int len), void *priv) 182 int (*write)(void *priv, const void *data, size_t len), void *priv)
183{ 183{
184 int ret; 184 int ret;
185 int chunks; 185 int chunks;
@@ -203,11 +203,11 @@ struct chunk_data {
203 void *priv; 203 void *priv;
204 unsigned int block; 204 unsigned int block;
205 unsigned int nr_blocks; 205 unsigned int nr_blocks;
206 int (*write)(void *priv, const void *data, int len, unsigned int block, 206 int (*write)(void *priv, const void *data, size_t len,
207 unsigned int nr_blocks); 207 unsigned int block, unsigned int nr_blocks);
208}; 208};
209 209
210static int foreach_chunk_write(void *priv, const void *data, int len) 210static int foreach_chunk_write(void *priv, const void *data, size_t len)
211{ 211{
212 struct chunk_data *chk = priv; 212 struct chunk_data *chk = priv;
213 213
@@ -215,7 +215,7 @@ static int foreach_chunk_write(void *priv, const void *data, int len)
215} 215}
216 216
217int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc, 217int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
218 int (*write)(void *priv, const void *data, int len, unsigned int block, 218 int (*write)(void *priv, const void *data, size_t len, unsigned int block,
219 unsigned int nr_blocks), 219 unsigned int nr_blocks),
220 void *priv) 220 void *priv)
221{ 221{
@@ -250,7 +250,7 @@ int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
250 return ret; 250 return ret;
251} 251}
252 252
253static int out_counter_write(void *priv, const void *data __unused, int len) 253static int out_counter_write(void *priv, const void *data __unused, size_t len)
254{ 254{
255 int64_t *count = priv; 255 int64_t *count = priv;
256 *count += len; 256 *count += len;