Vai al contenuto

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)

  1. ✅ Verificare quale costanti.cpy è usata attualmente bash grep "k-max-col-grid" cpy/costanti.cpy

  2. ✅ Controllare date compilazione programmi bash ls -lh wpoptre cogv40 dialogs setmask

  3. ✅ Aggiungere display w-ig-n-col in setmask (test)

Fase 2: Fix temporaneo (1 ora)

  1. ✅ 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

  2. ✅ Ricompilare setmask con costanti aggiornate

Fase 3: Fix definitivo (2 ore)

  1. ✅ Ricompilare TUTTI i programmi della catena con stessa versione costanti
  2. ✅ Aggiungere check validazione permanente
  3. ✅ 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

  1. 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!

  2. Nessun controllo bounds prima accesso array

  3. Non ci sono IF per verificare w-ig-n-col < k-max-col-grid

  4. Disallineamento versioni costanti

  5. Vecchio: 200
  6. Nuovo: 500
  7. Rischio: programmi compilati con versioni diverse

💡 Raccomandazioni a lungo termine

  1. Standard di compilazione
  2. Sempre usare stessa versione costanti.cpy per tutti i programmi
  3. Documentare versione costanti in header programma
  4. Script automatico per ricompilare catene dipendenze

  5. Validazioni difensive

  6. Aggiungere check bounds su TUTTI gli array OCCURS DEPENDING ON
  7. Validare parametri LINKAGE SECTION all'inizio programma
  8. Usare EVALUATE ALSO per gestire valori fuori range

  9. Logging e diagnostica

  10. Aggiungere logging valori critici (w-ig-n-col, ecc.)
  11. Creare utility per dump strutture dati
  12. Implementare assert COBOL custom

  13. Testing

  14. Test con valori limite (0, max, max+1)
  15. Test con dati corrotti
  16. Test catena completa chiamate

📚 Riferimenti codice


⚠️ 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).