Message ID | 1537956103-17504-1-git-send-email-mark.jonas@de.bosch.com |
---|---|
State | Accepted |
Headers | show |
Series | [v2] cpio_utils: fix infinite read when interrupting an update | expand |
On 26/09/2018 12:01, Mark Jonas wrote: > From: Ben Guan <ben.guan@cn.bosch.com> > > When using the IPC API to do an update from a stream using a compressed > image, a new update cannot be started if the previous one is > interrupted. > > The root cause is: When the client closes the socket, the read on the > server side will return 0 and it is treated as a successful read in > gunzip_step(). Thus, it goes into an infinite read loop. > > It is fixed by adhering to the contract that an upstream step return > zero in case of EOF. > > It can be reproduced using a compressed image: > > 1. Start the server via "swupdate -e stable,image2". > 2. Trigger an update via "swupdate-client image.swu". > 3. Cancel the update via Ctrl + C. > 4. Trigger another update via "swupdate-client image.swu". > > The following is the sw-description file used for the test: > > software = > { > version = "4.0.0"; > > hardware-compatibility: ["4.0"]; > > stable = { > image1: { > images: ( > { > filename = "rootfs.ext4.gz"; > device = "/dev/mmcblk2p1"; > compressed = true; > installed-directly = true; > sha256 = "@SHA256SUM@"; > } > ); > }; > image2: { > images: ( > { > filename = "rootfs.ext4.gz"; > device = "/dev/mmcblk2p2"; > compressed = true; > installed-directly = true; > sha256 = "@SHA256SUM@"; > } > ); > }; > }; > } > > Signed-off-by: Ben Guan <ben.guan@cn.bosch.com> > Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com> > --- > core/cpio_utils.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/core/cpio_utils.c b/core/cpio_utils.c > index 40ae474..0be31e6 100644 > --- a/core/cpio_utils.c > +++ b/core/cpio_utils.c > @@ -135,7 +135,7 @@ static int input_step(void *state, void *buffer, size_t size) > size = s->nbytes; > } > int ret = fill_buffer(s->fdin, buffer, size, s->offs, &s->checksum, s->dgst); > - if (ret < 0) { > + if (ret <= 0) { > return ret; > } > s->nbytes -= size; > @@ -173,6 +173,8 @@ static int decrypt_step(void *state, void *buffer, size_t size) > ret = s->upstream_step(s->upstream_state, s->input, sizeof s->input); > if (ret < 0) { > return ret; > + } else if (ret == 0) { > + s->eof = true; > } > > inlen = ret; > @@ -234,6 +236,8 @@ static int gunzip_step(void *state, void *buffer, size_t size) > ret = s->upstream_step(s->upstream_state, s->input, sizeof s->input); > if (ret < 0) { > return ret; > + } else if (ret == 0) { > + s->eof = true; > } > s->strm.avail_in = ret; > s->strm.next_in = s->input; > @@ -317,7 +321,7 @@ int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsi > if (!input_state.dgst) > return -EFAULT; > } > - > + > if (encrypted) { > aes_key = get_aes_key(); > ivt = get_aes_ivt(); > Acked-by: Stefano Babic <sbabic@denx.de> Best regards, Stefano Babic
diff --git a/core/cpio_utils.c b/core/cpio_utils.c index 40ae474..0be31e6 100644 --- a/core/cpio_utils.c +++ b/core/cpio_utils.c @@ -135,7 +135,7 @@ static int input_step(void *state, void *buffer, size_t size) size = s->nbytes; } int ret = fill_buffer(s->fdin, buffer, size, s->offs, &s->checksum, s->dgst); - if (ret < 0) { + if (ret <= 0) { return ret; } s->nbytes -= size; @@ -173,6 +173,8 @@ static int decrypt_step(void *state, void *buffer, size_t size) ret = s->upstream_step(s->upstream_state, s->input, sizeof s->input); if (ret < 0) { return ret; + } else if (ret == 0) { + s->eof = true; } inlen = ret; @@ -234,6 +236,8 @@ static int gunzip_step(void *state, void *buffer, size_t size) ret = s->upstream_step(s->upstream_state, s->input, sizeof s->input); if (ret < 0) { return ret; + } else if (ret == 0) { + s->eof = true; } s->strm.avail_in = ret; s->strm.next_in = s->input; @@ -317,7 +321,7 @@ int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsi if (!input_state.dgst) return -EFAULT; } - + if (encrypted) { aes_key = get_aes_key(); ivt = get_aes_ivt();