এই কোডটি কেন বাফার ওভারফ্লো আক্রমণে ঝুঁকিপূর্ণ?


148
int func(char* str)
{
   char buffer[100];
   unsigned short len = strlen(str);

   if(len >= 100)
   {
        return (-1);
   }

   strncpy(buffer,str,strlen(str));
   return 0;
}

এই কোডটি একটি বাফার ওভারফ্লো আক্রমণে ঝুঁকিপূর্ণ এবং আমি এটি কেন চেষ্টা করার চেষ্টা করছি। আমি ভাবছিলাম এটির পরিবর্তে lenঘোষিত হওয়ার সাথে কী হবে তবে আমি সত্যিই নিশ্চিত নই।shortint

কোন ধারনা?


3
এই কোডটি নিয়ে একাধিক সমস্যা রয়েছে। মনে রাখবেন যে সি স্ট্রিংগুলি নাল-সমাপ্ত।
দিমিত্রি চুবারভ

4
@ দিমিত্রি চুবারভ, স্ট্রিংটি বাতিল না করা কেবলমাত্র কল করার পরে যদি স্ট্রিংটি ব্যবহার করা হয় তবে সমস্যা হবে strncpy। এই ক্ষেত্রে, এটি না।
আর সাহু

43
এই কোডটিতে সমস্যাগুলি সরাসরি সত্য থেকে প্রবাহিত হয় strlenযা গণনা করা হয়, বৈধতা যাচাইয়ের জন্য ব্যবহৃত হয় এবং তারপরে এটি অযৌক্তিকভাবে আবার গণনা করা হয় - এটি একটি DRY ব্যর্থতা। যদি দ্বিতীয়টি strlen(str)প্রতিস্থাপন করা হয় lenতবে প্রকারের প্রকার নির্বিশেষে বাফার ওভারফ্লো হওয়ার সম্ভাবনা থাকবে না len। উত্তরগুলি এই পয়েন্টটি সম্বোধন করে না, তারা এটিকে এড়াতে কেবল পরিচালনা করে।
জিম বাল্টার

3
@ সিআইপান: ওয়েেন এতে নাল-টার্মিনেটেড স্ট্রিং পাস করার পরে, স্ট্রলন অপরিজ্ঞাত আচরণ প্রদর্শন করবে।
কাইসারলুদি

3
@ জিমবাল্টার নাহ, আমার মনে হয় আমি তাদের সেখানে রেখে দেব। হতে পারে অন্য কারওর মতো একই বোকা ভুল ধারণা থাকবে এবং সেখান থেকে শিখবে। যদি তারা আপনাকে কৃপণ করে তবে এটিকে পতাকা নির্দ্বিধায় ফেলুন, কেউ হয়তো এলোমেলো হয়ে মুছে ফেলবে।
আসাদ সাইদুদ্দীন

উত্তর:


192

বেশিরভাগ unsigned shortসংকলকগুলিতে একটিটির সর্বাধিক মান 65535।

উপরের কোনও মান যা প্রায় গুটিয়ে যায়, তাই 65536 0 হয়ে যায়, এবং 65600 65 হয়ে যায়।

এর অর্থ হ'ল ডান দৈর্ঘ্যের দীর্ঘ স্ট্রিং (উদাহরণস্বরূপ 65600) চেকটি পাস করবে এবং বাফারটি উপচে যাবে।


ব্যবহারের size_tফলে সঞ্চয় করতে strlen()না unsigned short, এবং তুলনা lenএকটি অভিব্যক্তি যা সরাসরি আকার এনকোড করতে buffer। উদাহরণস্বরূপ:

char buffer[100];
size_t len = strlen(str);
if (len >= sizeof(buffer) / sizeof(buffer[0]))  return -1;
memcpy(buffer, str, len + 1);

2
@ পেট্রিকরবার্টস তাত্ত্বিকভাবে, হ্যাঁ তবে আপনাকে মনে রাখতে হবে যে রানটাইমের 90% কোডের জন্য 10% কোড দায়ী, তাই আপনাকে সুরক্ষা দেওয়ার আগে পারফরম্যান্স যেতে দেওয়া উচিত নয়। এবং মনে রাখবেন যে সময়ের সাথে সাথে কোডগুলি পরিবর্তিত হয়, যার হঠাৎ বোঝানো যেতে পারে যে পূর্ববর্তী চেকটি চলে গেছে।
orlp

