NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/47892: bad mutex handling in /src/sys/opencrypto/crypto.c
>Number: 47892
>Category: kern
>Synopsis: bad mutex handling in /src/sys/opencrypto/crypto.c
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jun 05 10:50:00 +0000 2013
>Originator: Dr. Wolfgang Stukenbrock
>Release: NetBSD 6.1
>Organization:
Dr. Nagler & Company GmbH
>Environment:
System: NetBSD test-s0 5.1.2 NetBSD 5.1.2 (NSW-WS) #3: Fri Dec 21 15:15:43 CET
2012 wgstuken@test-s0:/usr/src/sys/arch/amd64/compile/NSW-WS amd64
Architecture: x86_64
Machine: amd64
>Description:
In function crypto_invoke() there are two calls to the crypto session
managment functions.
These functions now (since 6.x I think) allocates the crypto_mtx
themself so that it may not
be aquired when calling crypto_freesession() and/or
crypto_newsession(). OK so far.
But in crypto_invoke() the only mutex-handling is the following:
mutex_exit(&crypto_mtx);
crypto_freesession(crp->crp_sid);
mutex_enter(&crypto_mtx);
So when calling crypto_freesession() the "crypto_mtx" mutex is
released, but not when calling crypto_newsession().
This cannot be OK !!!!
I think crypto_invoke() is currently called without any of the crypto
mutexes aquired, so the "mutex_exit(&crypto_mtx);"
would crash the kernel. This may have been overlooked, because the
CRYPTOCAP_F_CLEANUP case is very rare ...
On the other hand crypto_invoke() accesses the global variable
crypto_drivers_num and that one may change when an
additional driver registers via crypto_get_driverid(). Same for the
cc_flags field inside the driver itself on unregister calls.
Therefore the "crypto_mtx" mutex need to be aquired - as far as I think.
I'm not shure if a driver may ever (un-)register at runtime, but if not
that should be stated somewhere in a comment and
a security assertion or something like this should be added to the
register function.
(and then the whole unregister support makes no sence ...)
If a driver unregister and all CAP are gone, the whole CAP-strucure is
cleared with memset(...).
This will kill cc_process and cc_arg fields, so if CRYPTOCAP_F_CLEANUP
is ever set, theese fields are NULL (or 0)
and the current implementation will end up by callein NULL as function.
By the way: the comment "Driver has unregistered; ..." is wrong,
because the variable crypto_drivers_num never gets
lower as before.
So either we have a very strange HID here (derived from the crp_sid) or
we will always fall into the case
"hid < crypto_drivers_num)". This looks like historic code that should
be cleaned up.
remark: the korresponding function "crypto_kinvoke" allocates the
crypto_mtx mutex. So it looks like that this is simply
missing here
>How-To-Repeat:
found while validating/integrating private changes/patches into 6.1
release
>Fix:
Not realy know at the moment, because I'm not 100% confirm with the
locking here till now.
As long as no crypto-driver registers or unregisters at runtime of the
system, CRYPTOCAP_F_CLEANUP is never set
and no problems should came up.
It may be a sollution (as quick shot) to just remove the mutext
operations from the
"mutex_exit(&crypto_mtx); crypto_freesession(crp->crp_sid);
mutex_enter(&crypto_mtx);" sequence, if no mutex is required.
But this does not honor the other mentioned things.
I think the mutex is needed and it should be handled as in
crypto_kinvoke().
Someone with deeper knowledge about the sence of the mutexes in
opencrypto should have a look at this.
>Unformatted:
Home |
Main Index |
Thread Index |
Old Index