Date: Wed, 25 Nov 2020 00:10:55 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368005 - in head: lib/libprocstat share/man/man4 sys/opencrypto sys/sys tools/tools/crypto usr.bin/procstat Message-ID: <202011250010.0AP0AtH3061986@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Wed Nov 25 00:10:54 2020 New Revision: 368005 URL: https://svnweb.freebsd.org/changeset/base/368005 Log: Remove the cloned file descriptors for /dev/crypto. Crypto file descriptors were added in the original OCF import as a way to provide per-open data (specifically the list of symmetric sessions). However, this gives a bit of a confusing API where one has to open /dev/crypto and then invoke an ioctl to obtain a second file descriptor. This also does not match the API used with /dev/crypto on other BSDs or with Linux's /dev/crypto driver. Character devices have gained support for per-open data via cdevpriv since OCF was imported, so use cdevpriv to simplify the userland API by permitting ioctls directly on /dev/crypto descriptors. To provide backwards compatibility, CRIOGET now opens another /dev/crypto descriptor via kern_openat() rather than dup'ing the existing file descriptor. This preserves prior semantics in case CRIOGET is invoked multiple times on a single file descriptor. Reviewed by: markj Relnotes: yes Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D27302 Modified: head/lib/libprocstat/libprocstat.c head/lib/libprocstat/libprocstat.h head/share/man/man4/crypto.4 head/sys/opencrypto/cryptodev.c head/sys/opencrypto/cryptodev.h head/sys/sys/user.h head/tools/tools/crypto/cryptocheck.c head/usr.bin/procstat/procstat.1 head/usr.bin/procstat/procstat_files.c Modified: head/lib/libprocstat/libprocstat.c ============================================================================== --- head/lib/libprocstat/libprocstat.c Tue Nov 24 23:56:33 2020 (r368004) +++ head/lib/libprocstat/libprocstat.c Wed Nov 25 00:10:54 2020 (r368005) @@ -708,7 +708,6 @@ kinfo_type2fst(int kftype) int fst_type; } kftypes2fst[] = { { KF_TYPE_PROCDESC, PS_FST_TYPE_PROCDESC }, - { KF_TYPE_CRYPTO, PS_FST_TYPE_CRYPTO }, { KF_TYPE_DEV, PS_FST_TYPE_DEV }, { KF_TYPE_FIFO, PS_FST_TYPE_FIFO }, { KF_TYPE_KQUEUE, PS_FST_TYPE_KQUEUE }, Modified: head/lib/libprocstat/libprocstat.h ============================================================================== --- head/lib/libprocstat/libprocstat.h Tue Nov 24 23:56:33 2020 (r368004) +++ head/lib/libprocstat/libprocstat.h Wed Nov 25 00:10:54 2020 (r368005) @@ -64,7 +64,7 @@ #define PS_FST_TYPE_PIPE 4 #define PS_FST_TYPE_PTS 5 #define PS_FST_TYPE_KQUEUE 6 -#define PS_FST_TYPE_CRYPTO 7 +/* was PS_FST_TYPE_CRYPTO 7 */ #define PS_FST_TYPE_MQUEUE 8 #define PS_FST_TYPE_SHM 9 #define PS_FST_TYPE_SEM 10 Modified: head/share/man/man4/crypto.4 ============================================================================== --- head/share/man/man4/crypto.4 Tue Nov 24 23:56:33 2020 (r368004) +++ head/share/man/man4/crypto.4 Wed Nov 25 00:10:54 2020 (r368005) @@ -60,7 +60,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 6, 2020 +.Dd November 24, 2020 .Dt CRYPTO 4 .Os .Sh NAME @@ -122,19 +122,11 @@ Open the .Pa /dev/crypto device. .It -Create a new cryptography file descriptor via -.Dv CRIOGET -to use for all subsequent -.Xr ioctl 2 -commands. -.It -Close the -.Pa /dev/crypto -device. -.It If any symmetric-keyed cryptographic or digest operations will be performed, create a session with -.Dv CIOCGSESSION . +.Dv CIOCGSESSION +or +.Dv CIOCGSESSION2 . Most applications will require at least one symmetric session. Since cipher and MAC keys are tied to sessions, many applications will require more. @@ -152,8 +144,9 @@ or Optionally destroy a session with .Dv CIOCFSESSION . .It -Close the cryptography file descriptor with -.Xr close 2 . +Close the +.Pa /dev/crypto +device. This will automatically close any remaining sessions associated with the file desriptor. .El @@ -458,11 +451,3 @@ session: if you request a algorithm, you must supply a suitably-sized buffer. .Pp The scheme for passing arguments for asymmetric requests is baroque. -.Pp -.Dv CRIOGET -should not exist. -It should be possible to use the -.Dv CIOC Ns \&* -commands directly on a -.Pa /dev/crypto -file descriptor. Modified: head/sys/opencrypto/cryptodev.c ============================================================================== --- head/sys/opencrypto/cryptodev.c Tue Nov 24 23:56:33 2020 (r368004) +++ head/sys/opencrypto/cryptodev.c Wed Nov 25 00:10:54 2020 (r368005) @@ -47,9 +47,8 @@ __FBSDID("$FreeBSD$"); #include <sys/mbuf.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/proc.h> #include <sys/sysctl.h> -#include <sys/file.h> -#include <sys/filedesc.h> #include <sys/errno.h> #include <sys/random.h> #include <sys/conf.h> @@ -57,8 +56,8 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/fcntl.h> #include <sys/bus.h> -#include <sys/user.h> #include <sys/sdt.h> +#include <sys/syscallsubr.h> #include <opencrypto/cryptodev.h> #include <opencrypto/xform.h> @@ -67,6 +66,17 @@ SDT_PROVIDER_DECLARE(opencrypto); SDT_PROBE_DEFINE1(opencrypto, dev, ioctl, error, "int"/*line number*/); +#ifdef COMPAT_FREEBSD12 +/* + * Previously, most ioctls were performed against a cloned descriptor + * of /dev/crypto obtained via CRIOGET. Now all ioctls are performed + * against /dev/crypto directly. + */ +#define CRIOGET _IOWR('c', 100, uint32_t) +#endif + +/* the following are done against the cloned descriptor */ + #ifdef COMPAT_FREEBSD32 #include <sys/mount.h> #include <compat/freebsd32/freebsd32.h> @@ -351,29 +361,6 @@ SYSCTL_TIMEVAL_SEC(_kern, OID_AUTO, cryptodev_warn_int &warninterval, "Delay in seconds between warnings of deprecated /dev/crypto algorithms"); -static int cryptof_ioctl(struct file *, u_long, void *, struct ucred *, - struct thread *); -static int cryptof_stat(struct file *, struct stat *, struct ucred *, - struct thread *); -static int cryptof_close(struct file *, struct thread *); -static int cryptof_fill_kinfo(struct file *, struct kinfo_file *, - struct filedesc *); - -static struct fileops cryptofops = { - .fo_read = invfo_rdwr, - .fo_write = invfo_rdwr, - .fo_truncate = invfo_truncate, - .fo_ioctl = cryptof_ioctl, - .fo_poll = invfo_poll, - .fo_kqfilter = invfo_kqfilter, - .fo_stat = cryptof_stat, - .fo_close = cryptof_close, - .fo_chmod = invfo_chmod, - .fo_chown = invfo_chown, - .fo_sendfile = invfo_sendfile, - .fo_fill_kinfo = cryptof_fill_kinfo, -}; - /* * Check a crypto identifier to see if it requested * a software device/driver. This can be done either @@ -762,7 +749,7 @@ cse_delete(struct fcrypt *fcr, u_int ses) } static struct cryptop_data * -cod_alloc(struct csession *cse, size_t aad_len, size_t len, struct thread *td) +cod_alloc(struct csession *cse, size_t aad_len, size_t len) { struct cryptop_data *cod; @@ -808,8 +795,7 @@ cryptodev_cb(struct cryptop *crp) } static int -cryptodev_op(struct csession *cse, const struct crypt_op *cop, - struct ucred *active_cred, struct thread *td) +cryptodev_op(struct csession *cse, const struct crypt_op *cop) { struct cryptop_data *cod = NULL; struct cryptop *crp = NULL; @@ -845,7 +831,7 @@ cryptodev_op(struct csession *cse, const struct crypt_ } } - cod = cod_alloc(cse, 0, cop->len + cse->hashsize, td); + cod = cod_alloc(cse, 0, cop->len + cse->hashsize); dst = cop->dst; crp = crypto_getreq(cse->cses, M_WAITOK); @@ -1019,8 +1005,7 @@ bail: } static int -cryptodev_aead(struct csession *cse, struct crypt_aead *caead, - struct ucred *active_cred, struct thread *td) +cryptodev_aead(struct csession *cse, struct crypt_aead *caead) { struct cryptop_data *cod = NULL; struct cryptop *crp = NULL; @@ -1050,7 +1035,7 @@ cryptodev_aead(struct csession *cse, struct crypt_aead } } - cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize, td); + cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize); dst = caead->dst; crp = crypto_getreq(cse->cses, M_WAITOK); @@ -1358,12 +1343,44 @@ cryptodev_find(struct crypt_find_op *find) return (0); } +static void +fcrypt_dtor(void *data) +{ + struct fcrypt *fcr = data; + struct csession *cse; + + while ((cse = TAILQ_FIRST(&fcr->csessions))) { + TAILQ_REMOVE(&fcr->csessions, cse, next); + KASSERT(refcount_load(&cse->refs) == 1, + ("%s: crypto session %p with %d refs", __func__, cse, + refcount_load(&cse->refs))); + cse_free(cse); + } + mtx_destroy(&fcr->lock); + free(fcr, M_XDATA); +} + static int -cryptof_ioctl(struct file *fp, u_long cmd, void *data, - struct ucred *active_cred, struct thread *td) +crypto_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { + struct fcrypt *fcr; + int error; + + fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK | M_ZERO); + TAILQ_INIT(&fcr->csessions); + mtx_init(&fcr->lock, "fcrypt", NULL, MTX_DEF); + error = devfs_set_cdevpriv(fcr, fcrypt_dtor); + if (error) + fcrypt_dtor(fcr); + return (error); +} + +static int +crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, + struct thread *td) +{ static struct timeval keywarn, featwarn; - struct fcrypt *fcr = fp->f_data; + struct fcrypt *fcr; struct csession *cse; struct session2_op *sop; struct crypt_op *cop; @@ -1390,14 +1407,14 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data, cmd32 = cmd; data32 = data; cmd = CIOCGSESSION; - data = &thunk.sopc; + data = (void *)&thunk.sopc; session_op_from_32((struct session_op32 *)data32, &thunk.sopc); break; case CIOCGSESSION232: cmd32 = cmd; data32 = data; cmd = CIOCGSESSION2; - data = &thunk.sopc; + data = (void *)&thunk.sopc; session2_op_from_32((struct session2_op32 *)data32, &thunk.sopc); break; @@ -1405,14 +1422,14 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data, cmd32 = cmd; data32 = data; cmd = CIOCCRYPT; - data = &thunk.copc; + data = (void *)&thunk.copc; crypt_op_from_32((struct crypt_op32 *)data32, &thunk.copc); break; case CIOCCRYPTAEAD32: cmd32 = cmd; data32 = data; cmd = CIOCCRYPTAEAD; - data = &thunk.aeadc; + data = (void *)&thunk.aeadc; crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc); break; case CIOCKEY32: @@ -1423,24 +1440,41 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data, cmd = CIOCKEY; else cmd = CIOCKEY2; - data = &thunk.kopc; + data = (void *)&thunk.kopc; crypt_kop_from_32((struct crypt_kop32 *)data32, &thunk.kopc); break; } #endif + devfs_get_cdevpriv((void **)&fcr); + switch (cmd) { +#ifdef COMPAT_FREEBSD12 + case CRIOGET: + /* + * NB: This may fail in cases that the old + * implementation did not if the current process has + * restricted filesystem access (e.g. running in a + * jail that does not expose /dev/crypto or in + * capability mode). + */ + error = kern_openat(td, AT_FDCWD, "/dev/crypto", UIO_SYSSPACE, + O_RDWR, 0); + if (error == 0) + *(uint32_t *)data = td->td_retval[0]; + break; +#endif case CIOCGSESSION: case CIOCGSESSION2: if (cmd == CIOCGSESSION) { - session2_op_from_op(data, &thunk.sopc); + session2_op_from_op((void *)data, &thunk.sopc); sop = &thunk.sopc; } else sop = (struct session2_op *)data; error = cse_create(fcr, sop); if (cmd == CIOCGSESSION && error == 0) - session2_op_to_op(sop, data); + session2_op_to_op(sop, (void *)data); break; case CIOCFSESSION: ses = *(uint32_t *)data; @@ -1456,7 +1490,7 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data, SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } - error = cryptodev_op(cse, cop, active_cred, td); + error = cryptodev_op(cse, cop); cse_free(cse); break; case CIOCKEY: @@ -1509,7 +1543,7 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data, SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } - error = cryptodev_aead(cse, caead, active_cred, td); + error = cryptodev_aead(cse, caead); cse_free(cse); break; default: @@ -1522,109 +1556,33 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data, switch (cmd32) { case CIOCGSESSION32: if (error == 0) - session_op_to_32(data, data32); + session_op_to_32((void *)data, data32); break; case CIOCGSESSION232: if (error == 0) - session2_op_to_32(data, data32); + session2_op_to_32((void *)data, data32); break; case CIOCCRYPT32: if (error == 0) - crypt_op_to_32(data, data32); + crypt_op_to_32((void *)data, data32); break; case CIOCCRYPTAEAD32: if (error == 0) - crypt_aead_to_32(data, data32); + crypt_aead_to_32((void *)data, data32); break; case CIOCKEY32: case CIOCKEY232: - crypt_kop_to_32(data, data32); + crypt_kop_to_32((void *)data, data32); break; } #endif return (error); } -/* ARGSUSED */ -static int -cryptof_stat(struct file *fp, struct stat *sb, struct ucred *active_cred, - struct thread *td) -{ - - return (EOPNOTSUPP); -} - -/* ARGSUSED */ -static int -cryptof_close(struct file *fp, struct thread *td) -{ - struct fcrypt *fcr = fp->f_data; - struct csession *cse; - - while ((cse = TAILQ_FIRST(&fcr->csessions))) { - TAILQ_REMOVE(&fcr->csessions, cse, next); - KASSERT(cse->refs == 1, - ("%s: crypto session %p with %d refs", __func__, cse, - cse->refs)); - cse_free(cse); - } - free(fcr, M_XDATA); - fp->f_data = NULL; - return 0; -} - -static int -cryptof_fill_kinfo(struct file *fp, struct kinfo_file *kif, - struct filedesc *fdp) -{ - - kif->kf_type = KF_TYPE_CRYPTO; - return (0); -} - -static int -cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, - struct thread *td) -{ - struct file *f; - struct fcrypt *fcr; - int fd, error; - - switch (cmd) { - case CRIOGET: - error = falloc_noinstall(td, &f); - if (error) - break; - - fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK | M_ZERO); - TAILQ_INIT(&fcr->csessions); - mtx_init(&fcr->lock, "fcrypt", NULL, MTX_DEF); - - finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops); - error = finstall(td, f, &fd, 0, NULL); - if (error) { - mtx_destroy(&fcr->lock); - free(fcr, M_XDATA); - } else - *(uint32_t *)data = fd; - fdrop(f, td); - break; - case CRIOFINDDEV: - error = cryptodev_find((struct crypt_find_op *)data); - break; - case CRIOASYMFEAT: - error = crypto_getfeat((int *)data); - break; - default: - error = EINVAL; - break; - } - return (error); -} - static struct cdevsw crypto_cdevsw = { .d_version = D_VERSION, - .d_ioctl = cryptoioctl, + .d_open = crypto_open, + .d_ioctl = crypto_ioctl, .d_name = "crypto", }; static struct cdev *crypto_dev; Modified: head/sys/opencrypto/cryptodev.h ============================================================================== --- head/sys/opencrypto/cryptodev.h Tue Nov 24 23:56:33 2020 (r368004) +++ head/sys/opencrypto/cryptodev.h Wed Nov 25 00:10:54 2020 (r368005) @@ -316,15 +316,6 @@ struct crypt_kop { #define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY) #define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY) -/* - * done against open of /dev/crypto, to get a cloned descriptor. - * Please use F_SETFD against the cloned descriptor. - */ -#define CRIOGET _IOWR('c', 100, uint32_t) -#define CRIOASYMFEAT CIOCASYMFEAT -#define CRIOFINDDEV CIOCFINDDEV - -/* the following are done against the cloned descriptor */ #define CIOCGSESSION _IOWR('c', 101, struct session_op) #define CIOCFSESSION _IOW('c', 102, uint32_t) #define CIOCCRYPT _IOWR('c', 103, struct crypt_op) Modified: head/sys/sys/user.h ============================================================================== --- head/sys/sys/user.h Tue Nov 24 23:56:33 2020 (r368004) +++ head/sys/sys/user.h Wed Nov 25 00:10:54 2020 (r368005) @@ -257,7 +257,7 @@ struct user { #define KF_TYPE_PIPE 3 #define KF_TYPE_FIFO 4 #define KF_TYPE_KQUEUE 5 -#define KF_TYPE_CRYPTO 6 +/* was KF_TYPE_CRYPTO 6 */ #define KF_TYPE_MQUEUE 7 #define KF_TYPE_SHM 8 #define KF_TYPE_SEM 9 Modified: head/tools/tools/crypto/cryptocheck.c ============================================================================== --- head/tools/tools/crypto/cryptocheck.c Tue Nov 24 23:56:33 2020 (r368004) +++ head/tools/tools/crypto/cryptocheck.c Wed Nov 25 00:10:54 2020 (r368005) @@ -352,23 +352,11 @@ crfind(int crid) bzero(&find, sizeof(find)); find.crid = crid; - if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1) + if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1) err(1, "ioctl(CIOCFINDDEV): crid %d", crid); return (find.name); } -static int -crget(void) -{ - int fd; - - if (ioctl(devcrypto(), CRIOGET, &fd) == -1) - err(1, "ioctl(CRIOGET)"); - if (fcntl(fd, F_SETFD, 1) == -1) - err(1, "fcntl(F_SETFD) (crget)"); - return fd; -} - static char rdigit(void) { @@ -436,11 +424,10 @@ ocf_init_session(struct session2_op *sop, const char * { int fd; - fd = crget(); + fd = devcrypto(); if (ioctl(fd, CIOCGSESSION2, sop) < 0) { warn("cryptodev %s %s not supported for device %s", type, name, crfind(sop->crid)); - close(fd); ses->fd = -1; return (false); } @@ -458,8 +445,6 @@ ocf_destroy_session(struct ocf_session *ses) if (ioctl(ses->fd, CIOCFSESSION, &ses->ses) < 0) warn("ioctl(CIOCFSESSION)"); - - close(ses->fd); } static void Modified: head/usr.bin/procstat/procstat.1 ============================================================================== --- head/usr.bin/procstat/procstat.1 Tue Nov 24 23:56:33 2020 (r368004) +++ head/usr.bin/procstat/procstat.1 Wed Nov 25 00:10:54 2020 (r368005) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 5, 2020 +.Dd November 24, 2020 .Dt PROCSTAT 1 .Os .Sh NAME @@ -311,8 +311,6 @@ file path or socket addresses (if available) The following file descriptor types may be displayed: .Pp .Bl -tag -width X -compact -.It c -crypto .It e POSIX semaphore .It f Modified: head/usr.bin/procstat/procstat_files.c ============================================================================== --- head/usr.bin/procstat/procstat_files.c Tue Nov 24 23:56:33 2020 (r368004) +++ head/usr.bin/procstat/procstat_files.c Wed Nov 25 00:10:54 2020 (r368005) @@ -384,11 +384,6 @@ procstat_files(struct procstat *procstat, struct kinfo xo_emit("{eq:fd_type/kqueue}"); break; - case PS_FST_TYPE_CRYPTO: - str = "c"; - xo_emit("{eq:fd_type/crypto}"); - break; - case PS_FST_TYPE_MQUEUE: str = "m"; xo_emit("{eq:fd_type/mqueue}");
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011250010.0AP0AtH3061986>