3
বাফার ওভারফ্লো রোধ করতে, কেবল lenস্ট্রিংকিপির তৃতীয় যুক্তি হিসাবে ব্যবহার করুন । আবার স্ট্র্লেন ব্যবহার করা যেকোন ক্ষেত্রেই বোবা।
জিম বাল্টার

15
/ sizeof(buffer[0])- নোট করুন যে sizeof(char)সি তে সর্বদা 1 থাকে (এমনকি কোনও চরে গাজিলিয়ন বিট থাকে এমন কি) তাই যখন অতিরিক্ত ডেটা ধরণের ব্যবহারের সম্ভাবনা না থাকে তখন তা অতিমাত্রায় হয়। এখনও ... সম্পূর্ণ উত্তরের জন্য কুডোস (এবং মন্তব্যে প্রতিক্রিয়াশীল হওয়ার জন্য ধন্যবাদ)
জিম বাল্টার

3
@ আরআর-: char[]এবং char*একই জিনিস নয়। আছে অনেক পরিস্থিতিতে যেখানে একজন char[]পরোক্ষভাবে একটি রূপান্তরিত হবে char*। উদাহরণস্বরূপ, ফাংশন আর্গুমেন্টগুলির জন্য টাইপ হিসাবে ব্যবহৃত char[]হুবহু একই char*। তবে রূপান্তরটি এর জন্য ঘটে না sizeof()
ডায়েটারিচ এপ্পি

4
@ নিয়ন্ত্রণ করুন কারণ আপনি যদি bufferকিছু সময়ে আকার পরিবর্তন করেন তবে এক্সপ্রেশনটি স্বয়ংক্রিয়ভাবে আপডেট হয়। এটি সুরক্ষার জন্য গুরুত্বপূর্ণ, কারণ ঘোষণাটি bufferপ্রকৃত কোডের চেক থেকে বেশ কিছু লাইন দূরে থাকতে পারে। সুতরাং বাফারের আকার পরিবর্তন করা সহজ তবে আকারটি ব্যবহৃত হয় এমন প্রতিটি স্থানে আপডেট করতে ভুলবেন না।
orlp

28

সমস্যাটি এখানে:

strncpy(buffer,str,strlen(str));
                   ^^^^^^^^^^^

যদি স্ট্রিংটি লক্ষ্য বাফারের দৈর্ঘ্যের চেয়ে বেশি হয় তবে স্ট্রান্সপিপি এখনও এটিকে অনুলিপি করবে। আপনি বাফারের আকারের পরিবর্তে কপির জন্য স্ট্রিংয়ের অক্ষরের সংখ্যাটি বেজ করছেন। এটি করার সঠিক উপায়টি নিম্নরূপ:

strncpy(buffer,str, sizeof(buff) - 1);
buffer[sizeof(buff) - 1] = '\0';

এটি যা করে তা হল নাল টার্মিনেটিং চরিত্রের জন্য বাফার বিয়োগের প্রকৃত আকারে অনুলিপি করা তথ্যের পরিমাণ সীমাবদ্ধ। তারপরে আমরা বাফারে সর্বশেষ বাইটটি একটি যুক্ত সুরক্ষা হিসাবে নাল চরিত্রটিতে সেট করি। এর কারণ হ'ল স্ট্রান্সকিপি টার্মিনেটিং নাল সহ এন বাইট পর্যন্ত অনুলিপি করবে, যদি স্ট্রেন (স্ট্র) <লেন - ১ না থাকে তবে নালটি অনুলিপি করা হয়নি এবং আপনার ক্র্যাশ পরিস্থিতি রয়েছে কারণ এখন আপনার বাফারটিতে একটি বাধা নেই has স্ট্রিং।

আশাকরি এটা সাহায্য করবে.

সম্পাদনা: আরও পরীক্ষা এবং অন্যের কাছ থেকে ইনপুট দেওয়ার পরে, ফাংশনটির জন্য একটি সম্ভাব্য কোডিং নিম্নলিখিত:

