κ°μ π
νλ¬ μ νμ¬μμ 리λ
μ€ λλ°μ΄μ€ λλΌμ΄λ² μ½λμ MISRA-C, CERT-C λ£°μ
λ€μ
μ΄μ©νμ¬ μ μ λΆμμ νλ λμ€, strcpy
μ λν warning μ μ΄λ»κ² μ²λ¦¬ν κΉ
κ³ λ―Όνλ€κ° LWN μμ Ushering out strlcpy()
λΌλ κΈ°μ¬λ¬Έμ μ½κ² λμλ€. string copyμ λν κΈμ μ½κ³ λΈλ‘κ·Έμ μ 리νμκ³
νλλ° μ΄μ μμΌ κ²¨μ° μ 리ν μ μκ² λμλ€.
리λ μ€ μ»€λμμ λ¬Έμμ΄ λ³΅μ¬λ₯Ό μν΄ λ§λ€μ΄μ§ 맀ν¬λ‘λ€μ λ€μνλ€. λͺ κ°μ μ리μ¦(?)κ° μλλ° μ 리ν΄λ³΄λ©΄ λ€μκ³Ό κ°λ€.
- strcpy
- strncpy
- strlcpy
- strscpy
strcpy π
strcpy
λ₯Ό λνλ΄λ©΄ μλμ κ°μ΄ κ°λ¨νλ€.
νμ§λ§ μ΄ κ²½μ° λ°μκ°λ₯ν λ¬Έμ λ destination
ν¬κΈ°κ° source
λ³΄λ€ μμ κ²½μ°
overrun
μ΄ λ°μνλ€λ μ μ΄λ€. μ΄λ₯Ό κ°μ νκ³ μ λ§λ€μ΄μ§ κ²μ΄ strncpy
μ΄λ€.
strncpy π
strncpy
λ μλμ κ°μ νλ‘ν νμ
μ κ°λλ€.
|
|
λͺ
μμ μΌλ‘ 볡μ¬νκ³ μ νλ ν¬κΈ°λ₯Ό μΈμλ‘ λ겨주기 λλ¬Έμ μμ strcpy
μ²λΌ
overrun
μ΄ λ°μν μΌμ΄ κ±°μ μλ€. νμ§λ§ μ΄μ²λΌ λ¬Έμ κ° μμ΄λ³΄μ΄λ λ°μλ
μ μ¬μ μΈ λ¬Έμ κ° μλ€. μλμ λ κ°μ§ κ²½μ°λ₯Ό μ΄ν΄λ³΄μ.
- μΈμ
n
보λ€source
κ° μ§§μ κ²½μ° - μΈμ
n
보λ€source
κ° κΈΈ κ²½μ°
첫 λ²μ§Έ κ²½μ°μλ source
κ° μΈμ n
λ³΄λ€ μμλ°λ λΆκ΅¬νκ³ μ 체 array
λ₯Ό
볡μ¬νκ² λλ λΆνμν μ°μ°μ΄ λ°μν μ μλ€.
λ λ²μ§Έ κ²½μ°μλ source
κ° μΈμ n
λ³΄λ€ ν° κ²½μ°μ΄λ€. μ΄ κ²½μ° destination
μ
NULL
λ‘ λλμ§ μκ² λΌ λ¬Έμμ΄λ‘μ¨ μ¬μ©ν μ μλ€. μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄
μ¬μ© λ²μ μ΄ strlcpy
μ΄λ€.
strlcpy π
BSD
κ³μ΄μ 컀λμμλ strncpy
λ₯Ό ν΄κ²°νκΈ° μν΄ strlcpy
λ₯Ό ꡬννμλ€.
|
|
νλ‘ν νμ
μ strncpy
μ λΉμ·νλ€. νμ§λ§ strncpy
μμ ν κ°μ§ μ°¨μ΄μ μ
strlcpy
λ νμ destination λ¬Έμμ΄μ΄ NUL-terminated λΌλ κ²μ 보μ₯νλ€λ
μ μ΄λ€. κ·Έλ¦¬κ³ λ°νκ°μΌλ‘ src
μ κΈΈμ΄λ₯Ό λ°ννκΈ° λλ¬Έμ *dest
λ‘ λ°νλ
λ¬Έμμ΄κ³Ό λΉκ΅ν¨μΌλ‘μ¨ μ μμ μΌλ‘ λ¬Έμμ΄ λ³΅μ¬κ° μ΄λ€μ‘λμ§ λΉκ΅ν μ μλ€. νμ§λ§
λΉμμ λΉν¨μ¨μ μ΄λΌλ μ΄μ λ‘ glibc
λ©μΈν
μ΄λμ 컀λ κ°λ°μλ€μκ²λ
strlcpy
λ νμλ°μ§ λͺ»νλ€.
This is horribly inefficient BSD crap. Using these function only leads to other errors. Correct string handling means that you always know how long your strings are and therefore you can you memcpy (instead of strcpy). Beside, those who are using strcat or variants deserved to be punished.
λ§λ λ§μ΄κΈ΄ νλ€. source
λ¬Έμμ΄μ κΈΈμ΄κ° μΌλ§μΈμ§ μκ³ μκΈ° λλ¬Έμ λͺ
μμ μΌλ‘
νμλ©΄ memcpy
λ₯Ό μ΄μ©νλ©΄ λμ§ κ΅³μ΄ strlcpy
λ₯Ό μ΄μ©ν΄κ°λ©΄μ λ°νκ°μ μ¬μ°¨
*dest
μ λΉκ΅νλ μ½λλ₯Ό 지 νμλ μλ€. νμ§λ§ μ΄κ²λ³΄λ€ λ μ€μν λͺ κ°μ§
κ²°ν¨μ΄ μλ€.
- μ€μ λ°μ΄ν°κ° 볡μ¬λ μ μλ κ²½μ°μλ
source
λ¬Έμμ΄μ μ½μ΄μΌ νλ€. source
λ¬Έμμ΄μ μ λ’°ν μ μλ κ²½μ°(non-NUL terminated)λ₯Ό μ²λ¦¬νμ§ λͺ»νλ€.- race condition μ΄ μ‘΄μ¬νλ€.
strlen
μ μ΄μ©ν΄ μ 체 μμ€ λ¬Έμμ΄μ κΈΈμ΄λ₯Ό νμΈνκΈ° μν΄ μ½μ΄μΌ νλ λ¬Έμ μ μ΄
μ‘΄μ¬νκ³ , μλμ κ°μ΄ ꡬνλμ΄ μλ strlcpy
λ λ§μ½ source
λ¬Έμμ΄μ΄ NULλ‘
λλμ§ μλ μνμΌ κ²½μ° λ¬Έμ κ° λ°μν μ μλ€. μ€μ μλμ μ½λλ₯Ό 보면 κ·Έλ¬ν
κ²½μ°κ° λ°μνμ λ ν΄λΌμ΄μΈνΈ μͺ½μμ μ μ μλ λ°©λ²μ΄ μλ€.
λν, race conditionμ΄ λ°μν μ μλ€. μ΄ λΆλΆμ μΈλ» μκ°νμ§ λͺ»ν
λΆλΆμΈλ°, src
μ κΈΈμ΄λ₯Ό κ°μ Έμ€κ³ λ λ€ μ€κ°μμ src
κ° λ°λλ κ²½μ°μλ μ΄λ₯Ό
μ²λ¦¬νμ§ λͺ»νλ€.
strscpy π
|
|
μ΄λ¬ν κ²°μ λ€μ ν΄κ²°ν ν¨μκ° λ°λ‘ strscpy
μ΄λ€. νλ‘ν νμ
λ§ λ³΄λ©΄ λ€λ₯Έ μ μ΄
μλ€. μ°¨μ΄μ μ λ°νκ°μ μλ€. strlcpy
μ λ¬λ¦¬ strscpy
λ 볡μ¬λ λ¬Έμλ€μ
κ°μλ₯Ό λ°ννλ€λ νΉμ§μ΄ μκ³ μ€μ
ꡬν(https://elixir.bootlin.com/linux/v5.19.3/source/lib/string.cL151)μ
μ΄ν΄λ³΄μμ λλ μμ κ°λ¨ν λ¬Έμμ΄ λ³΅μ¬λ°©λ²κ³Όλ μ¬λ λ€λ₯΄λ€.
λ§μΉλ©° π
νμ¬ κ°μ₯ μ΅μ λ²μ μ strscpy
ν¨μμμλ kasan
λ ν¨κ» 곡λΆν΄μΌ μμ νκ²
ν¨μλ₯Ό μ΄ν΄ν μ μμ κ² κ°λ€. μ΄μ νλ€νλ€ λ¬Έμμ΄ νλ 볡μ¬νλ ν¨μμ‘°μ°¨ μ½κ²
μ΄ν΄νκΈ° νλ€μ΄μ§ μ§κ²½κΉμ§ μ΄λ₯΄λ λ€. λ°°μλ κΉλ¨Ήμ΄λ²λ¦¬λ μΈμ κ° λ€μ μ΄ κΈλ
λ€μ λ€μ 거릴 λκ° μ¬ κ²μ΄λ€.