Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3986a999 authored by Elliott Hughes's avatar Elliott Hughes Committed by Automerger Merge Worker
Browse files

Merge "libsparse: Fix overflow of merged sparse chunk length" am: 7298ba09 am: 6c39be7d

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1394507

Change-Id: Ia4db25b923e319972d9a077441f7c31e8f4ee5e9
parents 81cebb37 6c39be7d
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@

struct backed_block {
  unsigned int block;
  unsigned int len;
  uint64_t len;
  enum backed_block_type type;
  union {
    struct {
@@ -60,7 +60,7 @@ struct backed_block* backed_block_iter_next(struct backed_block* bb) {
  return bb->next;
}

unsigned int backed_block_len(struct backed_block* bb) {
uint64_t backed_block_len(struct backed_block* bb) {
  return bb->len;
}

@@ -270,7 +270,7 @@ static int queue_bb(struct backed_block_list* bbl, struct backed_block* new_bb)
}

/* Queues a fill block of memory to be written to the specified data blocks */
int backed_block_add_fill(struct backed_block_list* bbl, unsigned int fill_val, unsigned int len,
int backed_block_add_fill(struct backed_block_list* bbl, unsigned int fill_val, uint64_t len,
                          unsigned int block) {
  struct backed_block* bb = reinterpret_cast<backed_block*>(calloc(1, sizeof(struct backed_block)));
  if (bb == nullptr) {
@@ -287,7 +287,7 @@ int backed_block_add_fill(struct backed_block_list* bbl, unsigned int fill_val,
}

/* Queues a block of memory to be written to the specified data blocks */
int backed_block_add_data(struct backed_block_list* bbl, void* data, unsigned int len,
int backed_block_add_data(struct backed_block_list* bbl, void* data, uint64_t len,
                          unsigned int block) {
  struct backed_block* bb = reinterpret_cast<backed_block*>(calloc(1, sizeof(struct backed_block)));
  if (bb == nullptr) {
@@ -305,7 +305,7 @@ int backed_block_add_data(struct backed_block_list* bbl, void* data, unsigned in

/* Queues a chunk of a file on disk to be written to the specified data blocks */
int backed_block_add_file(struct backed_block_list* bbl, const char* filename, int64_t offset,
                          unsigned int len, unsigned int block) {
                          uint64_t len, unsigned int block) {
  struct backed_block* bb = reinterpret_cast<backed_block*>(calloc(1, sizeof(struct backed_block)));
  if (bb == nullptr) {
    return -ENOMEM;
@@ -322,7 +322,7 @@ int backed_block_add_file(struct backed_block_list* bbl, const char* filename, i
}

/* Queues a chunk of a fd to be written to the specified data blocks */
int backed_block_add_fd(struct backed_block_list* bbl, int fd, int64_t offset, unsigned int len,
int backed_block_add_fd(struct backed_block_list* bbl, int fd, int64_t offset, uint64_t len,
                        unsigned int block) {
  struct backed_block* bb = reinterpret_cast<backed_block*>(calloc(1, sizeof(struct backed_block)));
  if (bb == nullptr) {
+5 −5
Original line number Diff line number Diff line
@@ -29,18 +29,18 @@ enum backed_block_type {
  BACKED_BLOCK_FILL,
};

int backed_block_add_data(struct backed_block_list* bbl, void* data, unsigned int len,
int backed_block_add_data(struct backed_block_list* bbl, void* data, uint64_t len,
                          unsigned int block);
int backed_block_add_fill(struct backed_block_list* bbl, unsigned int fill_val, unsigned int len,
int backed_block_add_fill(struct backed_block_list* bbl, unsigned int fill_val, uint64_t len,
                          unsigned int block);
int backed_block_add_file(struct backed_block_list* bbl, const char* filename, int64_t offset,
                          unsigned int len, unsigned int block);
int backed_block_add_fd(struct backed_block_list* bbl, int fd, int64_t offset, unsigned int len,
                          uint64_t len, unsigned int block);
int backed_block_add_fd(struct backed_block_list* bbl, int fd, int64_t offset, uint64_t len,
                        unsigned int block);

struct backed_block* backed_block_iter_new(struct backed_block_list* bbl);
struct backed_block* backed_block_iter_next(struct backed_block* bb);
unsigned int backed_block_len(struct backed_block* bb);
uint64_t backed_block_len(struct backed_block* bb);
unsigned int backed_block_block(struct backed_block* bb);
void* backed_block_data(struct backed_block* bb);
const char* backed_block_filename(struct backed_block* bb);
+7 −9
Original line number Diff line number Diff line
@@ -75,8 +75,7 @@ void sparse_file_destroy(struct sparse_file *s);
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_add_data(struct sparse_file *s,
		void *data, unsigned int len, unsigned int block);
int sparse_file_add_data(struct sparse_file* s, void* data, uint64_t len, unsigned int block);

/**
 * sparse_file_add_fill - associate a fill chunk with a sparse file
@@ -93,8 +92,8 @@ int sparse_file_add_data(struct sparse_file *s,
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_add_fill(struct sparse_file *s,
		uint32_t fill_val, unsigned int len, unsigned int block);
int sparse_file_add_fill(struct sparse_file* s, uint32_t fill_val, uint64_t len,
                         unsigned int block);

/**
 * sparse_file_add_file - associate a chunk of a file with a sparse file
@@ -116,9 +115,8 @@ int sparse_file_add_fill(struct sparse_file *s,
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_add_file(struct sparse_file *s,
		const char *filename, int64_t file_offset, unsigned int len,
		unsigned int block);
int sparse_file_add_file(struct sparse_file* s, const char* filename, int64_t file_offset,
                         uint64_t len, unsigned int block);

/**
 * sparse_file_add_file - associate a chunk of a file with a sparse file
@@ -143,8 +141,8 @@ int sparse_file_add_file(struct sparse_file *s,
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_add_fd(struct sparse_file *s,
		int fd, int64_t file_offset, unsigned int len, unsigned int block);
int sparse_file_add_fd(struct sparse_file* s, int fd, int64_t file_offset, uint64_t len,
                       unsigned int block);

/**
 * sparse_file_write - write a sparse file to a file
+20 −19
Original line number Diff line number Diff line
@@ -65,9 +65,9 @@ struct output_file_ops {
};

struct sparse_file_ops {
  int (*write_data_chunk)(struct output_file* out, unsigned int len, void* data);
  int (*write_fill_chunk)(struct output_file* out, unsigned int len, uint32_t fill_val);
  int (*write_skip_chunk)(struct output_file* out, int64_t len);
  int (*write_data_chunk)(struct output_file* out, uint64_t len, void* data);
  int (*write_fill_chunk)(struct output_file* out, uint64_t len, uint32_t fill_val);
  int (*write_skip_chunk)(struct output_file* out, uint64_t len);
  int (*write_end_chunk)(struct output_file* out);
};

@@ -316,7 +316,7 @@ int read_all(int fd, void* buf, size_t len) {
  return 0;
}

static int write_sparse_skip_chunk(struct output_file* out, int64_t skip_len) {
static int write_sparse_skip_chunk(struct output_file* out, uint64_t skip_len) {
  chunk_header_t chunk_header;
  int ret;

@@ -340,9 +340,10 @@ static int write_sparse_skip_chunk(struct output_file* out, int64_t skip_len) {
  return 0;
}

static int write_sparse_fill_chunk(struct output_file* out, unsigned int len, uint32_t fill_val) {
static int write_sparse_fill_chunk(struct output_file* out, uint64_t len, uint32_t fill_val) {
  chunk_header_t chunk_header;
  int rnd_up_len, count;
  uint64_t rnd_up_len;
  int count;
  int ret;

  /* Round up the fill length to a multiple of the block size */
@@ -370,9 +371,9 @@ static int write_sparse_fill_chunk(struct output_file* out, unsigned int len, ui
  return 0;
}

static int write_sparse_data_chunk(struct output_file* out, unsigned int len, void* data) {
static int write_sparse_data_chunk(struct output_file* out, uint64_t len, void* data) {
  chunk_header_t chunk_header;
  int rnd_up_len, zero_len;
  uint64_t rnd_up_len, zero_len;
  int ret;

  /* Round up the data length to a multiple of the block size */
@@ -437,9 +438,9 @@ static struct sparse_file_ops sparse_file_ops = {
    .write_end_chunk = write_sparse_end_chunk,
};

static int write_normal_data_chunk(struct output_file* out, unsigned int len, void* data) {
static int write_normal_data_chunk(struct output_file* out, uint64_t len, void* data) {
  int ret;
  unsigned int rnd_up_len = ALIGN(len, out->block_size);
  uint64_t rnd_up_len = ALIGN(len, out->block_size);

  ret = out->ops->write(out, data, len);
  if (ret < 0) {
@@ -453,10 +454,10 @@ static int write_normal_data_chunk(struct output_file* out, unsigned int len, vo
  return ret;
}

static int write_normal_fill_chunk(struct output_file* out, unsigned int len, uint32_t fill_val) {
static int write_normal_fill_chunk(struct output_file* out, uint64_t len, uint32_t fill_val) {
  int ret;
  unsigned int i;
  unsigned int write_len;
  uint64_t write_len;

  /* Initialize fill_buf with the fill_val */
  for (i = 0; i < out->block_size / sizeof(uint32_t); i++) {
@@ -464,7 +465,7 @@ static int write_normal_fill_chunk(struct output_file* out, unsigned int len, ui
  }

  while (len) {
    write_len = std::min(len, out->block_size);
    write_len = std::min(len, (uint64_t)out->block_size);
    ret = out->ops->write(out, out->fill_buf, write_len);
    if (ret < 0) {
      return ret;
@@ -476,7 +477,7 @@ static int write_normal_fill_chunk(struct output_file* out, unsigned int len, ui
  return 0;
}

static int write_normal_skip_chunk(struct output_file* out, int64_t len) {
static int write_normal_skip_chunk(struct output_file* out, uint64_t len) {
  return out->ops->skip(out, len);
}

@@ -639,16 +640,16 @@ struct output_file* output_file_open_fd(int fd, unsigned int block_size, int64_t
}

/* Write a contiguous region of data blocks from a memory buffer */
int write_data_chunk(struct output_file* out, unsigned int len, void* data) {
int write_data_chunk(struct output_file* out, uint64_t len, void* data) {
  return out->sparse_ops->write_data_chunk(out, len, data);
}

/* Write a contiguous region of data blocks with a fill value */
int write_fill_chunk(struct output_file* out, unsigned int len, uint32_t fill_val) {
int write_fill_chunk(struct output_file* out, uint64_t len, uint32_t fill_val) {
  return out->sparse_ops->write_fill_chunk(out, len, fill_val);
}

int write_fd_chunk(struct output_file* out, unsigned int len, int fd, int64_t offset) {
int write_fd_chunk(struct output_file* out, uint64_t len, int fd, int64_t offset) {
  auto m = android::base::MappedFile::FromFd(fd, offset, len, PROT_READ);
  if (!m) return -errno;

@@ -656,7 +657,7 @@ int write_fd_chunk(struct output_file* out, unsigned int len, int fd, int64_t of
}

/* Write a contiguous region of data blocks from a file */
int write_file_chunk(struct output_file* out, unsigned int len, const char* file, int64_t offset) {
int write_file_chunk(struct output_file* out, uint64_t len, const char* file, int64_t offset) {
  int ret;

  int file_fd = open(file, O_RDONLY | O_BINARY);
@@ -671,6 +672,6 @@ int write_file_chunk(struct output_file* out, unsigned int len, const char* file
  return ret;
}

int write_skip_chunk(struct output_file* out, int64_t len) {
int write_skip_chunk(struct output_file* out, uint64_t len) {
  return out->sparse_ops->write_skip_chunk(out, len);
}
+5 −5
Original line number Diff line number Diff line
@@ -30,11 +30,11 @@ struct output_file* output_file_open_fd(int fd, unsigned int block_size, int64_t
struct output_file* output_file_open_callback(int (*write)(void*, const void*, size_t), void* priv,
                                              unsigned int block_size, int64_t len, int gz,
                                              int sparse, int chunks, int crc);
int write_data_chunk(struct output_file* out, unsigned int len, void* data);
int write_fill_chunk(struct output_file* out, unsigned int len, uint32_t fill_val);
int write_file_chunk(struct output_file* out, unsigned int len, const char* file, int64_t offset);
int write_fd_chunk(struct output_file* out, unsigned int len, int fd, int64_t offset);
int write_skip_chunk(struct output_file* out, int64_t len);
int write_data_chunk(struct output_file* out, uint64_t len, void* data);
int write_fill_chunk(struct output_file* out, uint64_t len, uint32_t fill_val);
int write_file_chunk(struct output_file* out, uint64_t len, const char* file, int64_t offset);
int write_fd_chunk(struct output_file* out, uint64_t len, int fd, int64_t offset);
int write_skip_chunk(struct output_file* out, uint64_t len);
void output_file_close(struct output_file* out);

int read_all(int fd, void* buf, size_t len);
Loading