DF-2208 / rig_head.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | /* * DF-2208 / DF-2209 verbatim-code rig - HEAD * * Compiles the UNMODIFIED production functions * drm_sysfs_connector_add (sys/dev/drm/drm_sysfs.c:31-46) * drm_sysfs_connector_remove (sys/dev/drm/drm_sysfs.c:48-54) * kernel-resident and drives them with fabricated drm_connector state. * * Everything below the "production-faithful shims" banner mirrors the * shipped definitions byte-for-byte in SHAPE (field order, macro * semantics, flag values); the ONLY deltas are: * - allocation faults can be injected (rig_fail_kzalloc / * rig_fail_kasprintf) at exactly the call sites the findings cite, * modelling the Linux-GFP_KERNEL OOM window that the finding claims * (on DragonFly GFP_KERNEL == M_WAITOK|M_CACHEALIGN, and M_WAITOK * allocations PANIC or BLOCK instead of returning NULL -- see * sys/kern/kern_slaballoc.c:869-878 limit path, :1722-1724 * kernel_map path, :1786-1800 page-starvation retry loop). * - the pool is M_DF22 (own malloc_type) instead of M_DRM so the rig * is self-contained (no drm.ko dependency); zone/slab semantics of * kmalloc/kfree are the real allocator. * - DRM_DEBUG prints unconditionally (content capture). */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/malloc.h> #include <sys/sysctl.h> #include <sys/stdarg.h> MALLOC_DEFINE(M_DF22, "df22pool", "DF2208/DF2209 rig pool (mirrors M_DRM)"); /* ------------------------------------------------------------------ */ /* Production-faithful type shims */ /* struct kobject ......... include/linux/kobject.h:50-54 (order) */ /* struct device .......... include/linux/device.h:44-54 (order) */ /* offsetof(struct device, kobj.name) == 8 in production AND here */ /* ------------------------------------------------------------------ */ struct kref { int refcount; }; /* linux/kref.h */ struct kobj_type { void (*release)(void *); const void *sysfs_ops; void **default_attrs; }; struct kobject { const char *name; /* kobject.h:51 */ struct kref kref; /* kobject.h:52 */ struct kobj_type *ktype; /* kobject.h:53 */ }; struct dev_pm_info { int rig_pad; }; /* stand-in, past kobj */ struct device { struct device *parent; /* device.h:45 */ struct kobject kobj; /* device.h:47 */ void *bsddev; /* device.h:49 (device_t) */ void *driver_data; /* device.h:51 */ struct dev_pm_info power; /* device.h:53 */ }; struct drm_minor { int index; }; struct drm_device { struct drm_minor *primary; }; struct drm_connector { struct device *kdev; /* drm_connector.h:833 */ struct drm_device *dev; char name[32]; /* drm_connector.h (name[]) */ }; /* linux/gfp.h:16 verbatim */ #define GFP_KERNEL (M_WAITOK | M_CACHEALIGN) /* drm_print.h:388 -- normally debug-flag gated; here: capture */ #define DRM_DEBUG(fmt, ...) \ kprintf("DF22 [drm_sysfs] " fmt, ##__VA_ARGS__) /* ------------------------------------------------------------------ */ /* Fault-injecting allocator shims */ /* kzalloc == include/linux/slab.h:35 kmalloc(size, M_DRM, f|M_ZERO)*/ /* kfree == include/linux/slab.h:38-42 _kfree(ptr, M_DRM) guarded */ /* kasprintf== drm_dragonfly.c:87-94 -> kvasprintf drm_dragonfly.c:65 */ /* ------------------------------------------------------------------ */ static int rig_fail_kzalloc; /* inject NULL at drm_sysfs.c:39 */ static int rig_fail_kasprintf; /* inject NULL at drm_sysfs.c:40 */ static unsigned long rig_kzalloc_calls, rig_kfree_calls, rig_kasprintf_calls; static unsigned long rig_alloc_events, rig_free_events; #undef kzalloc #define kzalloc(size, flags) rig_kzalloc((size), (flags)) static void * rig_kzalloc(size_t size, int flags) { void *p; rig_kzalloc_calls++; if (rig_fail_kzalloc) return (NULL); /* INJECTION (see file header) */ p = kmalloc(size, M_DF22, flags | M_ZERO); /* slab.h:35 shape */ if (p != NULL) rig_alloc_events++; return (p); } #undef kfree #define kfree(ptr) do { \ if ((ptr) != NULL) { \ rig_kfree_calls++; \ rig_free_events++; \ _kfree((void *)(ptr), M_DF22); \ } \ } while (0) /* drm_dragonfly.c:65-82 verbatim shape, M_DF22 pool */ static char * rig_vasprintf(int flags, const char *format, va_list ap) { char *str; size_t size; va_list aq; va_copy(aq, ap); size = kvsnprintf(NULL, 0, format, aq); va_end(aq); str = kmalloc(size + 1, M_DF22, flags); if (str == NULL) return (NULL); /* drm_dragonfly.c:78-79 */ rig_alloc_events++; kvsnprintf(str, size + 1, format, ap); return (str); } #undef kasprintf #define kasprintf(flags, format, ...) \ rig_kasprintf((flags), (format), ##__VA_ARGS__) static char * rig_kasprintf(int flags, const char *format, ...) { va_list ap; char *str; rig_kasprintf_calls++; if (rig_fail_kasprintf) return (NULL); /* INJECTION (see file header) */ va_start(ap, format); str = rig_vasprintf(flags, format, ap); va_end(ap); return (str); } /* verbatim (baseline) + fix.diff variants, extracted by build.sh */ int drm_sysfs_connector_add(struct drm_connector *connector); void drm_sysfs_connector_remove(struct drm_connector *connector); int drm_sysfs_connector_add_fixed(struct drm_connector *connector); void drm_sysfs_connector_remove_fixed(struct drm_connector *connector); |