-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Here is a patch adapted to the OpenSolaris tree.  We need it when
porting ZFS to FreeBSD but it seems to be useful for general consumption.

Currently:

 - vsnprintf() will not call va_end() and the va_list passed is not defined;
 - subsequent vsprintf() references the passed va_list again.

On FreeBSD/amd64, the latter vsprintf() would write undefined result,
which tends to cause random panics.

It turns out that the undefined behavior is defined in standard, so we
have added a pair of va_copy() and va_end() calls and operate on the
copy for the first vsnprintf().

Cheers,
- -- 
Xin LI <[email protected]>            http://www.delphij.net/
FreeBSD - The Power to Serve!          Live free or die
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (FreeBSD)

iQEcBAEBAgAGBQJL2IBlAAoJEATO+BI/yjfBkOUH+wffwvwqQQT4Y2S3dkKW1Md9
CAmBzGlQJWGlteCUTKhxD7KMIaIfaq6GoCJJg5u1XWdxxOIILDW2wjyE03zDnCLY
HQJwGcbvTyc0AfiDlR/OuELDrHEAKWKE3FRQHhRjR4n8Go5k9IQCzqVvESmpDHZR
tfOJmpq6hm2lMbVTasR64n9+PrSPBhimKUh0irhQoiK2tdnweazeBPBV9nqwJoqB
erJDzI94I9u1whXpmJyttgVClqDzvrvK5v/wappfljbOH7tI4AQctRu2+s/eZrxr
0L0lro3+ZAeR1tYx63/CyvJcYf7NvmxT7ABfpV9rh6K14v+LyvoztrwmLtiJXEI=
=KTmF
-----END PGP SIGNATURE-----
diff -r 5faf8d02346b usr/src/uts/common/fs/zfs/spa_history.c
--- a/usr/src/uts/common/fs/zfs/spa_history.c   Wed Apr 28 12:15:56 2010 -0600
+++ b/usr/src/uts/common/fs/zfs/spa_history.c   Wed Apr 28 11:25:16 2010 -0700
@@ -421,6 +421,7 @@ log_internal(history_internal_events_t e
     dmu_tx_t *tx, cred_t *cr, const char *fmt, va_list adx)
 {
        history_arg_t *ha;
+       va_list adx2;
 
        /*
         * If this is part of creating a pool, not everything is
@@ -429,10 +430,14 @@ log_internal(history_internal_events_t e
        if (tx->tx_txg == TXG_INITIAL)
                return;
 
+       va_copy(adx2, adx);
+
        ha = kmem_alloc(sizeof (history_arg_t), KM_SLEEP);
-       ha->ha_history_str = kmem_alloc(vsnprintf(NULL, 0, fmt, adx) + 1,
+       ha->ha_history_str = kmem_alloc(vsnprintf(NULL, 0, fmt, adx2) + 1,
            KM_SLEEP);
 
+       va_end(adx2);
+
        (void) vsprintf(ha->ha_history_str, fmt, adx);
 
        ha->ha_log_type = LOG_INTERNAL;
_______________________________________________
zfs-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/zfs-code

Reply via email to