int func (char *str)
  {
    char buffer[100];
    unsigned short size = sizeof(buffer);
    unsigned short len = strlen(str);

    if (len > size - 1) return(-1);
    memcpy(buffer, str, len + 1);
    buffer[size - 1] = '\0';
    return(0);
  }

যেহেতু আমরা ইতিমধ্যে স্ট্রিংয়ের দৈর্ঘ্য জানি, তাই স্ট্রিং দ্বারা বাফারে রেফারেন্সযুক্ত অবস্থান থেকে স্ট্রিংটি অনুলিপি করতে আমরা ম্যাকপিটি ব্যবহার করতে পারি। নোট করুন যে স্ট্র্লেন (3) (একটি ফ্রিবিএসডি 9.3 সিস্টেমের জন্য) এর জন্য ম্যানুয়াল পৃষ্ঠা অনুসারে, নিম্নলিখিতটি বর্ণিত হয়েছে:

 The strlen() function returns the number of characters that precede the
 terminating NUL character.  The strnlen() function returns either the
 same result as strlen() or maxlen, whichever is smaller.

যা আমি ব্যাখ্যা করছি যে স্ট্রিংয়ের দৈর্ঘ্যে নাল অন্তর্ভুক্ত নয়। এই কারণেই নালটি অন্তর্ভুক্ত করার জন্য আমি লেন + 1 বাইটগুলি অনুলিপি করেছি এবং পরীক্ষাটি চেক করে পরীক্ষা করে পরীক্ষা করে নিন <দৈর্ঘ্যের বাফার - 2 বিয়োগ বিধি কারণ বাফার 0 অবস্থান থেকে শুরু হয়, এবং অন্য একটি বিয়োগের জায়গা আছে কিনা তা নিশ্চিত করার জন্য নাল জন্য।

সম্পাদনা: দেখা যাচ্ছে, কোনওটির আকার 1 দিয়ে শুরু হয় যখন অ্যাক্সেস 0 দিয়ে শুরু হয়, সুতরাং -2 এর আগে ভুল ছিল কারণ এটি কোনও কিছুর জন্য> 98 বাইটের জন্য ত্রুটি ফিরে আসবে তবে এটি> 99 বাইট হওয়া উচিত।

সম্পাদনা: স্বাক্ষরযুক্ত স্বল্প সংক্ষিপ্ত সম্পর্কে উত্তরটি যথাযথভাবে সঠিক কারণ প্রতিনিধিত্ব করা যায় এমন সর্বোচ্চ দৈর্ঘ্য 65৫,৫৩৫ অক্ষর হ'ল, এটি সত্যিকার অর্থে কিছু যায় আসে না কারণ যদি স্ট্রিংটি এর চেয়ে দীর্ঘ হয় তবে মানটি প্রায় মোড়াবে। এটি 75,231 (যা 0x000125DF) নেওয়া এবং শীর্ষ 16 বিটগুলি আপনাকে 9695 (0x000025DF) দিয়ে মাস্ক করার মতো। দৈর্ঘ্যের চেকটি অনুলিপিটির অনুমতি দেবে বলে আমি কেবল এটিই প্রথম 100 টি চরটি 65,535 এর আগে দেখতে পাচ্ছি, তবে এটি কেবলমাত্র স্ট্রিংয়ের প্রথম 100 টি অক্ষর পর্যন্ত অনুলিপি করে স্ট্রিংটি বাতিল করে দেবে । এমনকি মোড়ক ইস্যু নিয়েও, বাফারটি এখনও উপচে পড়া হবে না।

স্ট্রিংয়ের বিষয়বস্তু এবং আপনি এটি কী ব্যবহার করছেন তার উপর নির্ভর করে এটি নিজেই সুরক্ষা ঝুঁকি তৈরি করতে পারে বা নাও পারে। যদি এটি কেবল সরল পাঠ্য যা মানুষের পাঠযোগ্য, তবে সাধারণত কোনও সমস্যা নেই। আপনি কেবল একটি কাটা স্ট্রিং পাবেন। যাইহোক, এটি URL বা এমনকি কোনও এসকিউএল কমান্ড ক্রমের মতো কিছু হলে আপনার সমস্যা হতে পারে you


