এই গ্লিবসি সমস্যাটি ঘিরে কাজ করার সর্বোত্তম উপায় কী হবে?


26

আমি একটি জেন্টু কঠোর বাক্স পরিচালনা করি যা /bin/pingসেটআপড -রুট বাইনারিগুলির বেশিরভাগ প্রয়োজন (যেমন CAP_NET_RAW রয়েছে) মুছে ফেলার জন্য ফাইল ক্ষমতা ব্যবহার করে ।

প্রকৃতপক্ষে, আমি কেবল বাইনারিটি রেখেছি তা হ'ল:

abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ # 

যদি আমি সেটুইড বিটটি সরিয়ে ফেলি, বা আমার মূল ফাইল সিস্টেম পুনরায় গণনা করি, এসএসডিডি এবং nosuidজিএনইউ স্ক্রিন কাজ করা বন্ধ করে দেয় কারণ তারা grantpt(3)তাদের মাস্টার পেসুডোটার্মিনালগুলিকে কল করে এবং গ্লিবসি স্পষ্টতই এই প্রোগ্রামটি স্লেভ সিউডোটার্মিনালটির অধীনে ছোড এবং chmod করার জন্য প্রয়োগ করে /dev/pts/এবং জিএনইউ স্ক্রিনটি কখন এই ফাংশনটির যত্ন করে about ব্যর্থ।

সমস্যাটি হ'ল ম্যানপেজটি grantpt(3)স্পষ্টতই বলেছে যে লিনাক্সের অধীনে devptsফাইল - সিস্টেম মাউন্ট করা হয়েছে, এমন কোনও সহায়ক বাইনারি প্রয়োজন নেই; কার্নেলটি স্বয়ংক্রিয়ভাবে স্লেভের ইউআইডি ও জিআইডি সেট করার পরে প্রক্রিয়াটির প্রকৃত ইউআইডি এবং জিআইডি সেট হয়ে যাবে /dev/ptmx(কল করে getpt(3))।

আমি এটি প্রদর্শনের জন্য একটি ছোট উদাহরণ প্রোগ্রাম লিখেছি:

#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
    int master;
    char slave[16];
    struct stat slavestat;
    if ((master = getpt()) < 0) {
        fprintf(stderr, "getpt: %m\n");
        return 1;
    }
    printf("Opened a UNIX98 master terminal, fd = %d\n", master);
    /* I am not going to call grantpt() because I am trying to
     * demonstrate that it is not necessary with devpts mounted,
     * the owners and mode will be set automatically by the kernel.
     */
    if (unlockpt(master) < 0) {
        fprintf(stderr, "unlockpt: %m\n");
        return 2;
    }
    memset(slave, 0, sizeof(slave));
    if (ptsname_r(master, slave, sizeof(slave)) < 0) {
        fprintf(stderr, "ptsname: %m\n");
        return 2;
    }
    printf("Device name of slave pseudoterminal: %s\n", slave);
    if (stat(slave, &slavestat) < 0) {
        fprintf(stderr, "stat: %m\n");
        return 3;
    }
    printf("Information for device %s:\n", slave);
    printf("    Owner UID:  %d\n", slavestat.st_uid);
    printf("    Owner GID:  %d\n", slavestat.st_gid);
    printf("    Octal mode: %04o\n", slavestat.st_mode & 00007777);
    return 0;
}

পূর্বোক্ত প্রোগ্রামটি সরিয়ে দেওয়া সেটআপ বিটের সাথে এটিকে কর্মে পর্যবেক্ষণ করুন:

aaron@abraxas ~ $ id
uid=1000(aaron) gid=100(users) groups=100(users)
aaron@abraxas ~ $ ./ptytest 
Opened a UNIX98 master terminal, fd = 3
Device name of slave pseudoterminal: /dev/pts/17
Information for device /dev/pts/17:
    Owner UID:  1000
    Owner GID:  100
    Octal mode: 0620

এই সমস্যাটি সম্পর্কে কীভাবে কাজ করা যায় সে সম্পর্কে আমার কাছে কয়েকটি ধারণা রয়েছে:

1) প্রোগ্রামটি একটি কঙ্কাল দিয়ে প্রতিস্থাপন করুন যা কেবল 0 প্রদান করে।

2) প্যাচ গ্রান্ট () আমার libc তে কিছুই করতে হবে না।

আমি এই দুটিই স্বয়ংক্রিয় করতে পারি, তবে কারও কাছে কি একে অপরের উপরের জন্য একটি সুপারিশ আছে, বা কীভাবে এটি সমাধান করতে হবে তার জন্য সুপারিশ রয়েছে?

একবার এটি সমাধান হয়ে গেলে আমি শেষ পর্যন্ত পারি mount -o remount,nosuid /


আমি যখন কোনও প্রতিক্রিয়াটির অপেক্ষায় থাকি, আমি 1 টির সাথে যোগাযোগ করি এবং এসএসডিডি এবং জিএনইউ স্ক্রিন এখনও কাজ করে।
অ্যারন জোন্স

প্রোগ্রামগুলি ব্যর্থ হ'ল কি? সম্ভবত তারা ভেঙে গেছে এবং ptyপ্রোগ্রামের জন্য (তাদের যেমনটি হওয়া উচিত) তা পরীক্ষা না করে ?
ভোনব্র্যান্ড

যে কোনও প্রোগ্রামে CAP_CHOWN এবং CAP_FOWNER নেই, কল গ্রান্ট () এবং হেল্পার বাইনারিটি EID == 0 দিয়ে শুরু করা হয়নি, তাদের গ্রান্টের জন্য শূন্য-শূন্য রিটার্ন কোড থাকবে () এবং প্রোগ্রামগুলি যখন এটি ঘটে তখন পিটিএস সৃষ্টি বাতিল করতে হবে? , পিটিএমএক্স (4) অনুসারে।
অ্যারন জোন্স

