diff options
| author | Warner Losh <imp@FreeBSD.org> | 2016-10-11 22:30:41 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2016-10-11 22:30:41 +0000 |
| commit | d49a5ddd040bbaec8d00ba055c342696fd9ee436 (patch) | |
| tree | f2ee2e1672980598d31a1dbc487a77e36dc7f375 /lib | |
| parent | f79d484dff6cb0e8249bb489572727bab7ecbcf1 (diff) | |
Notes
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile | 5 | ||||
| -rw-r--r-- | lib/libefi/Makefile | 23 | ||||
| -rw-r--r-- | lib/libefi/efi_getvar.c | 68 | ||||
| -rw-r--r-- | lib/libefi/efi_nextvarname.c | 66 | ||||
| -rw-r--r-- | lib/libefi/efi_setvar.c | 66 | ||||
| -rw-r--r-- | lib/libefi/libefi.3 | 143 | ||||
| -rw-r--r-- | lib/libefi/libefi.h | 57 | ||||
| -rw-r--r-- | lib/libefivar/Makefile | 53 | ||||
| -rw-r--r-- | lib/libefivar/efivar.3 | 98 | ||||
| -rw-r--r-- | lib/libefivar/efivar.c | 380 | ||||
| -rw-r--r-- | lib/libefivar/efivar.h | 121 | ||||
| -rw-r--r-- | lib/libefivar/libefivar.c (renamed from lib/libefi/libefi.c) | 128 | ||||
| -rw-r--r-- | lib/libefivar/libefivar_int.h (renamed from lib/libefi/libefi_int.h) | 9 |
13 files changed, 729 insertions, 488 deletions
diff --git a/lib/Makefile b/lib/Makefile index 486034e2f0c9b..5d45734f8039d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -49,6 +49,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \ libdevstat \ libdwarf \ libedit \ + ${_libefivar} \ ${_libelftc} \ libevent \ libexecinfo \ @@ -240,6 +241,10 @@ _libcxxrt= libcxxrt _libcplusplus= libc++ .endif +.if ${MACHINE_ARCH} == "amd64" +_libefivar= libefivar +.endif + .if ${MK_LIBTHR} != "no" _libthr= libthr .endif diff --git a/lib/libefi/Makefile b/lib/libefi/Makefile deleted file mode 100644 index d9862f061899a..0000000000000 --- a/lib/libefi/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# $FreeBSD$ - -.include <bsd.own.mk> - -PACKAGE=lib${LIB} -LIB= efi -SHLIB_MAJOR= 1 - -SRCS= libefi.c \ - efi_getvar.c \ - efi_nextvarname.c \ - efi_setvar.c - -CFLAGS+= -I${.CURDIR} - -INCS= libefi.h - -MAN+= libefi.3 -MLINKS+=libefi.3 efi_getvar.3 \ - libefi.3 efi_nextvarname.3 \ - libefi.3 efi_setvar.3 - -.include <bsd.lib.mk> diff --git a/lib/libefi/efi_getvar.c b/lib/libefi/efi_getvar.c deleted file mode 100644 index 97e842e7d5269..0000000000000 --- a/lib/libefi/efi_getvar.c +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libefi.h> -#include <stdlib.h> - -#include "libefi_int.h" - -/* - * EFI_STATUS - * GetVariable( - * IN CHAR16 *VariableName, - * IN EFI_GUID *VendorGuid, - * OUT UINT32 *Attributes OPTIONAL, - * IN OUT UINTN *DataSize, - * OUT VOID *Data - * ); - */ - -int -efi_getvar(char *name, uuid_t *vendor, uint32_t *attrib, size_t *datasize, - void *data) -{ - struct iodev_efivar_req req; - int error; - - req.namesize = 0; - error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name); - if (error) - return (error); - - req.vendor = *vendor; - req.datasize = *datasize; - req.data = data; - req.access = IODEV_EFIVAR_GETVAR; - error = libefi_efivar(&req); - *datasize = req.datasize; - if (!error && attrib != NULL) - *attrib = req.attrib; - free(req.name); - return (error); -} diff --git a/lib/libefi/efi_nextvarname.c b/lib/libefi/efi_nextvarname.c deleted file mode 100644 index e07659fd74f54..0000000000000 --- a/lib/libefi/efi_nextvarname.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libefi.h> -#include <stdlib.h> - -#include "libefi_int.h" - -/* - * EFI_STATUS - * GetNextVariableName( - * IN OUT UINTN *VariableNameSize, - * IN OUT CHAR16 *VariableName, - * IN OUT EFI_GUID *VendorGuid - * ); - */ - -int -efi_nextvarname(size_t *namesize, char *name, uuid_t *vendor) -{ - struct iodev_efivar_req req; - int error; - - req.namesize = *namesize; - error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name); - if (error) - return (error); - - req.vendor = *vendor; - req.access = IODEV_EFIVAR_NEXTNAME; - error = libefi_efivar(&req); - *namesize = req.namesize; - if (!error) { - error = libefi_ucs2_to_utf8(req.name, namesize, name); - if (!error) - *vendor = req.vendor; - } - free(req.name); - return (error); -} diff --git a/lib/libefi/efi_setvar.c b/lib/libefi/efi_setvar.c deleted file mode 100644 index be43694f2104c..0000000000000 --- a/lib/libefi/efi_setvar.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <libefi.h> -#include <stdlib.h> - -#include "libefi_int.h" - -/* - * EFI_STATUS - * SetVariable( - * IN CHAR16 *VariableName, - * IN EFI_GUID *VendorGuid, - * IN UINT32 Attributes, - * IN UINTN DataSize, - * IN VOID *Data - * ); - */ - -int -efi_setvar(char *name, uuid_t *vendor, uint32_t attrib, size_t datasize, - void *data) -{ - struct iodev_efivar_req req; - int error; - - req.namesize = 0; - error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name); - if (error) - return (error); - - req.vendor = *vendor; - req.attrib = attrib; - req.datasize = datasize; - req.data = data; - req.access = IODEV_EFIVAR_SETVAR; - error = libefi_efivar(&req); - free(req.name); - return (error); -} diff --git a/lib/libefi/libefi.3 b/lib/libefi/libefi.3 deleted file mode 100644 index e090fd6e711f7..0000000000000 --- a/lib/libefi/libefi.3 +++ /dev/null @@ -1,143 +0,0 @@ -.\"- -.\" Copyright (c) 2010 Marcel Moolenaar -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 29, 2010 -.Dt LIBEFI 3 -.Os -.Sh NAME -.Nm efi_getvar , efi_nextvarname , efi_setvar -.Nd "interface for accessing the EFI variable services" -.Sh LIBRARY -.Lb libefi -.Sh SYNOPSIS -.In libefi.h -.Ft int -.Fo efi_getvar -.Fa "char *name" "uuid_t *vendor" "uint32_t *attrib" -.Fa "size_t *datasize" "void *data" -.Fc -.Ft int -.Fn efi_nextvarname "size_t *namesize" "char *name" "uuid_t *vendor" -.Ft int -.Fo efi_setvar -.Fa "char *name" "uuid_t *vendor" "uint32_t attrib" -.Fa "size_t datasize" "void *data" -.Fc -.Sh DESCRIPTION -The -.Nm libefi -library provides access to a select set of the runtime services of the -Extensible Firmware Interface (EFI). -.Pp -The -.Fn efi_nextvarname -function is used to enumerate the variables. -The -.Fa namesize -parameter needs to be set to the size of the buffer pointed to by -.Fa name . -On return, -.Fa namesize -is set to the length of the variable name (including the terminating -.Ql \e0 ) -irrespective of whether the buffer was big enough. -The buffer pointed to by -.Fa name -contains the full or partial variable name on return. -Only on successful completion of the request is the -.Fa vendor -updated. -The values returned should be passed to successive calls to -.Fn efi_nextvarname -until all variables have been enumerated. -.Pp -The variable name and vendor as returned by -.Fn efi_nextvarname -can be passed to -.Fn efi_getvar -to obtain the value and attribute of the variable. -The buffer that is to contain the value is specified by -.Fa data -and the size of the buffer is given by -.Fa datasize . -The attribute pointed to by -.Fa attrib -consists of the bit values defined by the EFI specification. -.Pp -Variables can be created, modified and deleted using the -.Fn efi_setvar -function. -All new variables must be non-volatile and runtime accessible in -order for the request to succeed. -Note that for runtime accessable variables the boottime accessable bit must -be set as well. -To delete a variable, set -.Fa datasize -to 0. -.Pp -The vendor UUID is used to avoid collisions between variable names of -different vendors. -Variables created for use by -.Fx -should use the -.Dv EFI_FREEBSD_VARIABLE -UUID as defined in the -.In libefi.h -header file. -.Sh RETURN VALUES -Upon successful completion, these functions return 0. -Otherwise, the error number is returned. -These functions will fail if: -.Bl -tag -width Er -.It Bq Er EACCES -Insufficient permissions to access the EFI services. -.It Bq Er EILSEQ -The variable name is not in UTF-8. -.It Bq Er EINVAL -The request has invalid parameters. -.It Bq Er ENOENT -The variable does not exist or no more variables exist. -.It Bq Er ENOMEM -Temporary storage could not be allocated. -.It Bq Er EOVERFLOW -The variable name is too long or the data is too big to fit in -the buffer provided. -.El -.Sh SEE ALSO -.Xr errno 2 , -.Xr uuid 3 -.Sh HISTORY -The -.Nm libefi -library first appeared in -.Fx 9.0 -for the ia64 architecture. -.Sh AUTHORS -The -.Nm libefi -library and this manual page were written by -.An Marcel Moolenaar Aq Mt marcel@FreeBSD.org . diff --git a/lib/libefi/libefi.h b/lib/libefi/libefi.h deleted file mode 100644 index 56d18ac9074a5..0000000000000 --- a/lib/libefi/libefi.h +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _LIBEFI_H_ -#define _LIBEFI_H_ - -#include <sys/types.h> -#include <sys/uuid.h> -#include <stddef.h> - -/* Attributes. */ -#define EFI_ATTR_NV 0x0001 /* Variable stored in NVRAM. */ -#define EFI_ATTR_BS 0x0002 /* Boot services accessable. */ -#define EFI_ATTR_RT 0x0004 /* Runtime accessable. */ -#define EFI_ATTR_HR 0x0008 /* Hardware error record. */ -#define EFI_ATTR_WR 0x0010 /* Authenticated write access. */ - -/* Vendor for architecturally defined variables. */ -#define EFI_GLOBAL_VARIABLE \ - {0x8be4df61,0x93ca,0x11d2,0xaa,0x0d,{0x00,0xe0,0x98,0x03,0x2b,0x8c}} - -/* Vendor for FreeBSD-specific variables. */ -#define EFI_FREEBSD_VARIABLE \ - {0x13c32014,0x0c9c,0x11df,0xa2,0x38,{0x00,0x17,0xa4,0xab,0x91,0x2d}} - -__BEGIN_DECLS -int efi_getvar (char *, uuid_t *, uint32_t *, size_t *, void *); -int efi_nextvarname (size_t *, char *, uuid_t *); -int efi_setvar (char *, uuid_t *, uint32_t, size_t, void *); -__END_DECLS - -#endif /* _LIBEFI_H_ */ diff --git a/lib/libefivar/Makefile b/lib/libefivar/Makefile new file mode 100644 index 0000000000000..c3ad3615e9d69 --- /dev/null +++ b/lib/libefivar/Makefile @@ -0,0 +1,53 @@ +# Copyright 1998 Juniper Networks, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +.include <src.opts.mk> + +PACKAGE=lib${LIB} +LIB= efivar +SRCS= efivar.c libefivar.c +INCS= efivar.h +SHLIB_MAJOR= 1 +MAN= efivar.3 + +MLINKS+=efivar.3 efi_set_variables_supported.3 \ + efivar.3 efi_del_variable.3 \ + efivar.3 efi_get_variable.3 \ + efivar.3 efi_get_variable_attributes.3 \ + efivar.3 efi_get_variable_size.3 \ + efivar.3 efi_append_variable.3 \ + efivar.3 efi_set_variable.3 \ + efivar.3 efi_get_next_variable_name.3 \ + efivar.3 efi_str_to_guid.3 \ + efivar.3 efi_guid_to_str.3 \ + efivar.3 efi_name_to_guid.3 \ + efivar.3 efi_guid_to_name.3 \ + efivar.3 efi_guid_to_symbol.3 \ + efivar.3 libefivar.3 + +WARNS?= 9 + +.include <bsd.lib.mk> diff --git a/lib/libefivar/efivar.3 b/lib/libefivar/efivar.3 new file mode 100644 index 0000000000000..4d1d50470467a --- /dev/null +++ b/lib/libefivar/efivar.3 @@ -0,0 +1,98 @@ +.\" Copyright 2016 Netflix, Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 14, 2016 +.Dt LIBEFIVAR 3 +.Os +.Sh NAME +.Nm libefivar +.Nd EFI Non Volatile Variable Suppoert +.Sh SYNOPSIS +.In efivar.h +.Ft int +.Fn efi_append_variable "efi_guid_t guid" "const char *name" "void *data" "size_t data_size" "uint32_t attributes" +.Ft int +.Fn efi_del_variable "efi_guid_t guid" "const char *name" +.Ft int +.Fn efi_get_variable "efi_guid_t guid" "const char *name" "void **data" "ssize_t *data_size" "uint32_t *attributes" +.Ft int +.Fn efi_get_variable_attributes "efi_guid_t guid" "const char *name" "uint32_t *attributes" +.Ft int +.Fn efi_get_variable_size "efi_guid_t guid" "const char *name" "size_t *size" +.Ft int +.Fn efi_get_next_variable_name "efi_guid_t **guid" "char **name" +.Ft int +.Fn efi_guid_to_name "efi_guid_t *guid" "char **name" +.Ft int +.Fn efi_guid_to_symbol "efi_guid_t *guid" "char **symbol" +.Ft int +.Fn efi_guid_to_str "const efi_guid_t *guid" "char **sp" +.Ft int +.Fn efi_name_to_guid "const char *name" "efi_guid_t *guid" +.Ft int +.Fn efi_set_variable "efi_guid_t guid" "const char *name" "void *data" "size_t data_size" "uint32_t attributes" +.Ft int +.Fn efi_str_to_guid "const char *s" "efi_guid_t *guid"; +.Ft int +.Fn efi_variables_supported "void"; +.Sh DESCRIPTION +The +.Nm +library implements access to EFI Variables via the EFI Runtime +Serivces. +All char * strings are converted to 16-bit UTF strings before passing +them to EFI. +.Pp +.Fn efi_variables_supported +returns non-zero if the current machine supports setting of EFI firmware +variables and the kernel support for doing so is present. +Otherwise zero is returned. +.Pp +.Fn efi_del_variable +deletes the EFI variable selected by +.Dv guid +and +.Dv name . +.Pp +.Fn efi_get_variable +.Fn efi_get_variable_attributes +.Fn efi_get_variable_size +.Fn efi_append_variable +.Fn efi_set_variable +.Fn efi_get_next_variable_name +.Fn efi_str_to_guid +.Fn efi_guid_to_str +.Fn efi_name_to_guid +.Fn efi_guid_to_name +.Fn efi_guid_to_symbol +This function is not actually implemented. +.Sh BUGS +No facilities exist to process the strings as native UTF. +This is a limitation in the Linux libefivar library interface. +.Sh AUTHORS +.An -nosplit +This software was originally written by +.An Warner Losh . diff --git a/lib/libefivar/efivar.c b/lib/libefivar/efivar.c new file mode 100644 index 0000000000000..fabdec3fcc770 --- /dev/null +++ b/lib/libefivar/efivar.c @@ -0,0 +1,380 @@ +/*- + * Copyright (c) 2016 Netflix, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efivar.h> +#include <sys/efiio.h> +#include <sys/param.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "libefivar_int.h" + +static int efi_fd = -2; + +#define Z { 0, 0, 0, 0, 0, { 0 } } + +const efi_guid_t efi_guid_empty = Z; + +static struct uuid_table +{ + const char *uuid_str; + const char *name; + efi_guid_t guid; +} guid_tbl [] = +{ + { "00000000-0000-0000-0000-000000000000", "zero", Z }, + { "093e0fae-a6c4-4f50-9f1b-d41e2b89c19a", "sha512", Z }, + { "0abba7dc-e516-4167-bbf5-4d9d1c739416", "redhat", Z }, + { "0b6e5233-a65c-44c9-9407-d9ab83bfc8bd", "sha224", Z }, + { "126a762d-5758-4fca-8531-201a7f57f850", "lenovo_boot_menu", Z }, + { "3bd2a492-96c0-4079-b420-fcf98ef103ed", "x509_sha256", Z }, + { "3c5766e8-269c-4e34-aa14-ed776e85b3b6", "rsa2048", Z }, + { "3CC24E96-22C7-41D8-8863-8E39DCDCC2CF", "lenovo", Z }, + { "3f7e615b-0d45-4f80-88dc-26b234958560", "lenovo_diag", Z }, + { "446dbf63-2502-4cda-bcfa-2465d2b0fe9d", "x509_sha512", Z }, + { "4aafd29d-68df-49ee-8aa9-347d375665a7", "pkcs7_cert", Z }, + { "605dab50-e046-4300-abb6-3dd810dd8b23", "shim", Z }, + { "665d3f60-ad3e-4cad-8e26-db46eee9f1b5", "lenovo_rescue", Z }, + { "67f8444f-8743-48f1-a328-1eaab8736080", "rsa2048_sha1", Z }, + { "7076876e-80c2-4ee6-aad2-28b349a6865b", "x509_sha384", Z }, + { "721c8b66-426c-4e86-8e99-3457c46ab0b9", "lenovo_setup", Z }, + { "77fa9abd-0359-4d32-bd60-28f4e78f784b", "microsoft", Z }, + { "7FACC7B6-127F-4E9C-9C5D-080F98994345", "lenovo_2", Z }, + { "826ca512-cf10-4ac9-b187-be01496631bd", "sha1", Z }, + { "82988420-7467-4490-9059-feb448dd1963", "lenovo_me_config", Z }, + { "8be4df61-93ca-11d2-aa0d-00e098032b8c", "global", Z }, + { "a5c059a1-94e4-4aa7-87b5-ab155c2bf072", "x509_cert", Z }, + { "a7717414-c616-4977-9420-844712a735bf", "rsa2048_sha256_cert", Z }, + { "a7d8d9a6-6ab0-4aeb-ad9d-163e59a7a380", "lenovo_diag_splash", Z }, + { "ade9e48f-9cb8-98e6-31af-b4e6009e2fe3", "redhat_2", Z }, + { "bc7838d2-0f82-4d60-8316-c068ee79d25b", "lenovo_msg", Z }, + { "c1c41626-504c-4092-aca9-41f936934328", "sha256", Z }, + { "c57ad6b7-0515-40a8-9d21-551652854e37", "shell", Z }, + { "d719b2cb-3d3a-4596-a3bc-dad00e67656f", "security", Z }, + { "e2b36190-879b-4a3d-ad8d-f2e7bba32784", "rsa2048_sha256", Z }, + { "ff3e5307-9fd0-48c9-85f1-8ad56c701e01", "sha384", Z }, + { "f46ee6f4-4785-43a3-923d-7f786c3c8479", "lenovo_startup_interrupt", Z }, + { "ffffffff-ffff-ffff-ffff-ffffffffffff", "zzignore-this-guid", Z }, +}; +#undef Z + +static void +efi_guid_tbl_compile(void) +{ + size_t i; + uint32_t status; + + for (i = 0; i < nitems(guid_tbl); i++) { + uuid_from_string(guid_tbl[i].uuid_str, &guid_tbl[i].guid, + &status); + /* all f's is a bad version, so ignore that error */ + if (status != uuid_s_ok && status != uuid_s_bad_version) + fprintf(stderr, "Can't convert %s to a uuid for %s: %d\n", + guid_tbl[i].uuid_str, guid_tbl[i].name, (int)status); + } +} + +static int +efi_open_dev(void) +{ + + if (efi_fd == -2) + efi_fd = open("/dev/efidev", O_RDWR); + if (efi_fd < 0) + efi_fd = -1; + else + efi_guid_tbl_compile(); + return (efi_fd); +} + +static void +efi_var_reset(struct efi_var_ioc *var) +{ + var->name = NULL; + var->namesize = 0; + memset(&var->vendor, 0, sizeof(var->vendor)); + var->attrib = 0; + var->data = NULL; + var->datasize = 0; +} + +static int +rv_to_linux_rv(int rv) +{ + if (rv == 0) + rv = 1; + else if (errno == ENOENT) { + rv = 0; + errno = 0; + } else + rv = -errno; + return (rv); +} + +int +efi_append_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes) +{ + + return efi_set_variable(guid, name, data, data_size, + attributes | EFI_VARIABLE_APPEND_WRITE, 0); +} + +int +efi_del_variable(efi_guid_t guid, const char *name) +{ + + /* data_size of 0 deletes the variable */ + return efi_set_variable(guid, name, NULL, 0, 0, 0); +} + +int +efi_get_variable(efi_guid_t guid, const char *name, + uint8_t **data, size_t *data_size, uint32_t *attributes) +{ + struct efi_var_ioc var; + int rv; + static uint8_t buf[1024*32]; + + if (efi_open_dev() == -1) + return -1; + + efi_var_reset(&var); + rv = libefi_utf8_to_ucs2(name, &var.name, &var.namesize); + if (rv != 0) + goto errout; + var.vendor = guid; + var.data = buf; + var.datasize = sizeof(buf); + rv = ioctl(efi_fd, EFIIOC_VAR_GET, &var); + if (data_size != NULL) + *data_size = var.datasize; + if (data != NULL) + *data = buf; + if (attributes != NULL) + *attributes = var.attrib; +errout: + free(var.name); + + return rv_to_linux_rv(rv); +} + +int +efi_get_variable_attributes(efi_guid_t guid, const char *name, + uint32_t *attributes) +{ + /* Make sure this construct works -- I think it will fail */ + + return efi_get_variable(guid, name, NULL, NULL, attributes); +} + +int +efi_get_variable_size(efi_guid_t guid, const char *name, + size_t *size) +{ + + /* XXX check to make sure this matches the linux value */ + + *size = 0; + return efi_get_variable(guid, name, NULL, size, NULL); +} + +int +efi_get_next_variable_name(efi_guid_t **guid, char **name) +{ + struct efi_var_ioc var; + int rv; + static efi_char *buf; + static size_t buflen = 256 * sizeof(efi_char); + static efi_guid_t retguid; + size_t size; + + if (efi_open_dev() == -1) + return -1; + + if (buf == NULL) + buf = malloc(buflen); + +again: + efi_var_reset(&var); + var.name = buf; + var.namesize = buflen; + if (*name == NULL) { + *buf = 0; + /* GUID zeroed in var_reset */ + } else { + rv = libefi_utf8_to_ucs2(*name, &var.name, &size); + if (rv != 0) + goto errout; + var.vendor = **guid; + } + rv = ioctl(efi_fd, EFIIOC_VAR_NEXT, &var); + if (rv == 0 && var.name == NULL) { + /* + * oops, too little space. Try again. + */ + void *new = realloc(buf, buflen); + buflen = var.namesize; + if (new == NULL) { + rv = -1; + errno = ENOMEM; + goto done; + } + buf = new; + goto again; + } + + if (rv == 0) { + *name = NULL; /* XXX */ + var.name[var.namesize / sizeof(efi_char)] = 0; /* EFI doesn't NUL terminate */ + rv = libefi_ucs2_to_utf8(var.name, name); + if (rv != 0) + goto errout; + retguid = var.vendor; + *guid = &retguid; + } +errout: + + /* XXX The linux interface expects name to be a static buffer -- fix or leak memory? */ +done: + return (rv_to_linux_rv(rv)); +} + +int +efi_guid_cmp(const efi_guid_t *guid1, const efi_guid_t *guid2) +{ + uint32_t status; + + return uuid_compare(guid1, guid2, &status); +} + +int +efi_guid_is_zero(const efi_guid_t *guid) +{ + uint32_t status; + + return uuid_is_nil(guid, &status); +} + +int +efi_guid_to_name(efi_guid_t *guid, char **name) +{ + size_t i; + uint32_t status; + + for (i = 0; i < nitems(guid_tbl); i++) { + if (uuid_equal(guid, &guid_tbl[i].guid, &status)) { + *name = strdup(guid_tbl[i].name); + return (0); + } + } + return (efi_guid_to_str(guid, name)); +} + +int +efi_guid_to_symbol(efi_guid_t *guid __unused, char **symbol __unused) +{ + + /* + * Unsure what this is used for, efibootmgr doesn't use it. + * Leave unimplemented for now. + */ + return -1; +} + +int +efi_guid_to_str(const efi_guid_t *guid, char **sp) +{ + uint32_t status; + + /* knows efi_guid_t is a typedef of uuid_t */ + uuid_to_string(guid, sp, &status); + + return (status == uuid_s_ok ? 0 : -1); +} + +int +efi_name_to_guid(const char *name, efi_guid_t *guid) +{ + size_t i; + + for (i = 0; i < nitems(guid_tbl); i++) { + if (strcmp(name, guid_tbl[i].name) == 0) { + *guid = guid_tbl[i].guid; + return (0); + } + } + return (efi_str_to_guid(name, guid)); +} + +int +efi_set_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes, mode_t mode __unused) +{ + struct efi_var_ioc var; + int rv; + + if (efi_open_dev() == -1) + return -1; + + efi_var_reset(&var); + rv = libefi_utf8_to_ucs2(name, &var.name, &var.namesize); + if (rv != 0) + goto errout; + var.vendor = guid; + var.data = data; + var.datasize = data_size; + var.attrib = attributes; + rv = ioctl(efi_fd, EFIIOC_VAR_SET, &var); +errout: + free(var.name); + + return rv; +} + +int +efi_str_to_guid(const char *s, efi_guid_t *guid) +{ + uint32_t status; + + /* knows efi_guid_t is a typedef of uuid_t */ + uuid_from_string(s, guid, &status); + + return (status == uuid_s_ok ? 0 : -1); +} + +int +efi_variables_supported(void) +{ + + return efi_open_dev() != -1; +} diff --git a/lib/libefivar/efivar.h b/lib/libefivar/efivar.h new file mode 100644 index 0000000000000..84301f0878aad --- /dev/null +++ b/lib/libefivar/efivar.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2016 Netflix, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _EFIVAR_H_ +#define _EFIVAR_H_ + +#include <uuid.h> +#include <sys/efi.h> +#include <sys/endian.h> +#include <stdint.h> + +/* Shoud these be elsewhere ? */ +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS \ + 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 +#if 0 /* todo */ +#define EFI_VARIABLE_HAS_AUTH_HEADER +#define EFI_VARIABLE_HAS_SIGNATURE +#endif + + +typedef uuid_t efi_guid_t; +#if BYTE_ORDER == LITTLE_ENDIAN +#define EFI_GUID(a, b, c, d, e0, e1, e2, e3, e4, e5) \ + ((efi_guid_t) {(a), (b), (c), (d) >> 8, (d) & 0xff, \ + { (e0), (e1), (e2), (e3), (e4), (e5) }}) +#else +#define EFI_GUID(a, b, c, d, e0, e1, e2, e3, e4, e5) \ + ((efi_guid_t) {(a), (b), (c), (d) & 0xff, (d) >> 8, \ + { (e0), (e1), (e2), (e3), (e4), (e5) }}) +#endif + +#define EFI_GLOBAL_GUID EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa0d, \ + 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c) + +int efi_append_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes); +int efi_del_variable(efi_guid_t guid, const char *name); +int efi_get_variable(efi_guid_t guid, const char *name, + uint8_t **data, size_t *data_size, uint32_t *attributes); +int efi_get_variable_attributes(efi_guid_t guid, const char *name, + uint32_t *attributes); +int efi_get_variable_size(efi_guid_t guid, const char *name, size_t *size); +int efi_get_next_variable_name(efi_guid_t **guid, char **name); +int efi_guid_cmp(const efi_guid_t *guid1, const efi_guid_t *guid2); +int efi_guid_is_zero(const efi_guid_t *guid1); +int efi_guid_to_name(efi_guid_t *guid, char **name); +int efi_guid_to_symbol(efi_guid_t *guid, char **symbol); +int efi_guid_to_str(const efi_guid_t *guid, char **sp); +int efi_name_to_guid(const char *name, efi_guid_t *guid); +int efi_set_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes, mode_t mode); +int efi_str_to_guid(const char *s, efi_guid_t *guid); +int efi_variables_supported(void); + +extern const efi_guid_t efi_guid_empty; + +/* Stubs that are expected, but aren't really used */ +static inline int +efi_error_get(unsigned int n __unused, char ** const fn __unused, + char ** const func __unused, int *line __unused, + char ** const msg __unused, int *err __unused) +{ + return 0; +} + +static inline int +efi_error_set(const char *fn __unused, const char *func __unused, + int line __unused, int err __unused, const char *fmt __unused, ...) +{ + return 0; +} + +static inline void +efi_error_clear(void) +{ +} + +static inline int +efi_error(const char *fmt __unused, ...) +{ + return 0; +} + +static inline int +efi_error_val(int val __unused, const char *fmt __unused, ...) +{ + return 0; +} + +#endif /* _EFIVAR_H_ */ diff --git a/lib/libefi/libefi.c b/lib/libefivar/libefivar.c index c65784f571323..951c484f5e3a0 100644 --- a/lib/libefi/libefi.c +++ b/lib/libefivar/libefivar.c @@ -27,86 +27,105 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/ioctl.h> #include <sys/types.h> -#include <fcntl.h> +#include <errno.h> #include <stddef.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/efi.h> +#include <machine/efi.h> -#include "libefi_int.h" +#include "libefivar_int.h" -static int __iofd = -1; +#include <stdio.h> -static void -iodev_fd_close(void) -{ - - close(__iofd); -} - -static int -iodev_fd(int *fd) +/* + * If nm were converted to utf8, what what would strlen + * return on the resulting string? + */ +static size_t +utf8_len_of_ucs2(const efi_char *nm) { + size_t len; + efi_char c; - *fd = __iofd; - if (__iofd != -1) - return (0); - - __iofd = open("/dev/io", O_RDWR); - if (__iofd == -1) - return (errno); + len = 0; + while (*nm) { + c = *nm++; + if (c > 0x7ff) + len += 3; + else if (c > 0x7f) + len += 2; + else + len++; + } - atexit(iodev_fd_close); - *fd = __iofd; - return (0); + return (len); } int -libefi_ucs2_to_utf8(u_short *nm, size_t *szp, char *name) +libefi_ucs2_to_utf8(const efi_char *nm, char **name) { size_t len, sz; - u_short c; + efi_char c; + char *cp; + int freeit = *name == NULL; + sz = utf8_len_of_ucs2(nm) + 1; len = 0; - sz = *szp; + if (*name != NULL) + cp = *name; + else + cp = *name = malloc(sz); + if (*name == NULL) + return (ENOMEM); + while (*nm) { c = *nm++; if (c > 0x7ff) { if (len++ < sz) - *name++ = 0xE0 | (c >> 12); + *cp++ = (char)(0xE0 | (c >> 12)); if (len++ < sz) - *name++ = 0x80 | ((c >> 6) & 0x3f); + *cp++ = (char)(0x80 | ((c >> 6) & 0x3f)); if (len++ < sz) - *name++ = 0x80 | (c & 0x3f); + *cp++ = (char)(0x80 | (c & 0x3f)); } else if (c > 0x7f) { if (len++ < sz) - *name++ = 0xC0 | ((c >> 6) & 0x1f); + *cp++ = (char)(0xC0 | ((c >> 6) & 0x1f)); if (len++ < sz) - *name++ = 0x80 | (c & 0x3f); + *cp++ = (char)(0x80 | (c & 0x3f)); } else { if (len++ < sz) - *name++ = (c & 0x7f); + *cp++ = (char)(c & 0x7f); } } - if (len++ < sz) - *name++ = 0; - *szp = len; - return ((len <= sz) ? 0 : EOVERFLOW); + if (len >= sz) { + /* Absent bugs, we'll never return EOVERFLOW */ + if (freeit) + free(*name); + return (EOVERFLOW); + } + *cp++ = '\0'; + + return (0); } int -libefi_utf8_to_ucs2(char *name, size_t *szp, u_short **nmp) +libefi_utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) { - u_short *nm; + efi_char *nm; size_t sz; uint32_t ucs4; int c, bytes; + int freeit = *nmp == NULL; - *szp = sz = (*szp == 0) ? strlen(name) * 2 + 2 : *szp; - *nmp = nm = malloc(sz); + sz = strlen(name) * 2 + 2; + if (*nmp == NULL) + *nmp = malloc(sz); + nm = *nmp; + *len = sz; ucs4 = 0; bytes = 0; @@ -119,7 +138,8 @@ libefi_utf8_to_ucs2(char *name, size_t *szp, u_short **nmp) if ((c & 0xc0) != 0x80) { /* Initial characters. */ if (bytes != 0) { - free(nm); + if (freeit) + free(nm); return (EILSEQ); } if ((c & 0xf8) == 0xf0) { @@ -141,36 +161,28 @@ libefi_utf8_to_ucs2(char *name, size_t *szp, u_short **nmp) ucs4 = (ucs4 << 6) + (c & 0x3f); bytes--; } else if (bytes == 0) { - free(nm); + if (freeit) + free(nm); return (EILSEQ); } } if (bytes == 0) { if (ucs4 > 0xffff) { - free(nm); + if (freeit) + free(nm); return (EILSEQ); } - *nm++ = (u_short)ucs4; + *nm++ = (efi_char)ucs4; sz -= 2; } } if (sz < 2) { - free(nm); + if (freeit) + free(nm); return (EDOOFUS); } + sz -= 2; *nm = 0; + *len -= sz; return (0); } - -int -libefi_efivar(struct iodev_efivar_req *req) -{ - int error, fd; - - error = iodev_fd(&fd); - if (!error) - error = (ioctl(fd, IODEV_EFIVAR, req) == -1) ? errno : 0; - if (!error) - error = req->result; - return (error); -} diff --git a/lib/libefi/libefi_int.h b/lib/libefivar/libefivar_int.h index 28ee822bad47c..276ab19dcffbf 100644 --- a/lib/libefi/libefi_int.h +++ b/lib/libefivar/libefivar_int.h @@ -29,12 +29,7 @@ #ifndef _LIBEFI_INT_H_ #define _LIBEFI_INT_H_ -#include <sys/errno.h> -#include <machine/iodev.h> - -int libefi_ucs2_to_utf8(u_short *, size_t *, char *); -int libefi_utf8_to_ucs2(char *, size_t *, u_short **); - -int libefi_efivar(struct iodev_efivar_req *); +int libefi_ucs2_to_utf8(const efi_char *, char **); +int libefi_utf8_to_ucs2(const char *, efi_char **, size_t *); #endif /* _LIBEFI_INT_H_ */ |