2
সত্য, তবে এটি প্রশ্নের সুযোগের বাইরে। কোডটি স্পষ্টভাবে ফাংশনটিকে একটি চর পয়েন্টারটি দিয়ে যাচ্ছে তা দেখায়। ফাংশনের ক্ষেত্রের বাইরে, আমরা যত্ন করি না।
ড্যানিয়েল রুডি

"যে বাফারে স্ট্র জমা আছে" - এটি কোনও বাফার ওভারফ্লো নয় , যা এখানে সমস্যা। এবং প্রতিটি উত্তরের সেই "সমস্যা" রয়েছে, যা func... এর স্বাক্ষর দিয়ে অনিবার্য এবং অন্য যে কোনও সি ফাংশন লিখিত থাকে যা NUL- সমাপ্ত স্ট্রিংকে আর্গুমেন্ট হিসাবে গ্রহণ করে। ইনপুটটি NUL- সমাপ্ত না হওয়ার সম্ভাবনা তুলে ধরা পুরোপুরি অসতর্ক।
জিম বাল্টার

"এটি প্রশ্নের আওতার বাইরে" - যা দুঃখের সাথে কিছু লোক বুঝতে সক্ষমতার বাইরে।
জিম বাল্টার

"সমস্যাটি এখানে" - আপনি ঠিক বলেছেন, তবে আপনি এখনও মূল সমস্যাটি মিস করছেন, যা হ'ল পরীক্ষা ( len >= 100) একটি মানের বিপরীতে করা হয়েছিল তবে অনুলিপিটির দৈর্ঘ্যকে আলাদা মান দেওয়া হয়েছিল ... এটি এটি DRY নীতি লঙ্ঘন। কেবল কল করা strncpy(buffer, str, len)বাফার ওভারফ্লো হওয়ার সম্ভাবনা এড়ায় এবং এর চেয়ে কম কাজ করে strncpy(buffer,str,sizeof(buffer) - 1)... যদিও এখানে এটি কেবল ধীর সমতুল্য memcpy(buffer, str, len)
জিম বাল্টার

@ জিমবাল্টার এটি প্রশ্নের আওতার বাইরে, তবে আমি ডিগ্রি করি। আমি বুঝতে পেরেছি যে পরীক্ষার দ্বারা ব্যবহৃত মানগুলি এবং স্ট্রেনসিপি-তে কী ব্যবহৃত হয় তা দুটি ভিন্ন। তবে সাধারণ কোডিং অনুশীলন বলছে যে অনুলিপিটির সীমাটি আকারের (বাফার) হতে হবে - 1 সুতরাং অনুলিপিটির উপর আরআরটির দৈর্ঘ্য কী তা বিবেচনা করে না। স্ট্রান্সকিপি বাইট অনুলিপি করা বন্ধ করে দিবে যখন তা হয় নালকে আঘাত করে বা এন বাইটস অনুলিপি করে। পরবর্তী লাইনটি গ্যারান্টি দেয় যে বাফারে শেষ বাইটটি নাল চর। কোডটি নিরাপদ, আমি আমার আগের বিবৃতিটি দিয়ে দাঁড়িয়েছি।
ড্যানিয়েল রুডি

11

যদিও আপনি ব্যবহার করছেন strncpy, কাট অফের দৈর্ঘ্য এখনও পাস করা স্ট্রিং পয়েন্টারের উপর নির্ভরশীল। স্ট্রিংটি কত দিন আপনার কোনও ধারণা নেই (পয়েন্টারের তুলনায় নাল টার্মিনেটরের অবস্থান)। সুতরাং strlenএকা কল করা আপনাকে দুর্বলতার দিকে উন্মুক্ত করে। আপনি যদি আরও সুরক্ষিত থাকতে চান তবে ব্যবহার করুন strnlen(str, 100)

সম্পূর্ণ কোড সংশোধন করা হবে:

int func(char *str) {
   char buffer[100];
   unsigned short len = strnlen(str, 100); // sizeof buffer

   if (len >= 100) {
     return -1;
   }

   strcpy(buffer, str); // this is safe since null terminator is less than 100th index
   return 0;
}

@ ব্যবহারকারী 3386109 তারপরেও বাফারের শেষটি strlenঅ্যাক্সেস করবেন না ?
প্যাট্রিক রবার্টস

