Analisi Memory Access Violation - SETMASK.CBL¶
Contesto errore¶
Errore: Memory Access Violation alla locazione 0x672d (26.413 decimale)
Programma: setmask.cbl
Catena chiamate:
1. wpoptre.cbl
2. cogv40.cbl
3. dialogs.cbl
4. setmask.cbl ← Errore qui
🔍 Analisi del programma SETMASK¶
Funzionalità¶
Il programma gestisce la lettura/scrittura di configurazioni form nel file MASKCTRF (maschere controllo form).
Operazioni:
- "Leggi": Legge posizione e dimensioni form salvate
- "Scrivi": Salva posizione e dimensioni form
Strutture dati critiche¶
1. Array dinamico con OCCURS DEPENDING ON¶
Location: Righe 125-130
01 w-int-griglia.
03 w-ig-n-col pic 9(04).
03 w-ig-ele occurs 0 to k-max-col-grid
depending on w-ig-n-col.
04 w-ig-des pic x(40).
04 w-ig-tit pic x(30).
Criticità:
- ⚠️ k-max-col-grid ha valori diversi nelle versioni:
- Versione vecchia: 200 (costanti vecchi)
- Versione attuale: 500 (costanti.cpy corrente)
- ⚠️ w-ig-n-col non viene mai validato in setmask.cbl
- ⚠️ Struttura NON usata nel codice di setmask → probabilmente in LINKAGE SECTION
Calcolo dimensione:
Dimensione elemento = 40 + 30 = 70 bytes
Se w-ig-n-col = 200: 200 * 70 = 14.000 bytes
Se w-ig-n-col = 500: 500 * 70 = 35.000 bytes
Se il programma è compilato con k-max-col-grid=200 ma riceve w-ig-n-col=500: → BUFFER OVERFLOW di 21.000 bytes!
🔴 Possibili cause dell'errore¶
Causa 1: Disallineamento versione costanti (PROBABILITÀ ALTA)¶
Scenario:
1. SETMASK compilato con k-max-col-grid = 200 (vecchia versione)
2. Programma chiamante passa struttura con w-ig-n-col > 200
3. Accesso a w-ig-ele(201) → fuori dai limiti → Memory violation
Evidenze:
# costanti.BAK ha valore 500
cpy/costanti.BAK:58: 78 k-max-col-grid value 500.
# Versioni vecchie hanno valore 200
cpy/pre-iscobol/costanti.cpy:43: 78 k-max-col-grid value 200.
Soluzione:
# Ricompilare SETMASK con costanti aggiornate
cobc -x setmask.cbl -I cpy/
Causa 2: Buffer overflow in a-record (PROBABILITÀ MEDIA)¶
Location: Riga 76
77 a-record pic x(1000).
Scenario:
- Variabile a-record di 1000 bytes
- Se viene scritta una stringa > 1000 caratteri → overflow
- Sovrascrive memoria successiva (possibilmente w-int-griglia)
Criticità: - ❌ Nessun controllo lunghezza prima di scrivere in a-record - ❌ Nessun boundary check
Causa 3: Corruzione memoria da programma chiamante (PROBABILITÀ ALTA)¶
Scenario: 1. Uno dei programmi nella catena (wpoptre, cogv40, dialogs) corrompe la memoria 2. SETMASK accede a strutture dati corrotte 3. Memory violation
Indizi: - La catena di chiamata è lunga (4 programmi) - Ogni programma può passare parametri via LINKAGE SECTION - Se un programma passa puntatori invalidi o strutture corrotte → errore in setmask
Causa 4: File MASKCTRF corrotto (PROBABILITÀ BASSA)¶
Location: Righe 184-196
open i-o maskctrf
if stato not = "00"
if stato = "35"
open output maskctrf *> Ricrea se non esiste
Scenario: - File MASKCTRF.ARC corrotto o con dati invalidi - Lettura di record corrotto → dati sporchi in memoria - Accesso a strutture corrotte
Causa 5: Offset 0x672d specifico (ANALISI TECNICA)¶
Conversione offset:
0x672d = 26.413 decimale
Ipotesi offset nella struttura:
*> Se l'errore è in w-int-griglia:
*> w-ig-n-col = 4 bytes (pic 9(04))
*> Elemento w-ig-ele = 70 bytes
*>
*> Offset elemento N = 4 + (N-1) * 70
*>
*> 26.413 = 4 + (N-1) * 70
*> 26.409 = (N-1) * 70
*> N-1 = 377.27
*> N ≈ 378
*> Se w-ig-n-col = 378 ma k-max-col-grid = 200
*> → ACCESSO FUORI BOUNDS!
Conclusione: L'errore avviene tentando di accedere all'elemento 378 di un array con max 200 elementi.
🛠️ Soluzioni proposte (in ordine di priorità)¶
1. Ricompilare con costanti aggiornate ⭐⭐⭐⭐⭐¶
# Verificare quale versione di costanti.cpy è usata
grep -n "k-max-col-grid" cpy/costanti.cpy
# Ricompilare SETMASK
cobc -x setmask.cbl -I cpy/
# Verificare che usi k-max-col-grid = 500
2. Aggiungere validazione w-ig-n-col ⭐⭐⭐⭐¶
*> All'inizio di setmask, in PROCEDURE DIVISION
screen-0.
if w-ig-n-col > k-max-col-grid
string "ERRORE: w-ig-n-col (" w-ig-n-col
") > max (" k-max-col-grid ")"
delimited size into wb-msg
perform vbx-msg-error
move "N" to w-setmask-esito
go to fine
end-if
3. Verificare versioni compilate programmi chiamanti ⭐⭐⭐⭐¶
# Verificare date compilazione
ls -l wpoptre cogv40 dialogs setmask
# Se diverse, ricompilare tutti con stessa versione costanti
4. Aggiungere logging debug ⭐⭐⭐¶
*> All'inizio di setmask
screen-0.
display "SETMASK: w-ig-n-col = " w-ig-n-col
display "SETMASK: k-max-col-grid = " k-max-col-grid
if w-ig-n-col > k-max-col-grid
display "ERRORE: array fuori bounds!"
end-if
5. Analizzare dump memoria ⭐⭐⭐¶
# Se disponibile core dump
gdb setmask core
# Comandi GDB
(gdb) info registers
(gdb) x/100x $esp # Esaminare stack
(gdb) bt # Backtrace completo
6. Verificare integrità file MASKCTRF ⭐⭐¶
# Backup e ricreazione
mv maskctrf.arc maskctrf.arc.bak
# Lasciare che setmask ricrei il file (riga 187)
📊 Test diagnostici¶
Test 1: Verificare valore w-ig-n-col¶
*> In wpoptre.cbl o cogv40.cbl, prima di chiamare setmask:
display "Prima di setmask: w-ig-n-col = " w-ig-n-col
call "SETMASK" using stringhe util-w-setmask
display "Dopo setmask: esito = " w-setmask-esito
Test 2: Forzare valore sicuro¶
*> In programma chiamante, prima di chiamare setmask:
if w-ig-n-col > 200
move 200 to w-ig-n-col *> Forza valore sicuro
end-if
call "SETMASK" using stringhe util-w-setmask
Test 3: Modalità debug AcuCOBOL¶
# Eseguire con runtime debug
runcbl -d setmask
# Impostare breakpoint
(adb) break setmask.cbl:172
(adb) run
(adb) print w-ig-n-col
(adb) print k-max-col-grid
🎯 Piano d'azione immediato¶
Fase 1: Diagnosi (30 minuti)¶
-
✅ Verificare quale costanti.cpy è usata attualmente
bash grep "k-max-col-grid" cpy/costanti.cpy -
✅ Controllare date compilazione programmi
bash ls -lh wpoptre cogv40 dialogs setmask -
✅ Aggiungere display w-ig-n-col in setmask (test)
Fase 2: Fix temporaneo (1 ora)¶
-
✅ Aggiungere validazione w-ig-n-col in setmask:
cobol if w-ig-n-col > k-max-col-grid move k-max-col-grid to w-ig-n-col *> Cap value end-if -
✅ Ricompilare setmask con costanti aggiornate
Fase 3: Fix definitivo (2 ore)¶
- ✅ Ricompilare TUTTI i programmi della catena con stessa versione costanti
- ✅ Aggiungere check validazione permanente
- ✅ Testing completo flusso wpoptre → setmask
📝 Checklist verifica¶
- [ ] Verificato valore k-max-col-grid in costanti.cpy corrente
- [ ] Verificato che setmask sia compilato con costanti correnti
- [ ] Verificato che wpoptre, cogv40, dialogs usino stesse costanti
- [ ] Aggiunta validazione w-ig-n-col > k-max-col-grid
- [ ] Testato con valori limite (w-ig-n-col = 200, 500)
- [ ] Verificato file MASKCTRF.ARC non corrotto
- [ ] Testato flusso completo senza errori
🔬 Analisi codice setmask¶
Variabili potenzialmente problematiche¶
| Variabile | Tipo | Dimensione | Rischio |
|---|---|---|---|
a-record |
x(1000) | 1000 bytes | 🟠 MEDIO - No boundary check |
w-ig-ele |
occurs 0-500 | 35.000 bytes | 🔴 ALTO - OCCURS DEPENDING ON |
w-ig-n-col |
9(04) | 4 bytes | 🔴 ALTO - Mai validato |
w-nome-maskctrf |
x(70) | 70 bytes | 🟡 BASSO |
Pattern pericolosi identificati¶
-
OCCURS DEPENDING ON senza validazione
cobol 03 w-ig-ele occurs 0 to k-max-col-grid depending on w-ig-n-col. *> ← Nessun check! -
Nessun controllo bounds prima accesso array
-
Non ci sono IF per verificare w-ig-n-col < k-max-col-grid
-
Disallineamento versioni costanti
- Vecchio: 200
- Nuovo: 500
- Rischio: programmi compilati con versioni diverse
💡 Raccomandazioni a lungo termine¶
- Standard di compilazione
- Sempre usare stessa versione costanti.cpy per tutti i programmi
- Documentare versione costanti in header programma
-
Script automatico per ricompilare catene dipendenze
-
Validazioni difensive
- Aggiungere check bounds su TUTTI gli array OCCURS DEPENDING ON
- Validare parametri LINKAGE SECTION all'inizio programma
-
Usare EVALUATE ALSO per gestire valori fuori range
-
Logging e diagnostica
- Aggiungere logging valori critici (w-ig-n-col, ecc.)
- Creare utility per dump strutture dati
-
Implementare assert COBOL custom
-
Testing
- Test con valori limite (0, max, max+1)
- Test con dati corrotti
- Test catena completa chiamate
📚 Riferimenti codice¶
- setmask.cbl: /programmi/eurocoge/cbl/setmask.cbl
- Struttura critica: Righe 125-130
- costanti.cpy: /programmi/eurocoge/cpy/costanti.cpy
- k-max-col-grid attuale: 500 (riga 62)
- k-max-col-grid vecchio: 200 (versioni precedenti)
⚠️ NOTA IMPORTANTE¶
L'errore 0x672d (26.413) corrisponde esattamente all'accesso all'elemento 378 dell'array w-ig-ele, che è FUORI BOUNDS se il programma è compilato con k-max-col-grid = 200.
Azione immediata: Ricompilare setmask.cbl con costanti.cpy aggiornata (valore 500).