AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 725590
Accepted
Jacob Valdez
Jacob Valdez
Asked: 2022-11-20 14:17:38 +0800 CST2022-11-20 14:17:38 +0800 CST 2022-11-20 14:17:38 +0800 CST

O Linux suporta a chamada de um programa diretamente por meio de seu número de inode?

  • 772

Estou perguntando porque as comparações de string são lentas, mas a indexação é rápida e muitos scripts que escrevo estão no bash, que, pelo que sei, executa uma pesquisa de string completa para cada chamada executável. Todos esses ls'se grep' seriam um pouco mais rápidos sem executar uma pesquisa de string em cada etapa. Claro, isso agora se aprofunda na otimização do compilador.

De qualquer forma, existe uma maneira de invocar diretamente um programa no Linux usando apenas seu número de inode (supondo que você tenha que procurá-lo apenas uma vez para todas as invocações)?

scripting
  • 4 4 respostas
  • 4262 Views

4 respostas

  • Voted
  1. Best Answer
    user10489
    2022-11-20T14:38:07+08:002022-11-20T14:38:07+08:00

    A resposta curta é não.

    A resposta mais longa é que a API do usuário linux não suporta o acesso a arquivos por qualquer método usando o número do inode. O único acesso ao número do inode é normalmente por meio da chamada de sistema stat() que expõe o número do inode, o que pode ser útil para identificar se dois nomes de arquivo são o mesmo arquivo, mas não é usado para mais nada.

    Acessar um arquivo por inode seria uma violação de segurança, pois ignoraria as permissões nos diretórios que contêm o arquivo vinculado ao inode.

    O mais próximo que você pode chegar disso seria acessar um arquivo pelo identificador de arquivo aberto. Mas você também não pode executar um programa a partir dele, e isso ainda exigiria a abertura do arquivo por um caminho. (Conforme observado nos comentários, essa funcionalidade foi adicionada ao Linux por motivos de segurança junto com o restante das chamadas *at do sistema, mas não é portátil.)

    Também existem várias maneiras de usar o número do inode para encontrar o arquivo (basicamente, rastrear o sistema de arquivos e usar stat) e executá-lo normalmente, mas isso é o oposto do que você deseja, pois é muito mais caro do que apenas acessar o arquivo por nome de caminho e também não remove esse custo.

    Dito isto, preocupar-se com esse tipo de otimização provavelmente é discutível, pois o Linux já otimizou bastante a pesquisa interna do inode. Além disso, tradicionalmente, os shells fazem o hash da localização do caminho dos executáveis ​​para que não precisem procurá-los em todos os diretórios o $PATHtempo todo.

    • 40
  2. bishop
    2022-11-20T16:34:24+08:002022-11-20T16:34:24+08:00

    Sim, é possível executar um arquivo pelo seu inode:

    find / -inum 242 -exec {} \; -quit
    

    O desempenho motivou a pergunta, porém, e o acima não é performático. Não apenas a estrutura do diretório é percorrida para encontrar um arquivo com esse inode (e pode haver vários), mas sob o capô, o número do inode é resolvido para um caminho e o caminho é fornecido ao kernel para executar. Mas por que?

    O kernel expõe a família exec de funções ( execl, execvp, etc), que envolvem a função do kernel execve. Essa função substitui a imagem do processo atual por uma nova imagem do processo, uma que foi inicializada pela leitura do conteúdo de um determinado caminho de arquivo . Portanto, todas as maneiras que o kernel fornece para executar um programa exigem que seja fornecido por caminho. Ao usar o caminho do arquivo como ponto de entrada, obtemos todos os benefícios de controle de acesso associados aos caminhos do arquivo e, por isso, a API "by path" é a única no Linux para executar um programa.


    No entanto, existe um mecanismo complicado e não garantido para funcionar em todos os ambientes que permite invocar um programa de dentro da memória . Como qualquer coisa na memória é necessariamente mais rápida do que qualquer coisa no disco, isso leva ao cerne da questão: como executar um programa o mais rápido possível.

    No início de 2002, um (famoso) hacker conhecido como grugq introduziu o conceito de userland exec. Esta não é uma função do shell exec: é uma emulação de cada etapa que a execvefunção do kernel executa, apenas escrita em userland. Isso é ideal para hackers que desejam ocultar sua atividade, pois permite a execução de um programa fora do mecanismo de controle de acesso usual do execve.

    A implementação desse método requer vários auxiliares que podem limpar o espaço de endereço, carregar o vinculador dinâmico, se necessário, inicializar a pilha e assim por diante. O mecanismo também requer que o código desejado seja carregado em certos tipos de memória.

    Também existem contra-medidas para tornar esse tipo de coisa difícil, mas, observe, não impossível. Tudo o que é necessário é que o sistema de destino tenha memória alinhada à página, a capacidade de marcar a memória como executável e a capacidade de pular para pontos arbitrários na memória. Esses requisitos geralmente se traduzem em: você deve escrevê-lo em C e usá-lo em um sistema sem SELinux ou sem o SELinux estar completamente habilitado. Não entrarei em detalhes de implementação aqui, mas fornecerei links que permitem que você explore por conta própria.

    Portanto, se o seu sistema Linux atender aos requisitos acima, você poderá executar o código na memória:

    1. Carregando o código na memória em algum lugar. Atores mal-intencionados já terão carregado o código desejado na memória como parte da queda inicial, mas se você quiser fazer isso nos moldes do inode, poderá fazerfind / -inum 242 -exec cat {} \;
    2. Chamando o mecanismo exec userland, definindo seu ponto de entrada para o endereço de memória onde você armazenou seu programa desde a etapa 1
    3. Lucro

    O kernel, o sistema de arquivos e o shell foram todos ajustados para tornar a pesquisa e a execução de programas uma fração insignificante da sobrecarga total necessária para realizar o trabalho. Carregar um programa na memória e executá-lo a partir daí não está realmente no domínio do caso de uso médio, então, a menos que faça isso por diversão, eu diria que você deseja comparar o desempenho antes de investir tempo tentando.

    Referências:

    • https://grugq.github.io/docs/ul_exec.txt
    • https://www.rapid7.com/blog/post/2019/01/03/santas-elfs-running-linux-executables-without-execve/
    • https://github.com/rapid7/mettle/pull/154
    • https://stackoverflow.com/a/13702073/2908724
    • https://unix.stackexchange.com/a/393444/50240
    • 18
  3. Edgar Bonet
    2022-11-22T01:01:24+08:002022-11-22T01:01:24+08:00

    Esta não é uma resposta direta à pergunta sobre i-nodes, mas sim uma maneira possível de evitar procurar os caminhos de utilitários padrão em scripts de shell.

    BusyBox é um programa que combina muitos utilitários padrão do Unix em um único executável que é muito menor do que o tamanho combinado de todas as ferramentas que ele substitui. É muito popular no mundo embarcado, onde o tamanho do disco costuma ser muito importante. Em um sistema típico baseado em BusyBox, sh, lse grepsão todos links simbólicos para busybox. Assim, um script de shell que chama lse grepchamaria busyboxa si mesmo apenas duas vezes.

    O BusyBox possui um recurso experimental chamado “shell autônomo”. Quando ativado, o BusyBox agindo como um shell não executa pesquisas de caminho para os utilitários que implementa. Em vez disso, ele apenas se executa /proc/self/execom os parâmetros corretos. Por exemplo, se ele executar um script de shell que chame grep, em vez de procurar grepem $PATH, ele executará /proc/self/exe grep <arguments>. Ainda há uma pesquisa de caminho no kernel para /proc/self/exe, mas é sempre a mesma, independentemente do utilitário que está sendo chamado, e a imagem executável já está na memória, portanto não há necessidade de carregá-la.

    Observe, no entanto, que o BusyBox foi altamente otimizado para tamanho e não para velocidade; portanto, pode não ser sua melhor opção se você se preocupa em economizar alguns microssegundos. Além disso, como observado anteriormente, o recurso “shell autônomo” é rotulado como experimental.

    • 2
  4. Jörg W Mittag
    2022-11-21T02:58:58+08:002022-11-21T02:58:58+08:00

    existe uma maneira de invocar diretamente um programa no Linux usando apenas seu número de nó

    Não, não é, e por um motivo simples: você está usando a forma singular " um programa" e " seu número de inode" em sua pergunta, mas os inodes não são únicos: pode haver vários arquivos no sistema com o mesmo inode número.

    Portanto, pelo simples senso comum, o melhor que você pode fazer é "invocar diretamente um ou mais de um conjunto de programas usando apenas seus números de inode", mas você não pode invocar um programa específico sem informações de identificação adicionais sobre o referido programa para escolher o único programa do conjunto de programas.

    Uma dessas informações de identificação, é claro, poderia ser seu caminho... ponto em que você está de volta à estaca zero.

    • -3

relate perguntas

  • Verifique o histórico de login do usuário root

  • Uma maneira rápida de duplicar um site (Wordpress) no meu ambiente de servidor Nginx?

  • problema ao iniciar aplicativos: linha de comando vs. gui

  • Shell Script para encontrar string no arquivo de log

  • Renomeie (acrescentar) arquivos CSV em massa com base em um valor dentro

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve