|
416 | 416 | ,@body |
417 | 417 | (setf (read-storage-offset ,storage) (+ ,original-offset ,reserve-bytes))))))) |
418 | 418 |
|
| 419 | +(defmacro sap-ref-fixnum (sap offset) |
| 420 | + "This is hideous. On SBCL we have stored the data fixnum encoded, which means shifted up |
| 421 | + by one so we shift it back to generate an 'unencoded' fixnum. We would normally just have |
| 422 | + blitted things back into the array without telling sbcl what we are doing, but in the |
| 423 | + presence of potentially malicious data, we have to make sure that our numbers are fixnums, |
| 424 | + so we shift them back down which makes it impossible for malicious actor to put bogus dat |
| 425 | + in the array sap. On non sbcl we just check to make sure things are fixnums because we |
| 426 | + did not blit the data out" |
| 427 | + #+sbcl |
| 428 | + `(ash (signed-sap-ref-64 ,sap ,offset) -1) |
| 429 | + #-sbcl |
| 430 | + (let ((a (gensym))) |
| 431 | + `(let ((,a (signed-sap-ref-64 ,sap ,offset))) |
| 432 | + (if (typep ,a 'fixnum) |
| 433 | + ,a |
| 434 | + (unexpected-data "non fixnum in fixnum array"))))) |
| 435 | + |
419 | 436 | (defun restore-simple-specialized-vector (storage) |
420 | 437 | (declare (optimize (speed 3) (safety 1))) |
421 | 438 | (let ((num-elts (restore-tagged-unsigned-fixnum/interior storage))) |
|
452 | 469 | (bit (reader 1 nil)) |
453 | 470 | (single-float (reader 32 nil sap-ref-single (simple-array single-float (*)))) |
454 | 471 | (double-float (reader 64 nil sap-ref-double (simple-array double-float (*)))) |
455 | | - (fixnum (reader 64 t signed-sap-ref-64 (simple-array fixnum (*)))) |
| 472 | + (fixnum (reader 64 t sap-ref-fixnum (simple-array fixnum (*)))) |
456 | 473 | (otherwise (unexpected-data "array of unexpected type")))))) |
457 | 474 | #+sbcl |
458 | 475 | (with-pinned-objects (sv) |
459 | | - (let ((target-sap (vector-sap sv))) |
460 | | - (chunked/read |
461 | | - storage num-bytes |
462 | | - (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
463 | | - (copy-sap target-sap data-start/bytes source-sap source-sap-offset (the fixnum (- data-end-bytes data-start/bytes))))))) |
| 476 | + (multiple-value-bind (type bits-per-elt) |
| 477 | + (encoded-element-type-to-type/packing encoded-element-info) |
| 478 | + (declare (ignorable bits-per-elt)) |
| 479 | + (cond |
| 480 | + ((eq type 'fixnum) |
| 481 | + ;; We have to be careful here, as just blitting potentially malicious 64 |
| 482 | + ;; bit data into a simple-array fixnum (*) can cause issues. |
| 483 | + ;; Now the problem is that we already "fixnum encoded" the data if it is |
| 484 | + ;; correct, which means that it needs to be un-fixnum-ized |
| 485 | + (reader 64 t sap-ref-fixnum (simple-array fixnum (*)))) |
| 486 | + (t |
| 487 | + (let ((target-sap (vector-sap sv))) |
| 488 | + ;; OK, so we have a problem here --- if the fixnums aren't actually fixnums |
| 489 | + ;; then we end up screwing things up. |
| 490 | + (chunked/read |
| 491 | + storage num-bytes |
| 492 | + (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
| 493 | + (copy-sap target-sap data-start/bytes source-sap source-sap-offset (the fixnum (- data-end-bytes data-start/bytes)))))))))) |
464 | 494 | sv)))) |
465 | 495 |
|
466 | 496 | ;; for ccl ccl::array-data-and-offset would be fine... it's been a stable interface |
|
511 | 541 | (type-of sa) num-bytes array-dimensions encoded-element-info) |
512 | 542 | (with-pinned-objects (sa) |
513 | 543 | (let ((target-sap (array-sap sa))) |
514 | | - (chunked/read |
515 | | - storage num-bytes |
516 | | - (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
517 | | - (copy-sap target-sap data-start/bytes source-sap source-sap-offset (- data-end-bytes data-start/bytes)))))) |
| 544 | + (multiple-value-bind (type bits-per-elt) |
| 545 | + (encoded-element-type-to-type/packing encoded-element-info) |
| 546 | + (declare (ignorable bits-per-elt)) |
| 547 | + (cond |
| 548 | + ((eq type 'fixnum) |
| 549 | + ;; We have to be careful here, as just blitting potentially malicious 64 |
| 550 | + ;; bit data into a simple-array fixnum (*) can cause issues. |
| 551 | + (sb-kernel:with-array-data ((sv sa) (start) (end)) |
| 552 | + (declare (ignore start end)) |
| 553 | + (reader 64 t sap-ref-fixnum (simple-array fixnum (*))))) |
| 554 | + (t |
| 555 | + (chunked/read |
| 556 | + storage num-bytes |
| 557 | + (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
| 558 | + (copy-sap target-sap data-start/bytes source-sap source-sap-offset (- data-end-bytes data-start/bytes))))))))) |
518 | 559 | sa))) |
0 commit comments