Don't access a user buffer directly from the kernel.
The handle_string callback for the ENCIOC_SETSTRING ioctl was passing a user pointer to memcpy(). Fix by using copyin() instead. For ENCIOC_GETSTRING ioctls, the handler was storing the user pointer in a CCB's data_ptr field where it was indirected by other code. Fix this by allocating a temporary buffer (which ENCIOC_SETSTRING already did) and copying the result out to the user buffer after the CCB has been processed. Reviewed by: kib Obtained from: CheriBSD MFC after: 1 week Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D24487
This commit is contained in:
parent
5253de2d05
commit
cf8fb4efb7
@ -2904,13 +2904,19 @@ ses_handle_string(enc_softc_t *enc, encioc_string_t *sstr, int ioc)
|
||||
buf[1] = 0;
|
||||
buf[2] = sstr->bufsiz >> 8;
|
||||
buf[3] = sstr->bufsiz & 0xff;
|
||||
memcpy(&buf[4], sstr->buf, sstr->bufsiz);
|
||||
ret = copyin(sstr->buf, &buf[4], sstr->bufsiz);
|
||||
if (ret != 0) {
|
||||
ENC_FREE(buf);
|
||||
return (ret);
|
||||
}
|
||||
break;
|
||||
case ENCIOC_GETSTRING:
|
||||
payload = sstr->bufsiz;
|
||||
amt = payload;
|
||||
buf = ENC_MALLOC(payload);
|
||||
if (buf == NULL)
|
||||
return (ENOMEM);
|
||||
ses_page_cdb(cdb, payload, SesStringIn, CAM_DIR_IN);
|
||||
buf = sstr->buf;
|
||||
break;
|
||||
case ENCIOC_GETENCNAME:
|
||||
if (ses_cache->ses_nsubencs < 1)
|
||||
@ -2950,6 +2956,8 @@ ses_handle_string(enc_softc_t *enc, encioc_string_t *sstr, int ioc)
|
||||
return (EINVAL);
|
||||
}
|
||||
ret = enc_runcmd(enc, cdb, 6, buf, &amt);
|
||||
if (ret == 0 && ioc == ENCIOC_GETSTRING)
|
||||
ret = copyout(buf, sstr->buf, sstr->bufsiz);
|
||||
if (ioc == ENCIOC_SETSTRING)
|
||||
ENC_FREE(buf);
|
||||
return (ret);
|
||||
|
Loading…
Reference in New Issue
Block a user