3
এই "সমাধান" আমাকে উইলগুলি দেয় ... সর্বোত্তম ক্ষেত্রে, এটি একটি বাগের জন্য কাগজপত্র দেয়, এটি সম্ভবত একটি নতুন বাগ তৈরি করে, সবচেয়ে খারাপ ক্ষেত্রে এটি একটি গুরুতর সুরক্ষার দুর্বলতা তৈরি করে। দয়া করে গ্লিবিসি বিকাশকারীদের সাথে এটি গ্রহণ করুন।
ভনব্র্যান্ড

3
তারপরে গ্লিবসি লোকদের কাছে এটি রিপোর্ট করুন।
ভনব্র্যান্ড

উত্তর:


2

যদি আপনার জন্য glibc যুক্তিসঙ্গতভাবে বর্তমান, এবং devpts সঠিকভাবে সেট আপ করা হয়েছে, সেখানে ডাকা করার কোন প্রয়োজন হওয়া উচিত pt_chownএ সব সাহায্যকারী।

আপনি সম্ভবত একটি সেট / সেট সম্ভাব্য সমস্যা থেকে সেটুয়েড-রুট মুছে ফেলা হচ্ছে pt_chown

grantpt()glibc-2.7devfs থেকে সমর্থিত , glibc-2.11 এ পরিবর্তনগুলি করা হয়েছিল যদিও এটি স্পষ্টভাবে পরীক্ষা করার পরিবর্তে এটি পরীক্ষা করার আগে বা অনুরোধে ফিরে যাওয়ার আগে কোনও কাজ করার প্রয়োজন কিনা তা পরীক্ষা করে দেখুন ।DEVFS_SUPER_MAGICchown()pt_chown

থেকে glibc-2.17/sysdeps/unix/grantpt.c

  ...
  uid_t uid = __getuid ();
  if (st.st_uid != uid)
    {
       if (__chown (buf, uid, st.st_gid) < 0)
       goto helper;
    }
  ...

গিড এবং অনুমতিগুলি যাচাই করতে অনুরূপ স্তবক ব্যবহৃত হয়। ক্যাচটি হ'ল যে ইউআইডি, গিড এবং মোড অবশ্যই প্রত্যাশার সাথে মেলে (আপনি, টিটি, এবং ঠিক 620; এর সাথে নিশ্চিত হন /usr/libexec/pt_chown --help)। যদি তা না হয়, chown()(যার জন্য ব্যাপিং বাইনারি / প্রক্রিয়াটির CAP_CHOWN, CAP_FOWNER এর সক্ষমতা প্রয়োজন) চেষ্টা করা হয় এবং যদি এটি ব্যর্থ হয় তবে pt_chownবাহ্যিক সহায়ক (যা অবশ্যই সেটুয়েড-রুট হওয়া আবশ্যক) চেষ্টা করা হবে। জন্য জন্য pt_chownক্ষমতাগুলি যা এটি (এবং অত: পর আপনার জন্য glibc) সঙ্গে কম্পাইল হয়ে থাকতে হবে ব্যবহার করতে পাবে HAVE_LIBCAPতবে , মনে হয় যে pt_chownআছে (হিসাবে জন্য glibc-2.17 , এবং আপনি উল্লিখিত যদিও আপনি সংস্করণ বিবৃত করেন নি) চান হার্ড কোডেড geteuid()==0 নির্বিশেষে এর HAVE_LIBCAPথেকে, প্রাসঙ্গিক কোড glibc-2.17/login/programs/pt_chown.c:

  ...
  if (argc == 1 && euid == 0)
    {
#ifdef HAVE_LIBCAP
  /* Drop privileges.  */
     if (uid != euid)
  ...
#endif
    /* Normal invocation of this program is with no arguments and
       with privileges.  */
    return do_pt_chown ();
  }
...
  /* Check if we are properly installed.  */
  if (euid != 0)
    error (FAIL_EXEC, 0, gettext ("needs to be installed setuid `root'"));

( geteuid()==0দক্ষতা ব্যবহারের চেষ্টা করার আগে আশা করা আসলেই দক্ষতার চেতনাতে মনে হয় না, আমি এইটিতে একটি বাগ লগ করতে যাব))

আক্রান্ত প্রোগ্রামগুলিতে CAP_CHOWN, CAP_FOWNER দেওয়ার একটি সম্ভাব্য কাজের সমাধান হতে পারে, তবে আমি সত্যিই এটির প্রস্তাব দিই না যেহেতু আপনি অবশ্যই এটি পিটিএস পর্যন্ত সীমাবদ্ধ করতে পারবেন না।

যদি এটি আপনাকে সমাধান করতে সহায়তা করে না, প্যাচিং sshdএবং screenগ্ল্যাবকি প্যাচিংয়ের তুলনায় কিছুটা কম দ্বিমতযোগ্য। যেহেতু সমস্যাটি গ্লিবসি-র মধ্যে রয়েছে, তাই একটি ক্লিনার পদ্ধতির একটি ডামি বাস্তবায়নের জন্য ডিএলএল ইঞ্জেকশন নির্বাচন করতে হবে grantpt()


"যেহেতু সমস্যাটি গ্লিবসি-র মধ্যে রয়েছে, তাই একটি ক্লিনার পদ্ধতির মাধ্যমে ডামি গ্রান্ট () প্রয়োগ করতে ডিএলএল ইঞ্জেকশন নির্বাচন করতে হবে।" - উজ্জ্বল। কেন আমি তা ভেবে দেখিনি? ধন্যবাদ। :)
অ্যারন জোন্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.