একটি প্রক্রিয়া জন্য একটি নির্দিষ্ট পাথ জাল করা সম্ভব?


9

আমি একাধিক ব্যবহারকারীর সাথে লিনাক্স সার্ভারে এডিবি চালানোর চেষ্টা করছি যেখানে আমি মূল নই (আমার অ্যান্ড্রয়েড এমুলেটর দিয়ে খেলতে)। অ্যাডবি ডিমন ফাইলগুলিতে তার লগগুলি লিখেছে /tmp/adb.logযা দুর্ভাগ্যবশত এডিবিতে কঠোর কোডড হয়েছে বলে মনে হচ্ছে এবং এই পরিস্থিতি কোনও পরিবর্তন হতে পারে না

সুতরাং, এডিবি রান করতে ব্যর্থ হচ্ছে সুস্পষ্ট ত্রুটি দান: cannot open '/tmp/adb.log': Permission denied। এই ফাইলটি অন্য একজন ব্যবহারকারী দ্বারা তৈরি এবং /tmpএতে স্টিকি বিট রয়েছে। যদি আমি adb nodaemon serverএটিকে স্টডআউটে লেখার চেষ্টা করে শুরু করি , তবে কোনও ত্রুটি ঘটবে না (বিবাদগুলি এড়ানোর জন্য আমি এর বন্দরটি একটি অনন্য মানতেও সেট আপ করেছি)।

আমার প্রশ্ন: এডিবি এর চেয়ে অন্য কোনও ফাইলে লেখার উপায় আছে /tmp/adb.logকি? আরও সাধারণভাবে, কোনও প্রক্রিয়া-নির্দিষ্ট সিমিলিংক তৈরি করার কোনও উপায় আছে কি? আমি সমস্ত ফাইল অ্যাক্সেসগুলিতে /tmp/adb.logএকটি ফাইলকে পুনর্নির্দেশ করতে চাই ~/tmp/adb.log

আবার, আমি সার্ভারে রুট নই, সুতরাং chroot, mount -o rbindএবং chmodবৈধ বিকল্প নয়। যদি সম্ভব হয় তবে আমি এডিবি উত্সগুলি সংশোধন না করতে চাই তবে অবশ্যই যদি অন্য কোনও সমাধান না হয় তবে আমি তা করব।

দ্রষ্টব্য নির্দিষ্ট এডিবি ক্ষেত্রে আমি চলমান অবলম্বন করতে adb nodaemon serverসঙ্গে nohupএবং আউটপুট ফেরৎ কিন্তু সাধারণ প্রশ্ন এখনো প্রাসঙ্গিক।


2
হ্যাঁ. আপনি একটি প্রাইভেট মাউন্ট নেমস্পেসে আপনার প্রক্রিয়াটি রাখতে পারেন এবং অন্য কোনও ফাইলকে মাউন্ট করতে পারেন /tmp/adb.log, বা এমনকি নিজস্ব ব্যক্তিগতটিকে /tmpপুরোপুরি মাউন্ট করতে পারেন । কি man unshareএবং man namespacesএবং man nsenter
মাইকসার্ভ

1
@ মাইক্রোসার্ভ দুর্দান্ত, আমার কাছে যা প্রয়োজন ঠিক তা মনে হচ্ছে, আপনাকে ধন্যবাদ! যদি আপনি নিজের মন্তব্যের উত্তর হিসাবে পুনরায় ফর্ম্যাট করেন তবে আমি এটি গ্রহণযোগ্য হিসাবে সেট করতে সক্ষম হব।
gluk47

বা LD_PRELOADকৌশল আছে, যদিও এটি আরও জটিল হবে।
ট্রিগার করুন

@ থ্রিগ্রি হ্যাঁ, আমি যদিও এলডিপ্রেলড সম্পর্কে, তবে সত্যই, হার্ডকোড করা /home/$USER/tmp/adb.logএবং
অ্যাডাবির

উত্তর:


5

