Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177434047
D59238.1794378795.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
3 KB
Referenced Files
None
Subscribers
None
D59238.1794378795.diff
View Options
Index: sys/dev/tpm/tpm.c
===================================================================
--- sys/dev/tpm/tpm.c
+++ sys/dev/tpm/tpm.c
@@ -40,6 +40,7 @@
#include <isa/isavar.h>
#include <dev/tpm/tpmvar.h>
+MALLOC_DEFINE(M_TPM, "tpm12_buffer", "buffer for TPM 1.2 responses");
#define TPM_BUFSIZ 1024
@@ -1472,13 +1473,14 @@
tpmread(struct cdev *dev, struct uio *uio, int flags)
{
struct tpm_softc *sc;
- u_int8_t buf[TPM_BUFSIZ], *p;
- size_t cnt;
- int end_error, len, n, rv;
+ u_int8_t header[TPM_HDRSIZE], *buf;
+ size_t cnt, len;
+ int end_error, rv;
sc = TPMSOFTC(dev);
if (sc == NULL)
return (ENXIO);
+ buf = NULL;
sx_xlock(&sc->sc_lock);
if (sc->sc_dying) {
@@ -1496,39 +1498,42 @@
#ifdef TPM_DEBUG
printf("tpmread: getting header\n");
#endif
- rv = sc->sc_read(sc, buf, TPM_HDRSIZE, &cnt, 0);
+ rv = sc->sc_read(sc, header, sizeof(header), &cnt,
+ TPM_PARAM_SIZE);
if (rv != 0)
goto end;
+ if (cnt != sizeof(header)) {
+ rv = EIO;
+ goto end;
+ }
- len = (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | buf[5];
+ len = be32dec(header + 2);
#ifdef TPM_DEBUG
- printf("tpmread: len %d, io count %d\n", len, uio->uio_resid);
+ printf("tpmread: len %zu, io count %zd\n", len, uio->uio_resid);
#endif
- if (len > uio->uio_resid) {
+ if (len < sizeof(header) || len > uio->uio_resid || len > INT_MAX) {
rv = EIO;
#ifdef TPM_DEBUG
- printf("tpmread: bad residual io count 0x%x\n", uio->uio_resid);
+ printf("tpmread: invalid response length %zu\n", len);
#endif
goto end;
}
- /* Copy out header. */
- rv = uiomove((caddr_t)buf, cnt, uio);
- if (rv != 0)
+ /*
+ * Finish the device transaction before touching user memory. Use a
+ * non-blocking allocation so lifecycle operations are not held up by
+ * memory pressure while waiting for the transaction lock.
+ */
+ buf = malloc(len, M_TPM, M_NOWAIT);
+ if (buf == NULL) {
+ rv = ENOMEM;
goto end;
+ }
+ memcpy(buf, header, sizeof(header));
- /* Get remaining part of the answer (if anything is left). */
- for (len -= cnt, p = buf, n = sizeof(buf); len > 0; p = buf, len -= n,
- n = sizeof(buf)) {
- n = MIN(n, len);
-#ifdef TPM_DEBUG
- printf("tpmread: n %d len %d\n", n, len);
-#endif
- rv = sc->sc_read(sc, p, n, NULL, TPM_PARAM_SIZE);
- if (rv != 0)
- goto end;
- p += n;
- rv = uiomove((caddr_t)buf, p - buf, uio);
+ if (len > sizeof(header)) {
+ rv = sc->sc_read(sc, buf + sizeof(header),
+ (int)(len - sizeof(header)), NULL, TPM_PARAM_SIZE);
if (rv != 0)
goto end;
}
@@ -1539,6 +1544,9 @@
rv = end_error;
out:
sx_xunlock(&sc->sc_lock);
+ if (rv == 0)
+ rv = uiomove(buf, (int)len, uio);
+ free(buf, M_TPM);
return (rv);
}
@@ -1552,6 +1560,12 @@
sc = TPMSOFTC(dev);
if (sc == NULL)
return (ENXIO);
+
+ n = MIN(sizeof(buf), uio->uio_resid);
+ rv = uiomove(buf, n, uio);
+ if (rv != 0)
+ return (rv);
+
sx_xlock(&sc->sc_lock);
if (sc->sc_dying) {
rv = ENXIO;
@@ -1563,14 +1577,9 @@
}
#ifdef TPM_DEBUG
- printf("tpmwrite: io count %d\n", uio->uio_resid);
+ printf("tpmwrite: io count %d\n", n);
#endif
- n = MIN(sizeof(buf), uio->uio_resid);
- rv = uiomove((caddr_t)buf, n, uio);
- if (rv != 0)
- goto out;
-
rv = sc->sc_start(sc, UIO_WRITE);
if (rv != 0)
goto out;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 11, 6:33 AM (8 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41654823
Default Alt Text
D59238.1794378795.diff (3 KB)
Attached To
Mode
D59238: tpm: Move user copies outside the TPM 1.2 lock
Attached
Detach File
Event Timeline