summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Stange <nicstange@gmail.com>2016-05-26 17:19:51 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2016-05-31 04:41:59 -0400
commit03cdfaad491e82e4a66593c6e149ddae0421df59 (patch)
treed117afc69edfe44a4f0fb77798e4a73351b51481
parenteef0df6a59537032ab6b708f30b28d9530f8760e (diff)
lib/mpi: mpi_read_from_buffer(): return error code
mpi_read_from_buffer() reads a MPI from a buffer into a newly allocated MPI instance. It expects the buffer's leading two bytes to contain the number of bits, followed by the actual payload. On failure, it returns NULL and updates the in/out argument ret_nread somewhat inconsistently: - If the given buffer is too short to contain the leading two bytes encoding the number of bits or their value is unsupported, then ret_nread will be cleared. - If the allocation of the resulting MPI instance fails, ret_nread is left as is. The only user of mpi_read_from_buffer(), digsig_verify_rsa(), simply checks for a return value of NULL and returns -ENOMEM if that happens. While this is all of cosmetic nature only, there is another error condition which currently isn't detectable by the caller of mpi_read_from_buffer(): if the given buffer is too small to hold the number of bits as encoded in its first two bytes, the return value will be non-NULL and *ret_nread > 0. In preparation of communicating this condition to the caller, let mpi_read_from_buffer() return error values by means of the ERR_PTR() mechanism. Make the sole caller of mpi_read_from_buffer(), digsig_verify_rsa(), check the return value for IS_ERR() rather than == NULL. If IS_ERR() is true, return the associated error value rather than the fixed -ENOMEM. Signed-off-by: Nicolai Stange <nicstange@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--lib/digsig.c12
-rw-r--r--lib/mpi/mpicoder.c6
2 files changed, 11 insertions, 7 deletions
diff --git a/lib/digsig.c b/lib/digsig.c
index 07be6c1ef4e2..a121cbc5a46b 100644
--- a/lib/digsig.c
+++ b/lib/digsig.c
@@ -104,16 +104,18 @@ static int digsig_verify_rsa(struct key *key,
104 datap = pkh->mpi; 104 datap = pkh->mpi;
105 endp = ukp->data + ukp->datalen; 105 endp = ukp->data + ukp->datalen;
106 106
107 err = -ENOMEM;
108
109 for (i = 0; i < pkh->nmpi; i++) { 107 for (i = 0; i < pkh->nmpi; i++) {
110 unsigned int remaining = endp - datap; 108 unsigned int remaining = endp - datap;
111 pkey[i] = mpi_read_from_buffer(datap, &remaining); 109 pkey[i] = mpi_read_from_buffer(datap, &remaining);
112 if (!pkey[i]) 110 if (IS_ERR(pkey[i])) {
111 err = PTR_ERR(pkey[i]);
113 goto err; 112 goto err;
113 }
114 datap += remaining; 114 datap += remaining;
115 } 115 }
116 116
117 err = -ENOMEM;
118
117 mblen = mpi_get_nbits(pkey[0]); 119 mblen = mpi_get_nbits(pkey[0]);
118 mlen = DIV_ROUND_UP(mblen, 8); 120 mlen = DIV_ROUND_UP(mblen, 8);
119 121
@@ -126,8 +128,10 @@ static int digsig_verify_rsa(struct key *key,
126 128
127 nret = siglen; 129 nret = siglen;
128 in = mpi_read_from_buffer(sig, &nret); 130 in = mpi_read_from_buffer(sig, &nret);
129 if (!in) 131 if (IS_ERR(in)) {
132 err = PTR_ERR(in);
130 goto err; 133 goto err;
134 }
131 135
132 res = mpi_alloc(mpi_get_nlimbs(in) * 2); 136 res = mpi_alloc(mpi_get_nlimbs(in) * 2);
133 if (!res) 137 if (!res)
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index eda34aba017e..350abaf4bee7 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -86,12 +86,12 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
86 MPI val = NULL; 86 MPI val = NULL;
87 87
88 if (*ret_nread < 2) 88 if (*ret_nread < 2)
89 goto leave; 89 return ERR_PTR(-EINVAL);
90 nbits = buffer[0] << 8 | buffer[1]; 90 nbits = buffer[0] << 8 | buffer[1];
91 91
92 if (nbits > MAX_EXTERN_MPI_BITS) { 92 if (nbits > MAX_EXTERN_MPI_BITS) {
93 pr_info("MPI: mpi too large (%u bits)\n", nbits); 93 pr_info("MPI: mpi too large (%u bits)\n", nbits);
94 goto leave; 94 return ERR_PTR(-EINVAL);
95 } 95 }
96 buffer += 2; 96 buffer += 2;
97 nread = 2; 97 nread = 2;
@@ -100,7 +100,7 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
100 nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); 100 nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
101 val = mpi_alloc(nlimbs); 101 val = mpi_alloc(nlimbs);
102 if (!val) 102 if (!val)
103 return NULL; 103 return ERR_PTR(-ENOMEM);
104 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; 104 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
105 i %= BYTES_PER_MPI_LIMB; 105 i %= BYTES_PER_MPI_LIMB;
106 val->nbits = nbits; 106 val->nbits = nbits;