এখানে ব্যবহার একটি খুব সহজ উদাহরণ util-linux's unshareএকটি প্রাইভেট নামস্থান মাউন্ট একটি প্রক্রিয়া করা এবং এটি একই ফাইলসিস্টেম তার পিতা বা মাতা বর্তমানে রয়েছে একটি ভিন্ন দৃশ্য দিতে:

{   cd /tmp                      #usually a safe place for this stuff
    echo hey   >file             #some
    echo there >file2            #evidence
    sudo unshare -m sh -c '      #unshare requires root by default
         mount -B file2 file     #bind mount there over hey
         cat file                #show it
         kill -TSTP "$$"         #suspend root shell and switch back to parent
         umount file             #unbind there
         cat file'               #show it
    cat file                     #root shell just suspended
    fg                           #bring it back
    cat file2                    #round it off
}

there                            #root shell
hey                              #root shell suspended
hey                              #root shell restored
there                            #rounded

আপনি কোনও প্রক্রিয়াটি unshareআপ-টু-ডেট লিনাক্স সিস্টেমের ইউটিলিটি সহ তার ফাইল সিস্টেমের একটি ব্যক্তিগত ভিউ দিতে পারেন , যদিও মাউন্ট নেমস্পেসের সুবিধাটি পুরো 3.x কার্নেল সিরিজের জন্য যথেষ্ট পরিপক্ক। আপনি nsenterএকই প্যাকেজ থেকে ইউটিলিটি সহ সমস্ত ধরণের প্রাক-বিদ্যমান নেমস্পেস লিখতে পারেন এবং এর সাথে আরও সন্ধান করতে পারেন man


কেবল একটি quiestion: এটি আমার বা এটি একটি সঠিক সমাধান কিন্তু শুধুমাত্র রুট ব্যবহারকারীর জন্য?
gluk47

@ গ্লুক 47 - এটি হওয়ার দরকার নেই। আপনি unshareসব ধরণের নেমস্পেস করতে পারেন - ব্যবহারকারীর নাম স্থান অন্তর্ভুক্ত করতে। এবং সুতরাং আপনার ব্যবহারকারী একটি নেমস্পেস চালাতে পারেন যার এটিতে রুট অ্যাক্সেস রয়েছে এবং এটি কোনও রুট ব্যবহারকারী যা স্ক্রু আপ করতে পারে তার মধ্যে প্যারেন্ট নেমস্পেসকে প্রভাবিত করে না। অন্য কথায়, একটি মাউন্ট নেমস্পেস একটি ব্যবহারকারীর নেমস্পেসের মধ্যে এম্বেড করা যেতে পারে। আপনার সত্যিই সেই manপৃষ্ঠাগুলি পড়া উচিত । এটা গভীর হয়। এটি ঠিক কীভাবে dockerএবং sytemd-nspawnকাজ করে।
মাইকজার্ভ

আমি এই ম্যান পেজগুলি এবং ইন্টারনেট থেকে উদাহরণগুলি পড়েছি) মনে হয় কেবল এগুলি আরও পড়তে হবে, কেবল এই প্রযুক্তির দিকে নির্দেশ করার জন্য আপনাকে ধন্যবাদ, আমি কোনওভাবেই এ সম্পর্কে সচেতন ছিলাম না।
গ্লুক 47

@ গ্লুক 47 - আনুগত্যের জন্য উত্তরগুলি গ্রহণ করবেন না। যখন অনুভূতির প্রশংসা করা হয়, সেই ধরণের জিনিস এই জায়গার উদ্দেশ্যকে হারাতে পারে। আপনি যে উত্তরটি ব্যবহার করেন তা গ্রহণ করুন । যদি সে এটি না হয় তবে দয়া করে এই উত্তরটি গ্রহণ করবেন না । উপায় দ্বারা, ঠিক কারণ একটি প্রক্রিয়া চালু রুট হিসাবে, না মানে এটা হয়েছে থাকা একটি রুট প্রক্রিয়া। সেখানে runuserইউটিলিটি ব্যবহার করা যেতে পারে unshare, এবং আপনি যদি কোনওভাবেই সংকলিত প্রোগ্রামগুলি লেখার জন্য উন্মুক্ত হন তবে unshare()সিস্কালটি একই কাজ করতে, বা এমনকি system()স্যুইড বাইনারি ব্যবহার করার কোনও কারণ নেই ।
মাইক্রজারভ

