diff options
author | mav <mav@FreeBSD.org> | 2014-07-05 14:32:42 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-07-05 14:32:42 +0000 |
commit | 6a3d6f39825c967975be57c4826c2a2c91803940 (patch) | |
tree | b3bd61abf4959a5fd0aa9484d9141b8715dc3bad | |
parent | cd2bf77221bc5ca0b3bc700494ceb7267a9c276c (diff) | |
download | FreeBSD-src-6a3d6f39825c967975be57c4826c2a2c91803940.zip FreeBSD-src-6a3d6f39825c967975be57c4826c2a2c91803940.tar.gz |
Improve CTL_BEARG_* flags support, including optional values copyout.
-rw-r--r-- | sys/cam/ctl/ctl.c | 64 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_backend.c | 4 |
2 files changed, 43 insertions, 25 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 126dbf2..cb41bf5 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -2013,40 +2013,40 @@ ctl_copyin_alloc(void *user_addr, int len, char *error_str, } static void -ctl_free_args(int num_be_args, struct ctl_be_arg *be_args) +ctl_free_args(int num_args, struct ctl_be_arg *args) { int i; - if (be_args == NULL) + if (args == NULL) return; - for (i = 0; i < num_be_args; i++) { - free(be_args[i].kname, M_CTL); - free(be_args[i].kvalue, M_CTL); + for (i = 0; i < num_args; i++) { + free(args[i].kname, M_CTL); + free(args[i].kvalue, M_CTL); } - free(be_args, M_CTL); + free(args, M_CTL); } static struct ctl_be_arg * -ctl_copyin_args(int num_be_args, struct ctl_be_arg *be_args, +ctl_copyin_args(int num_args, struct ctl_be_arg *uargs, char *error_str, size_t error_str_len) { struct ctl_be_arg *args; int i; - args = ctl_copyin_alloc(be_args, num_be_args * sizeof(*be_args), + args = ctl_copyin_alloc(uargs, num_args * sizeof(*args), error_str, error_str_len); if (args == NULL) goto bailout; - for (i = 0; i < num_be_args; i++) { + for (i = 0; i < num_args; i++) { args[i].kname = NULL; args[i].kvalue = NULL; } - for (i = 0; i < num_be_args; i++) { + for (i = 0; i < num_args; i++) { uint8_t *tmpptr; args[i].kname = ctl_copyin_alloc(args[i].name, @@ -2060,31 +2060,43 @@ ctl_copyin_args(int num_be_args, struct ctl_be_arg *be_args, goto bailout; } - args[i].kvalue = NULL; - - tmpptr = ctl_copyin_alloc(args[i].value, - args[i].vallen, error_str, error_str_len); - if (tmpptr == NULL) - goto bailout; - - args[i].kvalue = tmpptr; - - if ((args[i].flags & CTL_BEARG_ASCII) - && (tmpptr[args[i].vallen - 1] != '\0')) { - snprintf(error_str, error_str_len, "Argument %d " - "value is not NUL-terminated", i); - goto bailout; + if (args[i].flags & CTL_BEARG_RD) { + tmpptr = ctl_copyin_alloc(args[i].value, + args[i].vallen, error_str, error_str_len); + if (tmpptr == NULL) + goto bailout; + if ((args[i].flags & CTL_BEARG_ASCII) + && (tmpptr[args[i].vallen - 1] != '\0')) { + snprintf(error_str, error_str_len, "Argument " + "%d value is not NUL-terminated", i); + goto bailout; + } + args[i].kvalue = tmpptr; + } else { + args[i].kvalue = malloc(args[i].vallen, + M_CTL, M_WAITOK | M_ZERO); } } return (args); bailout: - ctl_free_args(num_be_args, args); + ctl_free_args(num_args, args); return (NULL); } +static void +ctl_copyout_args(int num_args, struct ctl_be_arg *args) +{ + int i; + + for (i = 0; i < num_args; i++) { + if (args[i].flags & CTL_BEARG_WR) + copyout(args[i].kvalue, args[i].value, args[i].vallen); + } +} + /* * Escape characters that are illegal or not recommended in XML. */ @@ -2945,6 +2957,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, retval = backend->ioctl(dev, cmd, addr, flag, td); if (lun_req->num_be_args > 0) { + ctl_copyout_args(lun_req->num_be_args, + lun_req->kern_be_args); ctl_free_args(lun_req->num_be_args, lun_req->kern_be_args); } diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c index 9178c9d..0e1a76c 100644 --- a/sys/cam/ctl/ctl_backend.c +++ b/sys/cam/ctl/ctl_backend.c @@ -181,6 +181,10 @@ ctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args) STAILQ_INIT(opts); for (i = 0; i < num_args; i++) { + if ((args[i].flags & CTL_BEARG_RD) == 0) + continue; + if ((args[i].flags & CTL_BEARG_ASCII) == 0) + continue; opt = malloc(sizeof(*opt), M_CTL, M_WAITOK); opt->name = malloc(strlen(args[i].kname) + 1, M_CTL, M_WAITOK); strcpy(opt->name, args[i].kname); |