Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

Samba smbclient―書式指定文字列に潜む脆弱性

実例で学ぶ脆弱性対策コーディング 第4回

  • LINEで送る
  • このエントリーをはてなブックマークに追加

 本連載では、脆弱性を含むサンプルコードを題材に、修正方法の例を解説していきます。今回取り上げるコードは、Windowsからアクセスできるファイルサーバーを構築するためのオープンソースソフトウェア「Samba」です。

目次

 今回はSambaを取り上げます。Sambaは、Unix系マシンをWindowsファイル共有サーバーにするためのソフトウェアとして有名です。市販のNAS(ネットワーク接続ストレージ)の多くも、LinuxとSambaの組み合わせでその機能を実現しています。ここでは、昨年2009年に発見・修正された問題を取り上げてみましょう。

サンプルコード

 Sambaでは、種々のサーバープログラムと共に、サーバーに接続するためのクライアントプログラムも提供しています。今回は、そのクライアントプログラムのソースコードに含まれているcmd_get()という関数に注目しましょう。それほど長い関数ではありませんが、他の部分で定義されている関数をいろいろ呼び出しているので、それらのプロトタイプ宣言とコメント部分を一緒に並べてあります。

samba-3.2.12/source/client/client.c 他より抜粋
/* Get us the current top of the talloc stack. */
TALLOC_CTX *talloc_tos(void);

/* strdup with a talloc */
char *talloc_strdup(const void *t, const char *p);

/* Get the next token from a string, return false if none found. */
bool next_token_talloc(TALLOC_CTX *ctx,
            const char **ptr, char **pp_buff, const char *sep);

/* print intenal strings in the "display charset" */
int d_printf(const char *format, ...);

/*
  Realloc s to append the formatted result of fmt and return s,
  which may have moved.  Good for gradually accumulating output
  into a string buffer.
 */
char *talloc_asprintf_append(char *s, const char *fmt, ...);

/* Reduce a file name, removing .. elements. */
char *clean_name(TALLOC_CTX *ctx, const char *s);

/* Get a file from rname to lname */
static int do_get(const char *rname, const char *lname_in, bool reget);

/****************************************************************************
 Get a file.
****************************************************************************/

static int cmd_get(void)
{
    TALLOC_CTX *ctx = talloc_tos();
    char *lname = NULL;
    char *rname = NULL;
    char *fname = NULL;

    rname = talloc_strdup(ctx, client_get_cur_dir());
    if (!rname) {
        return 1;
    }

    if (!next_token_talloc(ctx, &cmd_ptr,&fname,NULL)) {
        d_printf("get <filename> [localname]\n");
        return 1;
    }
    rname = talloc_asprintf_append(rname, fname);
    if (!rname) {
        return 1;
    }
    rname = clean_name(ctx, rname);
    if (!rname) {
        return 1;
    }

    next_token_talloc(ctx, &cmd_ptr,&lname,NULL);
    if (!lname) {
        lname = fname;
    }

    return do_get(rname, lname, false);
}

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

バックナンバー

連載:実例で学ぶ脆弱性対策コーディング

もっと読む

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5