diff --git a/ChangeLog b/ChangeLog index 5934a6b..520e794 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +1.9.8: Ludovic Rousseau +11 June 2022 +- Install install_spy.sh & uninstall_spy.sh scripts in docdir +- SCardTransmit(): do not fail if receive buffer is "too large" +- SCardControl(): do not fail if receive buffer is "too large" +- fix some memory leaks on shutdown +- use a better random number generator +- Some other minor improvements + + 1.9.7: Ludovic Rousseau 13 May 2022 - disable strict compilation by default diff --git a/ChangeLog.git b/ChangeLog.git index 8dcca00..699c733 100644 --- a/ChangeLog.git +++ b/ChangeLog.git @@ -1,4 +1,259 @@ -commit 5c45145d34b5e7382e0223477ff22de67ef97c77 (HEAD -> master) +commit 41dc5a51321bc3198af36574f73dc007cab72a7d (HEAD -> master, tag: 1.9.8) +Author: Ludovic Rousseau +Date: Sat Jun 11 10:49:34 2022 +0200 + + Release 1.9.8 + + Signed-off-by: Ludovic Rousseau + + ChangeLog | 10 ++++++++++ + configure.ac | 2 +- + 2 files changed, 11 insertions(+), 1 deletion(-) + +commit f7f80db5fae5f15c0d0ce2e6cd81a5c11c0a7510 (zotac/master, origin/master, origin/HEAD, github/master) +Author: Ludovic Rousseau +Date: Fri Jun 10 09:58:46 2022 +0200 + + Install install_spy.sh uninstall_spy.sh scripts + + They are installed in docdir i.e. ${datarootdir}/doc/${PACKAGE} where + datarootdir is ${prefix}/share + + On a Debian system with --prefix=/usr that is /usr/share/doc/pcsc-lite/ + + The idea is to have the scripts included in the -dev package so that + they are easily available on user's computer. + + src/spy/Makefile.am | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit c94aeb5ed933dbbe09af611a4829999860a0b293 +Author: Petr Mikhalicin +Date: Thu May 26 18:03:38 2022 +0300 + + Add destructor library function + + Resolve: https://salsa.debian.org/rousseau/PCSC/-/issues/1 + + src/winscard_clnt.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +commit b312b45dd6a8d6c18ee09a411e7b3df6a0ab831f +Author: Ludovic Rousseau +Date: Wed Jun 1 17:56:55 2022 +0200 + + SCardControl(): do not fail if receive buffer is "too large" + + SCardControl() should not fail if the receive buffer is "too large" + i.e. larger than MAX_BUFFER_SIZE_EXTENDED. + + src/winscard_clnt.c | 3 +-- + src/winscard_svc.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +commit 6218f7bc878ba183a788de5f7441247f20d1adaf +Author: Ludovic Rousseau +Date: Wed Jun 1 17:50:23 2022 +0200 + + Test the check of SCardControl(..., cbRecvLength,..) + + SCardControl() should not fail if the receive buffer is "too large" + i.e. larger than MAX_BUFFER_SIZE_EXTENDED. + + UnitaryTests/BufferOverflow_SCardControl.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 967e6e5495685bdedafb55d937fbef8a036f2c60 +Author: Ludovic Rousseau +Date: Wed Jun 1 17:41:58 2022 +0200 + + SCardTransmit(): do not fail if receive buffer is "too large" + + SCardTransmit() should not fail if the receive buffer is "too large" + i.e. larger than MAX_BUFFER_SIZE_EXTENDED. + + Thanks to Frank Morgner for the bug report. + " Too strict checking on limits for SCardTransmit #137 " + https://github.com/LudovicRousseau/PCSC/issues/137 + + src/winscard_clnt.c | 3 +-- + src/winscard_svc.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +commit 540026cdb77f42a91d1da5cdc7f607bbbbaffa70 +Author: Ludovic Rousseau +Date: Wed Jun 1 17:39:59 2022 +0200 + + Test the check of SCardTransmit(..., pbRecvBuffer) + + SCardTransmit() should not fail if the receive buffer is "too large" + i.e. larger than MAX_BUFFER_SIZE_EXTENDED. + + UnitaryTests/BufferOverflow_SCardTransmit.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +commit 210efa525f50e99821a10d91b8c861825e470d8b +Author: Maksim Ivanov +Date: Sun May 29 16:31:19 2022 +0200 + + Fix leak of fullName on shutdown (#134) + + Free _readerTracker::fullName strings on shutdown in hotplug_libusb. + + src/hotplug_libusb.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +commit 652cbffa4cad54bbd93ad538c27ad6b169bc869f +Author: Maksim Ivanov +Date: Sun May 29 16:27:47 2022 +0200 + + gitignore configure~, config.h.in~ (#136) + + Add the "configure~" and "config.h.in~" files to .gitignore. These files + are produced after running "bootstrap" more than once, and don't need to + be committed. + + .gitignore | 2 ++ + 1 file changed, 2 insertions(+) + +commit 9879d1c2b78caafc757b883b0fe8ccc8e7c4548f +Author: Maksim Ivanov +Date: Sun May 29 16:24:39 2022 +0200 + + Make sure AraKiriHotPlug false on libusb startup (#135) + + Reset the AraKiriHotPlug flag to false when starting libusb hotplug + search. + + This is not needed on the initial process startup, because the flag is + initialized to false, but allows to implement unit tests that need to + restart the previously stopped threads within the memory of the same + process. + + src/hotplug_libusb.c | 1 + + 1 file changed, 1 insertion(+) + +commit accaa9738ad6091603ead68e85d2217944624cee +Author: Maksim Ivanov +Date: Fri May 27 17:19:21 2022 +0200 + + Fix double-free of CFBundleName on shutdown (#132) + + Fix the double-free of the _driverTracker::CFBundleName field in + HPRescanUsbBus() in hotplug_libusb on the shutdown path. The root cause + was reusing the same string pointer for multiple entries in the + driverTracker array. + + src/hotplug_libusb.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 1ab596a91032f0f4ce8d73454c33cae9129ab358 +Author: Maksim Ivanov +Date: Fri May 27 17:17:37 2022 +0200 + + Fix libusb_device list leak on shutdown (#133) + + Call libusb_free_device_list() before exiting the hotplug thread in + hotplug_libusb.c. + + src/hotplug_libusb.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 7ca49799838cafcb403f63cce66624ff9fec15c8 +Author: Ludovic Rousseau +Date: Sun May 22 13:23:03 2022 +0200 + + Revert change from SYS_RandomInt() SYS_RandomLong() + + The communication between pcscd and libpcsclite uses 32-bits variables + in the exchanged structures: + uint32_t hContext; + int32_t hCard; + + If we want to use 64-bits variables we need to also change the + pcscd-libpcsclite communication protocol and upgrade + PROTOCOL_VERSION_MAJOR. + + This would break many working configurations using flatpak for example. + https://ludovicrousseau.blogspot.com/2022/02/accessing-smart-cards-from-inside.html + + src/readerfactory.c | 4 ++-- + src/sys_generic.h | 2 +- + src/sys_unix.c | 16 ++++++++-------- + src/winscard.c | 2 +- + 4 files changed, 12 insertions(+), 12 deletions(-) + +commit 8d60ec131318e97fe8fb2e8dec4bf1d8286e3407 +Author: Ludovic Rousseau +Date: Sun May 22 13:01:53 2022 +0200 + + Handle getrandom() return value + + Fix: + sys_unix.c:110:15: error: ignoring return value of 'getrandom' declared with attribute 'warn_unused_result' [-Werror=unused-result] + 110 | (void)getrandom(c, sizeof c, 0); + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + + src/sys_unix.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +commit 2c3d3bfd3793334aa688d565343e9fab1796229e +Author: Nikolaos Chatzikonstantinou +Date: Mon May 16 11:01:55 2022 +0900 + + Change random number generator + + Four fixes are applied in this patch: + + 1) The `SYS_RandomInt()` function is renamed to `SYS_RandomLong()`, + and its return type is now `long`. It no longer takes a range as + parameters for its random number generation; it always uses the full + range. + 2) The `getrandom()` syscall is added to configure.ac as a requested + function. + 3) The generator for `SYS_RandomLong()` is changed. The previous + generator was from the `rand()` function, but now it uses + `getrandom()` when available and otherwise `lrand48()`, from the POSIX + API. + 4) The seeding of the generator is via `SYS_InitRandom()`. It is + modified accordingly to seed the new generator. + + Addresses Ref #9 + "Improve SYS_RandomInt()" + https://salsa.debian.org/rousseau/PCSC/-/issues/9 + + configure.ac | 2 +- + src/readerfactory.c | 4 ++-- + src/sys_generic.h | 2 +- + src/sys_unix.c | 46 ++++++++++++++++++++++++++++++++-------------- + src/winscard.c | 2 +- + 5 files changed, 37 insertions(+), 19 deletions(-) + +commit 615160ff2f1e6f0f0ee324f7442b0068552d0068 +Author: Maksim Ivanov +Date: Wed May 18 21:38:13 2022 +0200 + + Fix shutdown memory leak of sReadersContexts + + RFCleanupReaders() should always free memory of sReadersContexts + (allocated in RFAllocateReaderSpace()), not only when the reader was + active. + + This was only a minor, shutdown-only, issue. + + src/readerfactory.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +commit e1a0103c0e1e643dd8680610c33da5849c76ce4c (debug/master) +Author: Ludovic Rousseau +Date: Fri May 13 13:45:44 2022 +0200 + + github actions: use --enable-strict + + .github/workflows/build.yml | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +commit 5c45145d34b5e7382e0223477ff22de67ef97c77 (tag: 1.9.7) Author: Ludovic Rousseau Date: Fri May 13 13:10:29 2022 +0200 @@ -19,7 +274,7 @@ Date: Fri May 13 13:08:31 2022 +0200 c.sh | 1 + 1 file changed, 1 insertion(+) -commit b3f795550713121eb12d0c5e5ee5c9ac7be37b13 (debug/master) +commit b3f795550713121eb12d0c5e5ee5c9ac7be37b13 Author: Ludovic Rousseau Date: Fri May 13 12:53:52 2022 +0200 @@ -31,7 +286,7 @@ Date: Fri May 13 12:53:52 2022 +0200 configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) -commit c2ca47deab2cc802b09dd509aca118f73f63b169 (zotac/master, origin/master, origin/HEAD, github/master) +commit c2ca47deab2cc802b09dd509aca118f73f63b169 Author: Ludovic Rousseau Date: Thu May 12 21:43:10 2022 +0200 diff --git a/Makefile.in b/Makefile.in index 7be8054..ebac14b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -160,7 +160,7 @@ DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/src/PCSC/pcsclite.h.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README TODO ar-lib compile config.guess \ - config.sub depcomp install-sh ltmain.sh missing ylwrap + config.sub install-sh ltmain.sh missing ylwrap DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/config.h.in b/config.h.in index 6416997..e40f629 100644 --- a/config.h.in +++ b/config.h.in @@ -40,6 +40,9 @@ /* Define to 1 if you have the `getopt_long' function. */ #undef HAVE_GETOPT_LONG +/* Define to 1 if you have the `getrandom' function. */ +#undef HAVE_GETRANDOM + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H diff --git a/configure b/configure index c55a8a8..78e41f3 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for pcsc-lite 1.9.7. +# Generated by GNU Autoconf 2.71 for pcsc-lite 1.9.8. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, @@ -618,8 +618,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='pcsc-lite' PACKAGE_TARNAME='pcsc-lite' -PACKAGE_VERSION='1.9.7' -PACKAGE_STRING='pcsc-lite 1.9.7' +PACKAGE_VERSION='1.9.8' +PACKAGE_STRING='pcsc-lite 1.9.8' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1424,7 +1424,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures pcsc-lite 1.9.7 to adapt to many kinds of systems. +\`configure' configures pcsc-lite 1.9.8 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1495,7 +1495,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pcsc-lite 1.9.7:";; + short | recursive ) echo "Configuration of pcsc-lite 1.9.8:";; esac cat <<\_ACEOF @@ -1649,7 +1649,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pcsc-lite configure 1.9.7 +pcsc-lite configure 1.9.8 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2065,7 +2065,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by pcsc-lite $as_me 1.9.7, which was +It was created by pcsc-lite $as_me 1.9.8, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3336,7 +3336,7 @@ fi # Define the identity of the package. PACKAGE='pcsc-lite' - VERSION='1.9.7' + VERSION='1.9.8' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -15395,6 +15395,12 @@ if test "x$ac_cv_func_vsnprintf" = xyes then : printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getrandom" "ac_cv_func_getrandom" +if test "x$ac_cv_func_getrandom" = xyes +then : + printf "%s\n" "#define HAVE_GETRANDOM 1" >>confdefs.h + fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works @@ -17236,7 +17242,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by pcsc-lite $as_me 1.9.7, which was +This file was extended by pcsc-lite $as_me 1.9.8, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17304,7 +17310,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -pcsc-lite config.status 1.9.7 +pcsc-lite config.status 1.9.8 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index e4d5571..55d3c6d 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.69]) -AC_INIT([pcsc-lite],[1.9.7]) +AC_INIT([pcsc-lite],[1.9.8]) AC_CONFIG_SRCDIR(src/pcscdaemon.c) AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip) AC_CONFIG_HEADERS([config.h]) @@ -109,7 +109,7 @@ AC_STRUCT_DIRENT_D_TYPE AC_FUNC_ERROR_AT_LINE AC_FUNC_STAT AC_FUNC_VPRINTF -AC_CHECK_FUNCS(getopt_long nanosleep strerror vsnprintf) +AC_CHECK_FUNCS(getopt_long nanosleep strerror vsnprintf getrandom) AC_FUNC_ALLOCA # C Compiler features diff --git a/src/hotplug_libusb.c b/src/hotplug_libusb.c index b9be449..e8af90a 100644 --- a/src/hotplug_libusb.c +++ b/src/hotplug_libusb.c @@ -129,6 +129,7 @@ static LONG HPAddHotPluggable(struct libusb_device *dev, struct _driverTracker *driver, struct _driverTracker *classdriver); static LONG HPRemoveHotPluggable(int reader_index); +static void HPCleanupHotPluggable(int reader_index); static LONG HPReadBundleValues(void) { @@ -212,7 +213,7 @@ static LONG HPReadBundleValues(void) if (rv) CFBundleName = NULL; else - CFBundleName = strdup(list_get_at(values, 0)); + CFBundleName = list_get_at(values, 0); /* while we find a nth ifdVendorID in Info.plist */ for (alias=0; aliasd_name); driverTracker[listCount].libraryPath = strdup(fullLibPath); driverTracker[listCount].ifdCapabilities = ifdCapabilities; - driverTracker[listCount].CFBundleName = CFBundleName; + driverTracker[listCount].CFBundleName = + CFBundleName ? strdup(CFBundleName) : NULL; #ifdef DEBUG_HOTPLUG Log2(PCSC_LOG_INFO, "Found driver for: %s", @@ -443,10 +445,19 @@ static void HPRescanUsbBus(void) HPRemoveHotPluggable(i); } + /* free the libusb allocated list & devices */ + libusb_free_device_list(devs, 1); + if (AraKiriHotPlug) { int retval; + for (i=0; i $@ endif -EXTRA_DIST = install_spy.sh uninstall_spy.sh pcsc-spy.pod +EXTRA_DIST = pcsc-spy.pod CLEANFILES = pcsc-spy.1 diff --git a/src/spy/Makefile.in b/src/spy/Makefile.in index bde6768..be8cafb 100644 --- a/src/spy/Makefile.in +++ b/src/spy/Makefile.in @@ -15,6 +15,7 @@ @SET_MAKE@ + VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ @@ -98,7 +99,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \ - $(am__DIST_COMMON) + $(dist_doc_DATA) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -131,7 +132,7 @@ am__uninstall_files_from_dir = { \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(man1dir)" + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libpcscspy_la_LIBADD = am_libpcscspy_la_OBJECTS = libpcscspy.lo @@ -186,6 +187,7 @@ am__can_run_installinfo = \ man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) +DATA = $(dist_doc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -362,11 +364,12 @@ usbdropdir = @usbdropdir@ AM_CPPFLAGS = -I$(top_srcdir)/src/PCSC -I$(top_builddir)/src/PCSC lib_LTLIBRARIES = libpcscspy.la dist_bin_SCRIPTS = pcsc-spy +dist_doc_DATA = install_spy.sh uninstall_spy.sh libpcscspy_la_SOURCES = \ libpcscspy.c @ENABLE_DOC_TRUE@man_MANS = pcsc-spy.1 -EXTRA_DIST = install_spy.sh uninstall_spy.sh pcsc-spy.pod +EXTRA_DIST = pcsc-spy.pod CLEANFILES = pcsc-spy.1 all: all-am @@ -558,6 +561,27 @@ uninstall-man1: } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique @@ -645,9 +669,9 @@ distdir-am: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(MANS) +all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -704,7 +728,7 @@ info: info-am info-am: -install-data-am: install-man +install-data-am: install-dist_docDATA install-man install-dvi: install-dvi-am @@ -750,8 +774,8 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dist_binSCRIPTS uninstall-libLTLIBRARIES \ - uninstall-man +uninstall-am: uninstall-dist_binSCRIPTS uninstall-dist_docDATA \ + uninstall-libLTLIBRARIES uninstall-man uninstall-man: uninstall-man1 @@ -762,16 +786,17 @@ uninstall-man: uninstall-man1 ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ - install-data-am install-dist_binSCRIPTS install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am \ + install-data-am install-dist_binSCRIPTS install-dist_docDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-dist_binSCRIPTS \ - uninstall-libLTLIBRARIES uninstall-man uninstall-man1 + uninstall-dist_docDATA uninstall-libLTLIBRARIES uninstall-man \ + uninstall-man1 .PRECIOUS: Makefile diff --git a/src/sys_generic.h b/src/sys_generic.h index f516b4b..b68c336 100644 --- a/src/sys_generic.h +++ b/src/sys_generic.h @@ -45,7 +45,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int SYS_USleep(int); - int SYS_RandomInt(int, int); + int SYS_RandomInt(void); void SYS_InitRandom(void); diff --git a/src/sys_unix.c b/src/sys_unix.c index 52c9486..d756648 100644 --- a/src/sys_unix.c +++ b/src/sys_unix.c @@ -39,11 +39,18 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "config.h" #include +#include #include #include +#ifdef HAVE_GETRANDOM +#include +#endif /* HAVE_GETRANDOM */ +#include +#include #include "misc.h" #include "sys_generic.h" +#include "PCSC/debuglog.h" /** * @brief Makes the current process sleep for some seconds. @@ -87,22 +94,40 @@ INTERNAL int SYS_USleep(int iTimeVal) /** * Generate a pseudo random number * - * @param[in] fStart minimal value - * @param[in] fEnd maximal value or -1 for a full range + * @return a non-negative random number * - * @return a random number between fStart and fEnd + * @remark the range is at least up to `2^31`. + * @remark this is a CSPRNG when `getrandom()` is available, LCG otherwise. + * @warning SYS_InitRandom() should be called (once) before using this function. + * @warning not thread safe when system lacks `getrandom()` syscall. + * @warning not cryptographically secure when system lacks `getrandom()` syscall. + * @warning if interrupted by a signal, this function may return 0. */ -INTERNAL int SYS_RandomInt(int fStart, int fEnd) +INTERNAL int SYS_RandomInt(void) { - int iRandNum = 0; +#ifdef HAVE_GETRANDOM + unsigned int ui = 0; + unsigned char c[sizeof ui] = {0}; + size_t i; + ssize_t ret; - if (-1 == fEnd) - /* full int range */ - iRandNum = rand(); - else - iRandNum = ((rand()+0.0)/RAND_MAX * (fEnd - fStart)) + fStart; - - return iRandNum; + ret = getrandom(c, sizeof c, 0); + if (-1 == ret) + { + Log2(PCSC_LOG_ERROR, "getrandom() failed: %s", strerror(errno)); + return lrand48(); + } + // this loop avoids trap representations that may occur in the naive solution + for(i = 0; i < sizeof ui; i++) { + ui <<= CHAR_BIT; + ui |= c[i]; + } + // the casts are for the sake of clarity + return (int)(ui & (unsigned int)INT_MAX); +#else + int r = lrand48(); // this is not thread-safe + return r; +#endif /* HAVE_GETRANDOM */ } /** @@ -110,6 +135,7 @@ INTERNAL int SYS_RandomInt(int fStart, int fEnd) */ INTERNAL void SYS_InitRandom(void) { +#ifndef HAVE_GETRANDOM struct timeval tv; struct timezone tz; long myseed = 0; @@ -124,6 +150,7 @@ INTERNAL void SYS_InitRandom(void) myseed = (long) time(NULL); } - srand(myseed); + srand48(myseed); +#endif /* HAVE_GETRANDOM */ } diff --git a/src/winscard.c b/src/winscard.c index 89b49d9..e6f4c67 100644 --- a/src/winscard.c +++ b/src/winscard.c @@ -210,7 +210,7 @@ LONG SCardEstablishContext(DWORD dwScope, /*@unused@*/ LPCVOID pvReserved1, * identified by clients and distinguished from others */ - *phContext = SYS_RandomInt(0, -1); + *phContext = SYS_RandomInt(); Log2(PCSC_LOG_DEBUG, "Establishing Context: 0x%lX", *phContext); diff --git a/src/winscard_clnt.c b/src/winscard_clnt.c index 20504d5..5eef776 100644 --- a/src/winscard_clnt.c +++ b/src/winscard_clnt.c @@ -498,6 +498,13 @@ end: return rv; } +#ifdef DESTRUCTOR +DESTRUCTOR static void destructor(void) +{ + list_destroy(&contextMapList); +} +#endif + /** * @brief Creates a communication context to the PC/SC Resource * Manager. @@ -547,9 +554,8 @@ static LONG SCardEstablishContextTH(DWORD dwScope, { int lrv; - /* NOTE: The list will never be freed (No API call exists to - * "close all contexts". - * Applications which load and unload the library will leak + /* NOTE: The list will be freed only if DESTRUCTOR is defined. + * Applications which load and unload the library may leak * the list's internal structures. */ lrv = list_init(&contextMapList); if (lrv < 0) @@ -2233,8 +2239,7 @@ LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, return SCARD_E_INVALID_HANDLE; } - if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED) - || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED)) + if (cbSendLength > MAX_BUFFER_SIZE_EXTENDED) { rv = SCARD_E_INSUFFICIENT_BUFFER; goto end; @@ -2689,8 +2694,7 @@ retry: return SCARD_E_INVALID_HANDLE; } - if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED) - || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED)) + if (cbSendLength > MAX_BUFFER_SIZE_EXTENDED) { rv = SCARD_E_INSUFFICIENT_BUFFER; goto end; diff --git a/src/winscard_svc.c b/src/winscard_svc.c index 3eda96f..0140832 100644 --- a/src/winscard_svc.c +++ b/src/winscard_svc.c @@ -658,8 +658,7 @@ static void * ContextThread(LPVOID newContext) goto exit; /* avoids buffer overflow */ - if ((trStr.pcbRecvLength > sizeof(pbRecvBuffer)) - || (trStr.cbSendLength > sizeof(pbSendBuffer))) + if (trStr.cbSendLength > sizeof(pbSendBuffer)) goto buffer_overflow; /* read sent buffer */ @@ -713,8 +712,7 @@ static void * ContextThread(LPVOID newContext) goto exit; /* avoids buffer overflow */ - if ((ctStr.cbRecvLength > sizeof(pbRecvBuffer)) - || (ctStr.cbSendLength > sizeof(pbSendBuffer))) + if (ctStr.cbSendLength > sizeof(pbSendBuffer)) { goto buffer_overflow; }