2
@ ব্যবহারকারী 3386109 আপনি যা দেখিয়েছেন তা orlp এর উত্তরকে আমার হিসাবে ঠিক অবৈধ করে তোলে। strnlenOrlp যা পরামর্শ দিচ্ছে তা যাইহোক সঠিকভাবে বিবেচনা করা থাকলে কেন সমস্যার সমাধান হয় না তা দেখতে আমি ব্যর্থ হয়েছি ।
প্যাট্রিক রবার্টস

1
"আমি মনে করি না যে স্ট্রেনলেন এখানে কিছু সমাধান করে" - অবশ্যই এটি করে; এটি উপচে পড়া রোধ করে buffer। "যেহেতু স্ট্রিং 2 বাইটের একটি বাফারকে নির্দেশ করতে পারে, যার মধ্যে কোনওটিই নুল নয়।" - এটি অপ্রাসঙ্গিক, এটি যে কোনও বাস্তবায়নের ক্ষেত্রে সত্য func। এখানে প্রশ্নটি ইউফ নয়, বাফার ওভারফ্লো সম্পর্কে কারণ ইনপুটটি NUL- সমাপ্ত নয়।
জিম বাল্টার

1
"দ্বিতীয় প্যারামিটারটি স্ট্রেনলনে পাস হওয়া অবধি অবশ্যই প্রথম প্যারামিটারটি নির্দেশ করে এমন বস্তুর আকার হতে হবে, বা স্ট্রেনল্যান মূল্যহীন" - এটি সম্পূর্ণ এবং একেবারে বাজে কথা। যদি দ্বিতীয় যুক্তিটি স্ট্রেনলে ইনপুট স্ট্রিংয়ের দৈর্ঘ্য হয় তবে স্ট্রেনলান স্ট্রেনের সমতুল্য। এমনকি আপনি কীভাবে এই নম্বরটি পাবেন এবং আপনার যদি এটি থাকে তবে আপনাকে কেন স্ট্র [এন] লেন কল করতে হবে? মোটেও স্ট্রেনলিন এটাই নয়।
জিম বাল্টার

1
কারণ এটি ওপি এর কোড সমতূল্য না +1 করুন উত্তর যদিও অপূর্ণ হয় - strncpy NUL-প্যাড এবং NUL বিনষ্ট নয়, যেহেতু strcpy NUL-বন্ধ এবং NUL প্যাড আছে, এটা না সমস্যা নেই, বিপরীত সমাধান হাস্যকর, উপরে অজ্ঞ মন্তব্য।
জিম বাল্টার

4

মোড়কের উত্তরটি সঠিক। তবে আমার মনে একটি সমস্যা রয়েছে যা উল্লেখ করা হয়নি তবে (লেন> = 100)

লেন যদি 100 হয় তবে আমরা 100 উপাদানগুলি অনুলিপি করতাম যা আমাদের কাছে \ 0 এর পিছনে নেই। এর সুস্পষ্টরূপে অর্থ হ'ল যথাযথ সমাপ্ত স্ট্রিংয়ের উপর নির্ভর করে অন্য কোনও ফাংশনটি মূল অ্যারের বাইরে চলে যাবে।

সি থেকে সমস্যাযুক্ত স্ট্রিংটি আইএমএইচও অলসযোগ্য v কল করার আগে আপনার কিছুটা সীমাবদ্ধতা আরও ভাল ছিল তবে তা এমনকি কোনও কাজে দেয় না। কোনও সীমানা যাচাই করা নেই এবং তাই বাফার ওভারফ্লো সবসময়ই করতে পারে এবং দুর্ভাগ্যক্রমে ঘটবে ....


স্ট্রিং সমস্যাযুক্ত হয় সমাধেয়: শুধু উপযুক্ত ফাংশন ব্যবহার করুন। আই। ই। না strncpy() এবং বন্ধুরা, তবে মেমরির মত বরাদ্দ করে strdup()এবং বন্ধুদের মতো করে । তারা POSIX-2008 স্ট্যান্ডার্ড হয়, তাই তারা মোটামুটি বহনযোগ্য, যদিও কিছু মালিকানাধীন সিস্টেমে উপলব্ধ না।
মাস্টার -