আমি নিশ্চিত উত্তরটি কার্যকর না হলে গ্রহণ করবেন না। আমি উভয় উত্তর প্রাসঙ্গিক এবং সহায়ক মনে করি, সুতরাং অনুভূতি এই উত্তরগুলির মধ্যে একটি চেক করার একমাত্র কারণ কারণ :)
gluk47

11

LD_PRELOAD খুব বেশি কঠিন নয় এবং আপনাকে রুট হওয়ার দরকার নেই। আপনার নিজের সি রুটিনকে ইন্টারপোজ করুন যা open()সি লাইব্রেরিতে আসল পরিবর্তে ডাকা হয় । আপনার রুটিনটি পরীক্ষা করে যদি ফাইলটি খোলার জন্য "/tmp/adb.log" থাকে এবং আলাদা ফাইলের নাম দিয়ে আসল ওপেনকে কল করে। আপনার shim_open.c এখানে:

/*
 * capture calls to a routine and replace with your code
 * gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
 * LD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
 */
#define _FCNTL_H 1 /* hack for open() prototype */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#define OLDNAME "/tmp/adb.log"
#define NEWNAME "/tmp/myadb.log"

int open(const char *pathname, int flags, mode_t mode){
    static int (*real_open)(const char *pathname, int flags, mode_t mode) = NULL;

    if (!real_open) {
        real_open = dlsym(RTLD_NEXT, "open");
        char *error = dlerror();
        if (error != NULL) {
            fprintf(stderr, "%s\n", error);
            exit(1);
        }
    }
    if (strcmp(pathname,OLDNAME)==0) pathname = NEWNAME;
    fprintf(stderr, "opening: %s\n", pathname);
    return real_open(pathname, flags, mode);
}

এটি দিয়ে সংকলন করুন gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.cএবং কিছু puttingুকিয়ে /tmp/myadb.logএবং চালিত করে এটি পরীক্ষা করুন LD_PRELOAD=/.../shim_open.so cat /tmp/adb.log। তারপরে Adb তে LD_PRELOAD ব্যবহার করে দেখুন।


ঠিক আছে, প্রকৃতপক্ষে আপনার সমাধানটি কেবলমাত্র আমিই কাজটি অ-রুট ব্যবহারকারী হিসাবে তৈরি করতে পরিচালিত। আমি শেয়ার ( Operation not permitted) ভাগ করে নিই । আমি আশা করি এটি openহ্যান্ডেল করার জন্য যথেষ্ট তবে শেষ পর্যন্ত unlinkএই হ্যান্ডেলারটি যুক্ত করা কঠিন নয়।
gluk47

ওহো। কী লজ্জার বিষয় যে আমি দুটি উত্তর চেক করতে পারি না। আমি মাইক্রজারকে প্রতিশ্রুতি দিয়েছিলাম যে উত্তরটি তার সমাধানটি পরীক্ষা করে দেখুন এবং এটি সত্যই কার্যকর able
গ্লুক 47

2
কিছু মনে করো না. আমি unshareপাশাপাশি শিখেছি , তাই আমরা সবাই লাভ!
meuh

কিছুক্ষণ পরে, এলডি_প্রেল্যাড নমুনার জন্য আপনাকে আবার ধন্যবাদ। যেহেতু আমি আপনার কোড চেষ্টা করেছি, তাই আমি LD_PRELOAD ব্যবহার করছি এমন পরিস্থিতিতে যেখানে আমি এটির কথা চিন্তাও করি না। আমার জীবন উন্নত হয়ে গেছে :)
gluk47

2
@ গ্লুক 47 এটি হ'ল গিনু / লিনাক্স সম্পর্কে এতটাই দুর্দান্ত: আপনার কখনই অন্বেষণ থামানো দরকার না! আবিষ্কার এবং ভাগ করার মতো অনেক ভাল জিনিস রয়েছে।
meuh
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.