Print this page
3469 dbuf_read_impl shows too much enthusiasm
Reviewed by: Dan McDonald <danmcd@omniti.com>

@@ -639,12 +639,29 @@
                 ASSERT3U(bonuslen, <=, db->db.db_size);
                 db->db.db_data = zio_buf_alloc(DN_MAX_BONUSLEN);
                 arc_space_consume(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
                 if (bonuslen < DN_MAX_BONUSLEN)
                         bzero(db->db.db_data, DN_MAX_BONUSLEN);
-                if (bonuslen)
-                        bcopy(DN_BONUS(dn->dn_phys), db->db.db_data, bonuslen);
+                if (bonuslen) {
+                        /*
+                         * Absent byzantine on-disk corruption, we fully expect
+                         * our bonuslen to be no more than DN_MAX_BONUSLEN --
+                         * but we nonetheless explicitly clamp it on the
+                         * bcopy() to prevent any on-disk corruption from
+                         * becoming rampant in-kernel corruption.
+                         */
+                        if (bonuslen > DN_MAX_BONUSLEN) {
+                                DTRACE_PROBE3(dbuf__read__impl__toolong, int,
+                                    bonuslen, dnode_t *, dn, dmu_buf_impl_t *,
+                                    db);
+                                bcopy(DN_BONUS(dn->dn_phys), db->db.db_data,
+                                    DN_MAX_BONUSLEN);
+                        } else {
+                                bcopy(DN_BONUS(dn->dn_phys), db->db.db_data,
+                                    bonuslen);
+                        }
+                }
                 DB_DNODE_EXIT(db);
                 db->db_state = DB_CACHED;
                 mutex_exit(&db->db_mtx);
                 return;
         }