"যথাযথ সমাপ্ত স্ট্রিংয়ের উপর নির্ভর করে অন্য কোনও ক্রিয়াকলাপ" - bufferএই ফাংশনের স্থানীয় এবং অন্য কোথাও ব্যবহৃত হয় না। একটি বাস্তব প্রোগ্রামে আমাদের এটি পরীক্ষা করে দেখতে হবে যে এটি কীভাবে ব্যবহৃত হয় ... কখনও কখনও NUL- সমাপ্তি সঠিক হয় না (স্ট্রেনসিপি-র মূল ব্যবহারটি ইউনিক্সের 14 বাইট ডিরেক্টরি এনট্রিগুলি তৈরি করতে হত - NUL-padded এবং NUL- সমাপ্ত নয়)। "সি থেকে সমস্যাযুক্ত স্ট্রিংটি হ'ল আইএমএইচও অলসযোগ্য" - যদিও সি একটি গাডডাফুল ভাষা যা আরও উন্নত প্রযুক্তির দ্বারা অতিক্রম করা হয়েছে, পর্যাপ্ত শৃঙ্খলা ব্যবহার করা হলে তাতে নিরাপদ কোড লেখা যেতে পারে।
জিম বাল্টার

আপনার পর্যবেক্ষণটি আমার কাছে বিপথগামী বলে মনে হচ্ছে। if (len >= 100)চেকটি ব্যর্থ হওয়ার জন্য শর্ত , এটি কখন পাস হয় না, যার অর্থ এমন কোনও ক্ষেত্রে নেই যেখানে কোনও NUL টার্মিনেটর সহ সঠিকভাবে 100 বাইট অনুলিপি করা হয়নি, কারণ দৈর্ঘ্যটি ব্যর্থ শর্তে অন্তর্ভুক্ত করা হয়েছে।
প্যাট্রিক রবার্টস

@ মাস্টার এই ক্ষেত্রে আপনি ভুল। এটি দ্রবণযোগ্য নয়, কারণ একজন সর্বদা সীমানা সীমানা লিখতে পারে। হ্যাঁ এটি অপরিবর্তিত আচরণ তবে এটি সম্পূর্ণরূপে প্রতিরোধের উপায় নেই।
ফ্রিডরিচ

@ জিম বাল্টার এটা কোনো ব্যপার না. আমি এই স্থানীয় বাফারের সীমানায় সম্ভাব্যরূপে লিখতে পারি এবং তাই কিছু অন্যান্য ডেটাস্ট্রাকচারকে সর্বদা কলুষিত করা সম্ভব হবে।
ফ্রিডরিচ

3

strlenএকাধিকবার কল করার সাথে জড়িত সুরক্ষা সম্পর্কিত বিষয়গুলির বাইরেও , সাধারণত তার স্ট্রিংগুলির ক্ষেত্রে সাধারণত স্ট্রিং পদ্ধতি ব্যবহার করা উচিত নয় যার দৈর্ঘ্যটি সুনির্দিষ্টভাবে জানা থাকে [বেশিরভাগ স্ট্রিং ফাংশনের জন্য, কেবল একটি সরু ক্ষেত্রে রয়েছে যেখানে সেগুলি ব্যবহার করা উচিত - যার জন্য সর্বাধিক সর্বোচ্চ দৈর্ঘ্যের নিশ্চয়তা দেওয়া যেতে পারে, তবে সঠিক দৈর্ঘ্য জানা যায়নি]। ইনপুট স্ট্রিংয়ের দৈর্ঘ্যটি জানা হয়ে গেলে এবং আউটপুট বাফারের দৈর্ঘ্যটি জানা হয়ে গেলে, কোনও অঞ্চলকে কতটা অনুলিপি করা উচিত তা নির্ধারণ করা উচিত এবং তারপরে memcpy()প্রশ্নটিতে অনুলিপিটি সম্পাদন করতে ব্যবহার করা উচিত । যদিও এটা সম্ভব যে strcpyসুখ্যাতি পারে memcpy()যখন শুধুমাত্র 1-3 বাইট বা তাই একটি স্ট্রিং অনুলিপি অনেক প্ল্যাটফর্মের উপর memcpy()সম্ভবত যখন বৃহত্তর স্ট্রিং সঙ্গে তার আচরণ বেশি দুইবার হিসাবে দ্রুত হতে হয়।

