Page MenuHomeFreeBSD

Don't pass a user buffer pointer as the data pointer in a CCB.
ClosedPublic

Authored by jhb on Apr 18 2020, 8:22 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Dec 16, 1:35 AM
Unknown Object (File)
Oct 11 2025, 8:25 PM
Unknown Object (File)
Oct 11 2025, 4:44 AM
Unknown Object (File)
Sep 13 2025, 2:41 AM
Unknown Object (File)
Sep 12 2025, 3:33 AM
Unknown Object (File)
Sep 2 2025, 3:41 PM
Unknown Object (File)
Aug 17 2025, 5:19 PM
Unknown Object (File)
Aug 14 2025, 6:35 AM
Subscribers

Details

Summary

Allocate a temporary buffer in the kernel to serve as the CCB data
pointer for a pass-through transaction and using copyin/copyout to
shuffle the data to/from the user buffer.

Test Plan
  • compile tested only, found on CheriBSD where user and kernel pointers have different types, so conflating the two gives compile errors

Diff Detail

Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 30596
Build 28337: arc lint + arc unit

Event Timeline

sys/cam/scsi/scsi_sg.c
633

Dir & CAM_DIR_OUT?

Modulo accepting or rejecting @imp's suggestion this looks good.

This revision is now accepted and ready to land.Apr 20 2020, 5:08 PM
sys/cam/scsi/scsi_sg.c
582

That is why I changed this btw, because BOTH != IN | OUT.

633

If only that would work. :(

From cam.h (and I don't know why this is so dumb):

	CAM_DIR_BOTH		= 0x00000000,/* Data direction (00:IN/OUT)    */
	CAM_DIR_IN		= 0x00000040,/* Data direction (01:DATA IN)   */
	CAM_DIR_OUT		= 0x00000080,/* Data direction (10:DATA OUT)  */
	CAM_DIR_NONE		= 0x000000C0,/* Data direction (11:no data)   */
	CAM_DIR_MASK		= 0x000000C0,/* Data direction Mask	      */
sys/cam/scsi/scsi_sg.c
633

Then we should seriously consider changing this.

jhb added inline comments.
sys/cam/scsi/scsi_sg.c
633

Hmm, rS216088 is when the 0 value was changed from RESERVED to BOTH. Maybe @ken has some thoughts?

I do think if we change CAM_DIR_BOTH we should probably do that as a separate change from this though? Do we think this patch is ok given the current CAM_DIR_* values?

Yep, can tackle the CAM_DIR problem separately.

sys/cam/scsi/scsi_sg.c
633

I added CAM_DIR_BOTH for SMP commands, because they are effectively bidirectional. The request was too big to allocate statically in the CCB.

The SCSI standard also defines bi-directional commands, at least with opcode 0x9D (Service Action Bi-Directional).

In other words, we can't remove bi-directional support, we need it in some form. This is also why it is typically written:

if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_X)

The problem isn't the existence of bi-directional commands, it's that DIR_BOTH == 0, not an OR'ing of DIR_IN and DIR_OUT, as would be expected.

The problem isn't the existence of bi-directional commands, it's that DIR_BOTH == 0, not an OR'ing of DIR_IN and DIR_OUT, as would be expected.

Well, CAM_DIR_NONE was defined as all 1's from the beginning. It was that way in the ANSI CAM spec. 0's was defined as CAM_DIR_RESV.

So that is why it is that way...

Blah, but thanks for the history on it, I guess I never noticed before. I would be surprised if this hasn't caused bugs. There's no longer an active standards group, and even if there was I'd advocate that this is wrong. Let's follow up with a change on it.

Blah, but thanks for the history on it, I guess I never noticed before. I would be surprised if this hasn't caused bugs. There's no longer an active standards group, and even if there was I'd advocate that this is wrong. Let's follow up with a change on it.

I'd love to change this too... but I worry about userland/kernel ABI changes being hard to transition...