OS-4539: zfs receive_read_record() may allocate nothing

Details

Issue Type:Improvement
Priority:4 - Normal
Status:Resolved
Created at:2015-07-23T18:44:59.000Z
Updated at:2017-12-14T17:24:10.451Z

People

Created by:Joshua M. Clulow [X]
Reported by:Robert Mustacchi [X]
Assigned to:Jerry Jelinek [X]

Resolution

Fixed: A fix for this issue is checked into the tree and tested.
(Resolution Date: 2015-07-29T22:41:35.000Z)

Fix Versions

2015-08-06 UDDI (Release Date: 2015-08-06)

Related Issues

Description

A panic on DEBUG bits:

ffffff000d7146d0 vpanic()
ffffff000d714710 0xfffffffffbdb1afe()
ffffff000d714750 kmem_zalloc+0xed(0, 0)
ffffff000d7147f0 receive_read_record+0x190(ffffff000d714840)
ffffff000d7149b0 dmu_recv_stream+0x439(ffffff000d714ad0, ffffff024a686480, ffffff000d714b60, 8, ffffff0306592150)
ffffff000d714bb0 zfs_ioc_recv+0x1e7(ffffff0306591000)
ffffff000d714c60 zfsdev_ioctl+0x4ff(5a00000000, 5a1b, 8046150, 100003, ffffff02e9880718, ffffff000d714e48)
ffffff000d714ca0 cdev_ioctl+0x39(5a00000000, 5a1b, 8046150, 100003, ffffff02e9880718, ffffff000d714e48)
ffffff000d714cf0 spec_ioctl+0x60(ffffff024b4bc200, 5a1b, 8046150, 100003, ffffff02e9880718, ffffff000d714e48, 0)
ffffff000d714d80 fop_ioctl+0x55(ffffff024b4bc200, 5a1b, 8046150, 100003, ffffff02e9880718, ffffff000d714e48, 0)
ffffff000d714ea0 ioctl+0x9b(3, 5a1b, 8046150)
ffffff000d714f00 _sys_sysenter_post_swapgs+0x241()

It would appear that receive_read_record() will occasionally allocate a zero-length buffer, which causes a panic on DEBUG bits since OS-4194.

Comments

Comment by Jerry Jelinek [X]
Created at 2015-07-29T17:07:38.000Z
Updated at 2017-12-14T17:24:10.424Z

I hit this this morning while importing an image and coded a fix which allows me to successfully import:

--- a/usr/src/uts/common/fs/zfs/dmu_send.c
+++ b/usr/src/uts/common/fs/zfs/dmu_send.c
@@ -2084,8 +2084,10 @@ receive_read_record(struct receive_arg *ra)
        {
                struct drr_object *drro = &ra->rrd->header.drr_u.drr_object;
                uint32_t size = P2ROUNDUP(drro->drr_bonuslen, 8);
-               void *buf = kmem_zalloc(size, KM_SLEEP);
+               void *buf = NULL;
                dmu_object_info_t doi;
+               if (size > 0)
+                       buf = kmem_zalloc(size, KM_SLEEP);
                err = receive_read_payload_and_next_header(ra, size, buf);
                if (err != 0) {
                        kmem_free(buf, size);

I can take this bug and get this fix integrated if you'd like. I confirmed receive_read_payload_and_next_header properly handles a 0 size and a NULL buf ptr.


Comment by Bot Bot [X]
Created at 2015-07-29T22:41:01.000Z

illumos-joyent commit 6f2b4ac (branch master, by Jerry Jelinek)

OS-4539 zfs receive_read_record() may allocate nothing
Reviewed by: Joshua M. Clulow <jmc@joyent.com>