যদিও কিছু পরিস্থিতিতে যেখানে নিরাপত্তা কর্মক্ষমতা খরচে আসতে হবে আছে, এটি একটি অবস্থা যেখানে নিরাপদ পন্থা হল এছাড়াও দ্রুত করুন। কিছু ক্ষেত্রে, কোড লিখতে যুক্তিসঙ্গত হতে পারে যা অদ্ভুত আচরণমূলক ইনপুটগুলির বিরুদ্ধে সুরক্ষিত নয়, যদি ইনপুট সরবরাহকারী কোডগুলি নিশ্চিত করতে পারে যে তারা ভাল আচরণ করবে এবং যদি খারাপ আচরণ করা ইনপুটগুলির বিরুদ্ধে রক্ষা করা কার্য সম্পাদনকে বাধা দেয়। স্ট্রিংয়ের দৈর্ঘ্য কেবলমাত্র পারফরম্যান্স এবং সুরক্ষার উভয় ক্ষেত্রেই উন্নতি হয়েছে কিনা তা একবারে পরীক্ষা করা হয়েছে তা নিশ্চিত করা, যদিও স্ট্রিংয়ের দৈর্ঘ্য ম্যানুয়ালি ট্র্যাক করার পরেও সুরক্ষার সুরক্ষায় সহায়তা করার জন্য আরও একটি কাজ করা যেতে পারে: প্রতিটি স্ট্রিংয়ের জন্য যে পেছনের নাল থাকবে বলে প্রত্যাশা করা হয়, তার জন্য ট্রিলিং নাল স্পষ্ট করে লিখুন উত্সের স্ট্রিংটি এটির চেয়ে প্রত্যাশার চেয়ে। সুতরাং, যদি কেউ একটি strdupসমতুল্য লিখতে থাকে :

char *strdupe(char const *src)
{
  size_t len = strlen(src);
  char *dest = malloc(len+1);
  // Calculation can't wrap if string is in valid-size memory block
  if (!dest) return (OUT_OF_MEMORY(),(char*)0); 
  // OUT_OF_MEMORY is expected to halt; the return guards if it doesn't
  memcpy(dest, src, len);      
  dest[len]=0;
  return dest;
}

নোট করুন যে মেমকিটি len+1বাইট প্রসেস করা থাকলে শেষ বিবৃতিটি সাধারণত বাদ দেওয়া যেতে পারে , তবে এটি অন্য থ্রেডে উত্সের স্ট্রিংটি পরিবর্তন করতে হবে ফলাফলটি একটি নন-ইউএনএল-সমাপ্ত গন্তব্য স্ট্রিং হতে পারে।


3
আপনি দয়া করে একাধিকবার কল করার সাথে জড়িত সুরক্ষা বিষয়গুলিstrlen ব্যাখ্যা করতে পারেন ?
বোগদান আলেকজান্দ্রু

1
@ বোগদান আলেকজান্দ্রু: একবার যখন কেউ strlenফিরে আসার মানের উপর ভিত্তি করে কিছু কল করে এবং কিছু ব্যবস্থা গ্রহণ করে (যা সম্ভবত এটি প্রথম স্থানে ডাকার কারণ ছিল), তারপরে পুনরাবৃত্তি করা কল (1) সর্বদা প্রথমটির মত একই উত্তর দেয়, এক্ষেত্রে এটি কেবল কাজের অপচয়, বা (২) কখনও কখনও (কারণ অন্য কিছু - সম্ভবত অন্য থ্রেড - এর মধ্যে স্ট্রিংটি সংশোধন করে) একটি পৃথক উত্তর দেয়, ক্ষেত্রে ক্ষেত্রে কোডটি দৈর্ঘ্যের সাথে কিছু কাজ করে (যেমন, উদাহরণস্বরূপ) একটি বাফার বরাদ্দ করা) কোডের চেয়ে আলাদা আকার গ্রহণ করতে পারে যা অন্যান্য কাজ করে (বাফারটিতে অনুলিপি করে)।
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.